vevet
Version:
Vevet is a JavaScript library for creative development that simplifies crafting rich interactions like split text animations, carousels, marquees, preloading, and more.
115 lines • 4.2 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { getPos } from 'get-image-pos';
import { noopIfDestroyed } from '../../internal/noopIfDestroyed';
import { addEventListener } from '../../utils';
import { Canvas } from '../Canvas';
import { MUTABLE_PROPS, STATIC_PROPS } from './props';
export * from './types';
/**
* The `CanvasMedia` class allows pre-rendering of media (such as images or video) onto a canvas.
* This can be useful for reducing payloads by preparing the media for further use in a more optimized form.
*
* [Documentation](https://vevetjs.com/docs/CanvasMedia)
*
* @group Components
*/
export class CanvasMedia extends Canvas {
/** Get default static properties */
_getStatic() {
return Object.assign(Object.assign({}, super._getStatic()), STATIC_PROPS);
}
/** Get default mutable properties */
_getMutable() {
return Object.assign(Object.assign({}, super._getMutable()), MUTABLE_PROPS);
}
constructor(props, onCallbacks) {
super(props, onCallbacks);
this._setMediaEvents();
}
/** Checks if the media element has the `requestVideoFrameCallback` method */
get hasRequestVideoFrameCallback() {
return 'requestVideoFrameCallback' in this.props.media;
}
/** Add media events */
_setMediaEvents() {
const { autoRenderVideo: hasVideoAutoRender, media } = this.props;
if (!hasVideoAutoRender || !(media instanceof HTMLVideoElement)) {
return;
}
// use requestVideoFrameCallback
if (this.hasRequestVideoFrameCallback) {
this._requestVideoFrame();
return;
}
// use timeupdate listener
const timeupdate = addEventListener(media, 'timeupdate', () => {
this.render();
});
this.onDestroy(() => timeupdate());
}
/** Resize the canvas */
resize() {
super.resize();
this.render();
}
/** Auto rendering for videos */
_requestVideoFrame() {
if (this.isDestroyed) {
return;
}
this.render();
const { media } = this.props;
if (media instanceof HTMLVideoElement) {
media.requestVideoFrameCallback(() => this._requestVideoFrame());
}
}
/** Pre-renders the media resource onto the canvas. */
render() {
super.render((props) => this._prerender(props));
}
/**
* Prerenders the media onto the canvas using the specified positioning rule.
*/
_prerender({ width, height, ctx }) {
const { media, rule } = this.props;
// Determine the media source and its dimensions
let source;
let sourceWidth;
let sourceHeight;
if (media instanceof Canvas) {
source = media.canvas;
sourceWidth = media.width;
sourceHeight = media.height;
}
else {
source = media;
}
// Calculate media position and size based on the posRule
const size = getPos({
source,
sourceWidth,
sourceHeight,
rule,
scale: 1,
width,
height,
});
// Clear the canvas and draw the media with the calculated size
ctx.clearRect(0, 0, width, height);
ctx.drawImage(source, size.x, size.y, size.width, size.height);
// Trigger prerender callback
this.callbacks.emit('render', undefined);
}
}
__decorate([
noopIfDestroyed
], CanvasMedia.prototype, "resize", null);
__decorate([
noopIfDestroyed
], CanvasMedia.prototype, "render", null);
//# sourceMappingURL=index.js.map