Технопарк, весна, 2019 г.
<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' );
// обводит прямоугольную область
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 - проводить против часовой стрелки
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');
// - создать из SVG
Path2D.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.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.save();
// вернуть предыдущие из стека
ctx.restore();
ctx.drawImage
для img, svg, video, canvasctx.getImageData
window.sleep(...)
window.setInterval(function, delay)
window.setTimeout(function, delay)
window.requestAnimationFrame(callback)
setInterval
function animation() {
redraw(); // перерисовываем кадр
}
const id = window.setInterval(animation, 1000 / 60); // 60 fps
// хотим прервать анимацию
window.clearInterval(id);
setTimeout
let id = null;
function animation() {
redraw(); // перерисовываем кадр
id = window.setTimeout(animation, 1000 / 60); // 60 fps
}
animation();
// хотим прервать анимацию
window.clearTimeout(id);
requestAnimationFrame
let animationFrameId = null;
function animation() {
redraw(); // перерисовываем кадр
animationFrameId = window.requestAnimationFrame(animation);
}
animation();
// хотим прервать анимацию
window.cancelAnimationFrame(animationFrameId)
setInterval
и setTimeout
requestAnimationFrame
dt
)dx = Vx * dt
)requestAnimationFrame
let last = perfomance.now(); // точное время в наносекундах
function animation(now) { // передаётся текущее perfomance.now()
const delay = now - last;
redraw(delay); // перерисовываем кадр
window.requestAnimationFrame(animation);
}
animation(perfomance.now());
requestAnimationFrame
canvas
canvas
canvas
для сложных сценcanvas
shadowBlur
Режимы, обязательные к реализации
Сначала реализуем singleplayer на js, а потом доработаем и добавим туда многопользовательность...
Pointer Lock API — это браузерный API, позволяющий создавать интерфейсы для работы с мышкой на основе ее относительных перемещений , а не только абсолютной позиции курсора. Это дает нам доступ к необработанным движениям мыши, прикрепляет курсор мыши к любому элементу в окне браузера, предоставляет возможность вычислять координаты мыши не ограниченной областью окна проекции, и скрывает курсор из поля зрения
document.addEventListener('pointerlockchange', lockStatusChange);
canv.onclick = canv.requestPointerLock;
function lockStatusChange() {
if (document.pointerLockElement === canv){
document.addEventListener('mousemove', update);
} else {
document.removeEventListener('mousemove', update);
}
}
// обработчик события
function update(event) {
// событие содержит смещение
const dx = event.movementX;
const dy = event.movementY;
animate(dx, dy);
}
Request Full Screen API — позволяет отображать элемент в полноэкранном режиме. Метод может применяться к любому элементу, даже, например, к простому блоку
Примерelement.requestFullscreen();
document.exitFullscreen();
WebGL (Web Graphics Library) — программная библиотека для языка JavaScript предназначенная для визуализации интерактивной трехмерной графики и двухмерной графики в пределах совместимости веб-браузера без использования плагинов. WebGL приносит в веб трехмерную графику, вводя API, который построен на основе OpenGL ES 2.0 , что позволяет его использовать в элементах
canvas
HTML5
Шейдеры — программы, которые работают на GPU. Шейдеры пишутся на специальном языке: OpenGL ES Shader Language (известный как ES SL). ES SL имеет переменные своих собственных типов данных и свои специфические встроенные функции. В свою очередь ES SL основан на C++. ES SL также называют GLSL, что означает Graphics Library Shader Language (язык программирования шейдеров графической библиотеки)
<script type="x-shader/x-vertex" id="vshader">
varying vec2 vUv;
void main() {
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script type="x-shader/x-fragment" id="fshader">
uniform sampler2D u_Sampler;
varying vec2 vUv;
void main() {
gl_FragColor = texture2D(u_Sampler, vUv);
}
</script>
if (window.innerHeight > window.innerWidth) {
// do smth
}
Пример
WebVR обеспечивает поддержку для использования устройств виртуальной реальности — например, шлемы виртуальной реальности, таких как Oculus Rift или HTC Vive — для веб-приложений, позволяя разработчикам передавать информацию о местоположении и движения с дисплея в движение вокруг 3D-сцены.
Stay tuned...
<audio
src="/music.ogg"
autoplay
>
Ваш браузер не поддерживает audio элемент.
</audio>
Web audio API — мощный и многогранный инструмент для манипуляции звуковой составляющей на веб-странице, что дает возможность разработчикам выбрать источники, добавить к ним специальные звуковые эффекты (такие как panning), визуализировать их и многое другое.
Web Speech API позволяет взаимодействовать с голосовыми интерфейсами в ваших веб приложениях. Web Speech API состоит из двух частей: SpeechSynthesis (Текст-в-Речь), и SpeechRecognition (Асинхронное распознавание речи)