vevet
Version:
Vevet is a JavaScript library for creative development that simplifies crafting rich interactions like split text animations, carousels, marquees, preloading, and more.
183 lines • 6.07 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 { Module } from '../../base/Module';
import { initVevet } from '../../global/initVevet';
import { doc } from '../../internal/env';
import { isNumber } from '../../internal/isNumber';
import { noopIfDestroyed } from '../../internal/noopIfDestroyed';
import { onResize } from '../../utils/listeners/onResize';
import { MUTABLE_PROPS, STATIC_PROPS } from './props';
export * from './types';
/**
* A class for managing an HTML5 Canvas element and its 2D context.
*
* [Documentation](https://vevetjs.com/docs/Canvas)
*
* @group Components
*/
export class Canvas extends Module {
/** 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 for the Ctx2D class.
*/
constructor(props, onCallbacks) {
super(props, onCallbacks);
/** The current width of the canvas, considering the device pixel ratio (DPR) */
this._width = 0;
/** The current height of the canvas, considering the device pixel ratio (DPR) */
this._height = 0;
/** The current device pixel ratio (DPR) */
this._dpr = 1;
const { container } = this.props;
// Create canvas element
this._canvas = doc.createElement('canvas');
// Add canvas styles
const { style } = this._canvas;
style.position = 'absolute';
style.top = '0';
style.left = '0';
style.width = '100%';
style.height = '100%';
// Append canvas to container if required
if (this.props.append && container instanceof HTMLElement) {
container.append(this._canvas);
}
// Create 2D context
this._ctx = this._canvas.getContext('2d');
// Set events
this._setEvents();
}
/** The canvas element instance. */
get canvas() {
return this._canvas;
}
/** Returns the 2D rendering context */
get ctx() {
return this._ctx;
}
/** Canvas width (DPR applied). */
get width() {
return this._width;
}
/** Width without DPR scaling. */
get offsetWidth() {
return this.width / this.dpr;
}
/** Canvas height (DPR applied). */
get height() {
return this._height;
}
/** Height without DPR scaling. */
get offsetHeight() {
return this.height / this.dpr;
}
/** Current device pixel ratio. */
get dpr() {
return this._dpr;
}
/** Checks if the canvas is ready to render. */
get canRender() {
return this.width > 0 && this.height > 0;
}
/** Handle property mutations */
_handleProps(props) {
super._handleProps(props);
this.resize();
}
/** Set events */
_setEvents() {
const { props } = this;
const { viewportTarget, resizeDebounce } = props;
// Set resize events
if (props.resizeOnInit) {
this.resize();
}
// Runtime resize
if (!props.resizeOnRuntime) {
return;
}
const resizeHandler = onResize({
callback: () => this.resize(),
element: this.props.container,
viewportTarget,
resizeDebounce,
name: this.name,
});
this.onDestroy(() => resizeHandler.remove());
}
/** Triggers a canvas resize based on container or viewport dimensions. */
resize() {
const core = initVevet();
const { props, canvas } = this;
const { container } = this.props;
// Calculate DPR
this._dpr = isNumber(props.dpr) ? props.dpr : core.dpr;
// Calculate new width and height
let newWidth = 0;
let newHeight = 0;
if (props.width === 'auto') {
newWidth = (container === null || container === void 0 ? void 0 : container.offsetWidth) || core.width;
}
else {
newWidth = props.width;
}
if (props.height === 'auto') {
newHeight = (container === null || container === void 0 ? void 0 : container.offsetHeight) || core.height;
}
else {
newHeight = props.height;
}
// Apply DPR
newWidth *= this._dpr;
newHeight *= this._dpr;
// Update canvas size
this._width = newWidth;
this._height = newHeight;
canvas.width = newWidth;
canvas.height = newHeight;
// Callbacks
this.callbacks.emit('resize', undefined);
}
/**
* Renders content on the canvas if it's ready.
*
* @param render - A function that performs the actual rendering on the canvas.
*/
render(render) {
if (!this.canRender) {
return;
}
render({
ctx: this.ctx,
width: this.width,
height: this.height,
dpr: this.dpr,
offsetWidth: this.offsetWidth,
offsetHeight: this.offsetHeight,
canvas: this.canvas,
});
}
/** Destroys the canvas. */
_destroy() {
super._destroy();
this.canvas.remove();
}
}
__decorate([
noopIfDestroyed
], Canvas.prototype, "resize", null);
__decorate([
noopIfDestroyed
], Canvas.prototype, "render", null);
//# sourceMappingURL=index.js.map