UNPKG

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
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