Моя функциональность работает нормально, но после нескольких циклов она замедляется, а «зеркальное» видео немного заикается.
Есть ли способ сделать это быстрее/плавнее?
Я хотел бы понять, правильно ли я выбрал способ зеркалирования видео.
У меня есть путь к клипу в css, и их должно быть 3, на которых у меня есть видео внутри зеркального отображения. Поначалу выглядит очень хорошо, но затем, после нескольких циклов, зеркальные видео начинают работать медленно и
Пожалуйста помоги.
document.addEventListener('DOMContentLoaded', function(){
var v = document.getElementById('video1');
var canvasBottom = document.getElementById('mycanvasbottom');
var canvasLeft = document.getElementById('mycanvasleft');
var canvasRight = document.getElementById('mycanvasright');
var contextB = canvasBottom.getContext('2d');
var contextL = canvasLeft.getContext('2d');
var contextR = canvasRight.getContext('2d');
var cw = 640;
var ch = 480;
canvasBottom.width = cw;
canvasBottom.height = ch;
canvasLeft.width = cw;
canvasLeft.height = ch;
canvasRight.width = cw;
canvasRight.height = ch
v.addEventListener('timeupdate', function(){
draw(this,contextL,cw,ch);
draw(this,contextR,cw,ch);
draw(this,contextB,cw,ch);
},false);
},false);
function draw(v,c,w,h) {
if (v.paused || v.ended) return false;
c.drawImage(v,0,0,w,h);
setTimeout(draw,20,v,c,w,h);
}
#mycanvasbottom {
position: absolute;
margin: 0 auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 75%;
height: 75%;
-webkit-filter: grayscale(1);
clip-path: polygon(0 100%, 50% 50%, 100% 100%);
}
#mycanvasleft {
position: absolute;
margin: 0 auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 75%;
height: 75%;
-webkit-filter: grayscale(1);
clip-path: polygon(0 0, 50% 50%, 0 100%);
}
#mycanvasright {
position: absolute;
margin: 0 auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 75%;
height: 75%;
-webkit-filter: grayscale(1);
clip-path: polygon(100% 0, 50% 50%, 100% 100%);
}
#video1 {
position: absolute;
left: 0;
}
<canvas id='mycanvasbottom' ></canvas>
<canvas id='mycanvasleft' ></canvas>
<canvas id='mycanvasright' ></canvas>
<video id='video1' autoplay muted loop width='320' >
<source src = "http://media.w3.org/2010/05/sintel/trailer.mp4" type = "video/mp4" />
</video>
Во-первых, событие «timeupdate» запускается несколько раз, поэтому вы на самом деле вызываете отрисовку гораздо чаще, чем хотите. По этой причине он начинает лагать - много операций выполняется в секунду. Вы, вероятно, можете прослушивать события «play» и «pause» (запускаются после выполнения методов play() и pause(); событие «play» также вызывается, когда начинается видео, поэтому вам не нужно вызывать его вручную, его все равно уволят). Затем вы можете вручную обрабатывать цикл рисования. Это должно решить вашу проблему (я смог воспроизвести, и это исправляет эффект замедления).
Кроме того, вот несколько советов, которые вы можете рассмотреть:
С уважением и хорошего дня!
Редактировать: Не поймите меня неправильно, некоторые из них касаются только личных предпочтений. Поработав довольно много с js, я предпочитаю, чтобы он был простым, как в этом фрагменте. Наслаждайтесь бесплатным кодом!
let lastAnimationFrameRequestId = 0;
document.addEventListener('DOMContentLoaded', function () {
const cw = 640;
const ch = 480;
const video = document.getElementById('video1');
const canvases = [];
const clipPaths = [
'clip-path: polygon(0 100%, 50% 50%, 100% 100%)',
'clip-path: polygon(0 0, 50% 50%, 0 100%);',
'clip-path: polygon(100% 0, 50% 50%, 100% 100%)'
];
clipPaths.forEach((clipPath) => {
const canvas = Object.assign(document.createElement('canvas'), { className: 'my-canvas', style: clipPath, width: cw, height: ch });
canvases.push(canvas);
document.body.appendChild(canvas);
});
video.addEventListener('play', () => window.requestAnimationFrame(() => draw(video, canvases)));
video.addEventListener('pause', () => window.cancelAnimationFrame(lastAnimationFrameRequestId));
});
function draw(video, canvases) {
canvases.forEach((canvas) => {
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
});
lastAnimationFrameRequestId = window.requestAnimationFrame(() => draw(video, canvases));
}
.my-canvas {
position: absolute;
margin: 0 auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 75%;
height: 75%;
-webkit-filter: grayscale(1);
}
<video id='video1' autoplay muted loop width='320'>
<source src = "http://media.w3.org/2010/05/sintel/trailer.mp4" type = "video/mp4" />
</video>
Вы знаете, как добавить эффект размытия на холст слева и справа? клип-путь: полигон (100% 0, 50% 50%, 100% 100%); фильтр: размытие (4px); Что-то вроде этого? похоже немного тормозит форма
Старый добрый друг при работе с JS — это console.info() — часто для меня это самый полезный инструмент для отладки JS. Просто, всегда работает. Попробуйте изменить CSS, свойство -webkit-filter с "-webkit-filter: оттенки серого (1);" на «-webkit-filter: оттенки серого (1) размытие (4 пикселя);». Вы можете смешивать несколько фильтров, просто разделяя их пробелом. Также может потребоваться добавить «-moz-filter» и «filter» для совместимости с браузером.
Не могли бы вы помочь мне с шириной что-то еще? Что делать, если у меня есть другое видео, и я хочу воспроизвести холст с другим видео? будет ли это работать без дублирования кода?
Не дублируйте код! Если вам нужно повторно использовать какую-то часть, извлеките ее в функцию, а затем вызовите ее с нужным элементом. Эта строка «const video = document.getElementById('video1');» необходимо параметризовать. Подумайте об этом и немного поиграйте с этим.
Привет, Майк, я собрал кое-какой код для демо, codepen.io/davide77/pen/vwpKxN?editors=1010, не мог бы ты проверить, правильно ли я это сделал?
Привет, Майк, ты знаешь, как заставить его работать в сафари?
Большое спасибо за этот подробный, хорошо объясненный ответ. Я действительно оценил. Без вас было бы невозможно достичь этого за миллион лет!