UNPKG

react-design-editor

Version:

Design Editor Tools with React.js + ant.design + fabric.js

347 lines (346 loc) 12.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const animejs_1 = __importDefault(require("animejs")); const warning_1 = __importDefault(require("warning")); class AnimationHandler { constructor(handler) { /** * Play the animation * @param {string} id * @param {boolean} [hasControls] * @returns */ this.play = (id, hasControls) => { const findObject = this.handler.findById(id); if (!findObject) { return; } if (findObject.anime) { findObject.anime.restart(); return; } if (findObject.animation.type === 'none') { return; } const instance = this.getAnime(findObject, hasControls); if (instance) { findObject.set('anime', instance); findObject.set({ hasControls: false, lockMovementX: true, lockMovementY: true, hoverCursor: 'pointer', }); this.handler.canvas.requestRenderAll(); instance.play(); } }; /** * Pause the animation * @param {string} id * @returns */ this.pause = (id) => { const findObject = this.handler.findById(id); if (!findObject) { return; } findObject.anime.pause(); }; /** * Stop the animation * @param {string} id * @param {boolean} [hasControls=true] * @returns */ this.stop = (id, hasControls = true) => { const findObject = this.handler.findById(id); if (!findObject) { return; } this.resetAnimation(findObject, hasControls); }; /** * Restart the animation * @param {string} id * @returns */ this.restart = (id) => { const findObject = this.handler.findById(id); if (!findObject) { return; } if (!findObject.anime) { return; } this.stop(id); this.play(id); }; /** * Reset animation * * @param {FabricObject} obj * @param {boolean} [hasControls=true] * @returns */ this.resetAnimation = (obj, hasControls = true) => { if (!obj.anime) { return; } let option; if (this.handler.editable) { option = { anime: null, hasControls, lockMovementX: !hasControls, lockMovementY: !hasControls, hoverCursor: hasControls ? 'move' : 'pointer', }; } else { option = { anime: null, hasControls: false, lockMovementX: true, lockMovementY: true, hoverCursor: 'pointer', }; } animejs_1.default.remove(obj); const { type } = obj.animation; if (type === 'fade') { Object.assign(option, { opacity: obj.originOpacity, originOpacity: null, }); } else if (type === 'bounce') { if (obj.animation.bounce === 'vertical') { Object.assign(option, { top: obj.originTop, originTop: null, }); } else { Object.assign(option, { left: obj.originLeft, originLeft: null, }); } } else if (type === 'shake') { if (obj.animation.shake === 'vertical') { Object.assign(option, { top: obj.originTop, originTop: null, }); } else { Object.assign(option, { left: obj.originLeft, originLeft: null, }); } } else if (type === 'scaling') { Object.assign(option, { scaleX: obj.originScaleX, scaleY: obj.originScaleY, originScaleX: null, originScaleY: null, }); } else if (type === 'rotation') { Object.assign(option, { angle: obj.originAngle, rotation: obj.originAngle, left: obj.originLeft, top: obj.originTop, originLeft: null, originTop: null, originAngle: null, }); } else if (type === 'flash') { if (obj.type === 'svg') { obj._objects.forEach(child => this.handler.setByPartial(child, { fill: child.originFill, stroke: child.originStroke, originFill: null, originStroke: null, })); } Object.assign(option, { fill: obj.originFill, stroke: obj.originStroke, originFill: null, originStroke: null, }); } else { console.warn('Not supported type.'); } obj.set(option); this.handler.canvas.renderAll(); }; /** * Get animation option * * @param {FabricObject} obj * @param {boolean} [hasControls] * @returns */ this.getAnime = (obj, hasControls) => { const { delay = 0, duration = 100, autoplay = true, loop = true, type, ...other } = obj.animation; const option = { targets: obj, delay, loop, autoplay, duration, direction: 'alternate', begin: () => { obj.set({ hasControls: false, lockMovementX: true, lockMovementY: true, hoverCursor: 'pointer', }); this.handler.canvas.requestRenderAll(); }, update: (instance) => { if (type === 'flash') { // I don't know why it works. Magic code... (0, warning_1.default)(instance.animations[0], 'instance.animations[0] undefined.'); (0, warning_1.default)(instance.animations[1], 'instance.animations[1] undefined.'); const fill = instance.animations[0]?.currentValue; const stroke = instance.animations[1]?.currentValue; if (obj.type === 'svg') { obj.setFill(fill); obj.setStroke(stroke); } else { obj.set('fill', ''); obj.set('fill', fill); obj.set('stroke', stroke); } } else if (type === 'rotation') { let angle = instance.animations[0].currentValue; if (typeof angle === 'string') { angle = parseInt(angle, 10); } obj.rotate(angle); this.handler.canvas.requestRenderAll(); return; } obj.setCoords(); this.handler.canvas.requestRenderAll(); }, complete: () => { this.resetAnimation(obj, hasControls); }, }; if (type === 'fade') { const { opacity = 0 } = other; obj.set('originOpacity', obj.opacity); Object.assign(option, { opacity, easing: 'easeInQuad', }); } else if (type === 'bounce') { const { offset = 1 } = other; if (other.bounce === 'vertical') { obj.set('originTop', obj.top); Object.assign(option, { top: obj.top + offset, easing: 'easeInQuad', }); } else { obj.set('originLeft', obj.left); Object.assign(option, { left: obj.left + offset, easing: 'easeInQuad', }); } } else if (type === 'shake') { const { offset = 1 } = other; if (other.shake === 'vertical') { obj.set('originTop', obj.top); Object.assign(option, { top: obj.top + offset, delay: 0, elasticity: 1000, duration: 500, }); } else { obj.set('originLeft', obj.left); Object.assign(option, { left: obj.left + offset, delay: 0, elasticity: 1000, duration: 500, }); } } else if (type === 'scaling') { const { scale = 2 } = other; obj.set('originScaleX', obj.scaleX); obj.set('originScaleY', obj.scaleY); obj.set({ originScaleX: obj.scaleX, originScaleY: obj.scaleY, }); const scaleX = obj.scaleX * scale; const scaleY = obj.scaleY * scale; Object.assign(option, { scaleX, scaleY, easing: 'easeInQuad', }); } else if (type === 'rotation') { const { angle = 360 } = other; obj.set('rotation', obj.angle); obj.set('originAngle', obj.angle); obj.set('originLeft', obj.left); obj.set('originTop', obj.top); Object.assign(option, { rotation: angle, easing: 'linear', direction: 'normal', }); } else if (type === 'flash') { const { fill = obj.fill, stroke = obj.stroke } = other; if (obj.type === 'svg') { obj._objects.forEach(child => this.handler.setByPartial(child, { originFill: child.fill, originStroke: child.stroke, })); } obj.set('originFill', obj.fill); obj.set('originStroke', obj.stroke); Object.assign(option, { fill, stroke, easing: 'easeInQuad', }); } else { console.warn('Not supported type.'); return null; } return (0, animejs_1.default)(option); }; this.handler = handler; } } exports.default = AnimationHandler;