Я недавно получил этот запрос от клиента для предоставления этой функции, и он должен быть дружественным к CMS. Техника включает в себя три большие идеи
- функция рисования
- многократный вызов одной и той же функции рисования
- с использованием
requestAnimationFrame
для рисования следующего кадра
Если у вас уже есть видеоэлемент, вы бы предприняли следующие шаги
- Скрыть элемент видео
- Создайте элемент canvas, высота / ширина которого соответствует элементу video, сохраните его где-нибудь
- Получите контекст элемента canvas с помощью canvas.getContext ('2d') и сохраните его где-нибудь
- Создание функции рисования
- В этой функции рисования вы должны использовать
canvas.drawImage(src, x, y)
, где src
- отредактированная версия текущего кадра видео;
- В этой функции рисования используйте рекурсию, чтобы вызвать себя снова
Я могу привести два примера того, как это делается (и применимо для систем управления контентом)
Первый здесь: https://jsfiddle.net/yywL381w/19/
Компания под названием SDL создает инструмент Media Manager для размещения видео. То, что вы видите, это плагин jQuery, который берет свои параметры из data-*
, делает запрос из Media Manager Rest API, создает видео и добавляет эффекты, полностью основываясь на атрибутах data*
. Этот плагин можно легко настроить для работы с видео, полученными из других источников. Вы можете посмотреть на репо для более подробной информации об использовании.
Другой пример здесь: http://codepen.io/paceaux/pen/egLOeR
Это не плагин jQuery; вместо этого это класс ES6. Вы можете создать изображение / видео и применить эффект обрезки с помощью этого:
let imageModule = new ImageCanvasModule(module);
imageModule.createCanvas();
imageModule.drawOnCanvas();
imageModule.hideOriginal();
В классе ImageCanvasModule
вы увидите этот метод:
drawFrame () {
if (this.isVideo && this.media.paused) return false;
let x = 0;
let width = this.media.offsetWidth;
let y = 0;
this.imageFrames[this.module.dataset.imageFrame](this.backContext);
this.backContext.drawImage(this.media, x, y, width, this.canvas.height);
this.context.drawImage(this.backCanvas, 0, 0);
if (this.isVideo) {
window.requestAnimationFrame(()=>{
this.drawFrame();
});
}
}
Класс создал второй холст, чтобы использовать его для рисования. Этот холст не виден, он просто помогает браузеру сохранить душевную боль.
"Манипулирование", которым можно управлять контентом: this.imageFrames[this.module.dataset.imageFrame](this.backContext);
«Кадр» - это атрибут, сохраненный на изображении / видео (который может быть выведен шаблоном в CMS). Это получает имя imageFrame и запускает его как соответствующую функцию. Он также отправляет в контексте (чтобы при необходимости я мог переключаться между рисованием на заднем холсте или на основном холсте)
затем this.backContext.drawImage(this.media, x, y, width, this.canvas.height);
рисует изображение в обратном контексте.
Наконец, это появляется на главном холсте с this.context.drawImage(this.backCanvas, 0, 0);
, где я беру задний холст и рисую его на главном холсте. Таким образом, видимый холст имеет наименьшее количество возможных манипуляций.
И в конце, потому что это видео, мы хотим нарисовать новый кадр. Итак, у нас есть сам вызов функции:
if (this.isVideo) {
window.requestAnimationFrame(()=>{
this.drawFrame();
});
Вся эта установка позволяет нам использовать CMS для вывода data-*
атрибутов, содержащих тип кадра, который пользователь хочет нарисовать вокруг изображения. JavaScript затем создает версию этого изображения или видео на холсте. Пример разметки может выглядеть так:
<video muted loop autoplay data-image-frame="wedgeTop">