Технопарк, осень, 2024 г.
<img src="image.png">)<video src="video.mp4"></video>)<canvas>Элемент
<canvas>(англ. canvas — «холст», рус. канва́с) — это HTML5 элемент, предназначенный для создания растрового двухмерного изображения на web-страницах с помощью программирования на JavaScript
Подробный туториал по canvas — на MDN
<canvas id="canvas" width="300" height="150"></canvas>
const canvas = document.createElement( 'canvas' );document.appendChild(canvas);// Объект двумерного контекстаconst context = canvas.getContext( '2d' );// Объект WebGL (3D) контекстаconst webgl = canvas.getContext( 'webgl' );
По умолчанию:(0;0) в верхнем левом углу
// обводит прямоугольную областьctx.strokeRect(x, y, width, height);// заливает прямоугольную областьctx.fillRect(x, y, width, height);// очищает прямоугольную областьctx.clearRect(x, y, width, height);
// толстая рамкаctx.fillRect(25, 25, 250, 250);ctx.clearRect(100, 100, 100, 100);// квадраты в центреctx.strokeRect(110, 110, 80, 80);ctx.strokeRect(120, 120, 60, 60);ctx.strokeRect(130, 130, 40, 40);ctx.strokeRect(140, 140, 20, 20);
Контур — точки, соединенные линиями разной формы
ctx.beginPath(); // создаёт новый контурctx.moveTo(x1, y1); // передвигает перо в нужную точкуctx.lineTo(x2, y2); // проводит линию до другой точкиctx.stroke(); // обводит созданный контурctx.fill(); // заливает область, обведённую контуром// "nonzero" or "evenodd"ctx.closePath(); // закрывает контур
// верхний треугольникctx.beginPath();ctx.moveTo(50, 50);ctx.lineTo(50, 200); ctx.lineTo(200, 50); ctx.lineTo(50, 50);ctx.closePath();ctx.fill();// нижний треугольникctx.beginPath();ctx.moveTo(250, 250);ctx.lineTo(250, 100); ctx.lineTo(100, 250); ctx.lineTo(250, 250);ctx.closePath();ctx.stroke();
// создаёт путь-дугуctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);// x, y - центр дуги// radius - радиус дуги (в радианах)// startAngle - начальный угол// endAngle - конечный угол// anticlockwise - проводить против часовой стрелки
radians = (Math.PI/180) * degrees
ctx.beginPath();ctx.arc(100, 100, 50, -Math.PI, 0);ctx.closePath(); ctx.fill();ctx.beginPath();ctx.arc(100, 110, 40, 0, Math.PI);ctx.closePath(); ctx.fill();ctx.beginPath();ctx.arc(200, 200, 50, -Math.PI, 0);ctx.arc(220, 200, 30, 0, Math.PI);ctx.closePath(); ctx.stroke();
// квадратичная криваяctx.quadraticCurveTo(cp1x, cp1y, x, y);// кубическая криваяctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);// cpx, cpy - опорные точки// x, y - куда вести
ctx.beginPath();ctx.moveTo(75, 25);ctx.quadraticCurveTo(25, 25, 25, 62.5);ctx.quadraticCurveTo(25, 100, 50, 100);ctx.quadraticCurveTo(50, 120, 30, 125);ctx.quadraticCurveTo(60, 120, 65, 100);ctx.quadraticCurveTo(25, 25, 25, 62.5);ctx.quadraticCurveTo(125, 100, 125, 62.5);ctx.quadraticCurveTo(125, 25, 75, 25);ctx.stroke();
// добавляет прямоугольный путь к текущему пути (не рисует)ctx.rect(x, y, width, height);// x, y - координаты левого верхнего угла
ctx.fillText(text, x, y, maxWidth);ctx.strokeText(text, x, y, maxWidth);// text - текст// x, y - координаты точки начала// maxWidth - опциональное ограничение по ширине
new Path2D('M10 10 h 80 v 80 h -80 Z');// - создать из SVGPath2D.addPath(path [, transform])// path - добавить путьconst rectangle = new Path2D();rectangle.rect(10, 10, 50, 50);ctx.stroke(rectangle);
// ширина линийctx.lineWidth = value;// пунктирctx.setLineDash(segments); // шаблон (массив чисел)ctx.getLineDash(); // получить текущий шаблонctx.lineDashOffset = value; // установить смещение (число)
ctx.beginPath();[1, 5, 10, 20, 50].forEach((v, i) => {ctx.beginPath();ctx.lineWidth = v; ctx.setLineDash([5, 5, 50, 5, 5, v]);ctx.moveTo(20, 30 + 55 * i); ctx.lineTo(280, 30 + 55 * i);ctx.stroke();});
// окончание линийctx.lineCap = 'butt'; // обрезанные концыctx.lineCap = 'round'; // скруглённые концыctx.lineCap = 'square'; // квадраты// оформление угловctx.lineJoin = 'bevel'; // срезанные углыctx.lineJoin = 'round'; // скруглённые углыctx.lineJoin = 'miter'; // острые углы
const lineJoin = ['round', 'bevel', 'miter'];ctx.lineWidth = 30;lineJoin.forEach((v, i) => {ctx.lineJoin = v; ctx.beginPath();ctx.moveTo(70, 110 + i * 80);ctx.lineTo(150, 30 + i * 80);ctx.lineTo(230, 110 + i * 80);ctx.stroke();});
ctx.lineWidth = 20;const lineCap = ['butt', 'round', 'square'];// Рисуем линииlineCap.forEach((v, i) => {ctx.lineCap = v; ctx.beginPath();ctx.moveTo(50 + i * 100, 20);ctx.lineTo(50 + i * 100, 280);ctx.stroke();});
ctx.fillStyle = color; // задаёт стиль заливкиctx.strokeStyle = color; // задаёт стиль обводкиctx.globalAlpha = value; // задаёт уровень прозрачности (0.0 .. 1.0)ctx.fillStyle = 'orange';ctx.fillStyle = '#FFA500';ctx.fillStyle = 'rgb(255, 165, 0)';ctx.fillStyle = 'rgba(255, 165, 0, 1)';
ctx.fillStyle = 'yellow'; ctx.fillRect(0, 0, 150, 150);ctx.fillStyle = '#6C0'; ctx.fillRect(150, 0, 150, 150);ctx.fillStyle = '#0099FF'; ctx.fillRect(0, 150, 150, 150);ctx.fillStyle = 'rgb(255,48,0)'; ctx.fillRect(150, 150, 150, 150);ctx.fillStyle = 'white';for (let i = 0; i < 7; i++) {ctx.beginPath();ctx.fillStyle = 'rgba(255,255,255,' + (i + 1) / 12 + ')';ctx.arc(150, 150, 10 + 20 * i, 0, Math.PI * 2, true);ctx.fill();}
// создание линейного градиентаlet gradient = ctx.createLinearGradient(x1, y1, x2, y2);// создание радиального градиентаgradient = ctx.createRadialGradient(x1, y1, r1, x2, y2, r2);// добавление контрольной точкиgradient.addColorStop(position, color);ctx.fillStyle = gradient;ctx.strokeStyle = gradient;
const linear = ctx.createLinearGradient(0, 150, 0, 0);const radial = ctx.createRadialGradient(150, 150, 0, 150, 150, 151);[linear, radial].forEach(grad => {grad.addColorStop(0, 'yellow');grad.addColorStop(0.5, 'green');grad.addColorStop(0.99, 'blue');grad.addColorStop(1, 'white');});ctx.fillStyle = linear;ctx.fillRect(0, 0, 300, 150);ctx.fillStyle = radial;ctx.fillRect(0, 150, 300, 150);
// создание паттернаlet pattern = ctx.createPattern(image, type);// тениctx.shadowOffsetX = float;ctx.shadowOffsetY = float;ctx.shadowBlur = float;ctx.shadowColor = color;
// сохранить все настройки, в том числе трансформации!ctx.save();// вернуть предыдущие из стекаctx.restore();
// перенос точки отсчётаctx.translate(x, y);// поворот осейctx.rotate(angle);// масштабирование по осямctx.scale(x, y);
// перенос точки отсчётаctx.transform(a, b, c, d, e, f);// a - горизонтальный масштаб// b - горизонтальный скос// c - вертикальный скос// d - вертикальный масштаб// e - горизонтальное смещение// f - вертикальное смещение
// сброс текущей трансформацииctx.resetTransform();// сброс текущей и установка новой трансформацииctx.setTransform(a, b, c, d, e, f);
ctx.drawImage для img, svg, video, canvasctx.getImageDatawindow.sleep(...)window.setInterval(function, delay)window.setTimeout(function, delay)window.requestAnimationFrame(callback)setIntervalfunction animation() {redraw(); // перерисовываем кадр}const id = window.setInterval(animation, 1000 / 60); // 60 fps// хотим прервать анимациюwindow.clearInterval(id);
setTimeoutlet id = null;function animation() {redraw(); // перерисовываем кадрid = window.setTimeout(animation, 1000 / 60); // 60 fps}animation();// хотим прервать анимациюwindow.clearTimeout(id);
requestAnimationFramelet animationFrameId = null;function animation() {redraw(); // перерисовываем кадрanimationFrameId = window.requestAnimationFrame(animation);}animation();// хотим прервать анимациюwindow.cancelAnimationFrame(animationFrameId)
dt)dx = Vx * dt)requestAnimationFramelet last = perfomance.now(); // точное время типа DOMHighResTimeStampfunction animation(now) { // передаётся текущее perfomance.now()const delay = now - last;last = now;redraw(delay); // перерисовываем кадрwindow.requestAnimationFrame(animation);}animation(perfomance.now());
requestAnimationFramecanvascanvascanvas для сложных сценcanvasshadowBlurWAAPI — браузерное API, позволяющее разработчикам управлять движком анимаций с помощью JavaScript.
Подробно про WAAPI — на MDN
Worklet интерфейс — это легковесная версия Web Worker-ов, которая дает разработчикам доступ к управлению процессом рендеринга на низком уровне. С его помощью можно исполнять JavaScript и WebAssembly код для высокопроизводительного рендеринга графики.
Подробно про интерфейс Worklet — на MDN
Статья про использование Animation Worklet-ов
WebGL (Web Graphics Library) — программная библиотека для языка JavaScript предназначенная для визуализации интерактивной трехмерной графики и двухмерной графики в пределах совместимости веб-браузера без использования плагинов. WebGL приносит в веб трехмерную графику, вводя API, который построен на основе OpenGL ES 2.0 , что позволяет его использовать в элементах
canvasHTML5
Шейдеры — программы, которые работают на GPU. Шейдеры пишутся на специальном языке: OpenGL ES Shader Language (известный как ES SL). ES SL имеет переменные своих собственных типов данных и свои специфические встроенные функции. В свою очередь ES SL основан на C++. ES SL также называют GLSL, что означает Graphics Library Shader Language (язык программирования шейдеров графической библиотеки)