UNPKG

sprite-frame-animation

Version:

A user-friendly Sprite frame animation library

344 lines (340 loc) 11.7 kB
/*! * sprite-frame-animation 1.0.0 (https://github.com/CNLHB/spriteFrame) * API https://github.com/CNLHB/spriteFrame/blob/master/doc/api.md * Copyright 2017-2025 CNLHB. All Rights Reserved * Licensed under MIT (https://github.com/CNLHB/spriteFrame/blob/master/LICENSE) */ import _asyncToGenerator from '@babel/runtime-corejs3/helpers/asyncToGenerator'; import _classCallCheck from '@babel/runtime-corejs3/helpers/classCallCheck'; import _createClass from '@babel/runtime-corejs3/helpers/createClass'; import _regeneratorRuntime from '@babel/runtime-corejs3/regenerator'; import _Map from '@babel/runtime-corejs3/core-js-stable/map'; import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each'; import _setTimeout from '@babel/runtime-corejs3/core-js-stable/set-timeout'; import _Promise from '@babel/runtime-corejs3/core-js-stable/promise'; import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat'; import _Date$now from '@babel/runtime-corejs3/core-js-stable/date/now'; var SPRITE_FRAME_ANIMATION_VERSION = '1.0.0'; var SPRITE_FRAME_ANIMATION_NAME = '_SPRITE_FRAME_ANIMATION_NAME_'; var SpriteFrameAnimation = /*#__PURE__*/function () { function SpriteFrameAnimation(options) { _classCallCheck(this, SpriteFrameAnimation); this.version = SPRITE_FRAME_ANIMATION_VERSION; this.initParam(); this.reset(options); this.init(options); this.validateName(); } _createClass(SpriteFrameAnimation, [{ key: "validateName", value: function validateName() { var key = SPRITE_FRAME_ANIMATION_NAME + this.name; this.key = key; var oldInstace = window[key]; if (this.name && !oldInstace) { window[this.key] = this; } else { console.warn('The animation name already exists', oldInstace); } } }, { key: "initParam", value: function initParam() { this.name = ''; //动画名称 this.width = 0; //帧动画每帧的宽度 this.height = 0; //帧动画每帧的高度 this.img = 0; //一个动画的完整序列帧url this.orient = 'left-right'; //关键帧图片的排列方式 this.count = 0; //动画循环次数 this.delay = 0; //动画延时多久开始 this.duration = 1000; //动画持续时间ms this.autoplay = true; this.currentKey = 0; //开始索引帧 this.totalKeyNum = 0; //总帧数据 this.paramMd5 = ''; this.delayFunc = []; this.spriteArray = []; this.interval = 0; //动画执行间隔时间 this.isAnimating = false; this.isLoadingImage = true; this.image = null; // 图片实例 this.fImage = null; // 首次渲染图片实例 this.eventMap = new _Map(); } }, { key: "reset", value: function reset(options) { var isReload = options.img && this.img && options.img !== this.img; //ani上的属性,全部赋值一遍 for (var attr in options) { this[attr] = options[attr]; } if (isReload) { console.log('Reload animation resources', options.img); this.init(options); } } }, { key: "initElement", value: function () { var _initElement = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(options) { var container, fImg; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (!this.canvasRef) { container = options.container; if (options.firstImg && !this.image) { fImg = document.createElement('img'); fImg.style.width = '100%'; fImg.style.height = '100%'; fImg.src = options.firstImg; container.appendChild(fImg); this.fImage = fImg; } this.canvasRef = document.createElement('canvas'); this.canvasRef.width = this.width; this.canvasRef.height = this.height; this.canvasRef.style.width = '100%'; this.canvasRef.style.height = '100%'; container.appendChild(this.canvasRef); } case 1: case "end": return _context.stop(); } }, _callee, this); })); function initElement(_x) { return _initElement.apply(this, arguments); } return initElement; }() }, { key: "getCurrentImage", value: function () { var _getCurrentImage = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: if (!(this.image && this.image.src === this.img)) { _context2.next = 2; break; } return _context2.abrupt("return", this.image); case 2: _context2.t0 = this.image; if (_context2.t0) { _context2.next = 7; break; } _context2.next = 6; return getImgData(this.img); case 6: _context2.t0 = _context2.sent; case 7: return _context2.abrupt("return", _context2.t0); case 8: case "end": return _context2.stop(); } }, _callee2, this); })); function getCurrentImage() { return _getCurrentImage.apply(this, arguments); } return getCurrentImage; }() }, { key: "init", value: function () { var _init = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(options) { var _this = this; var imageInstce, idx, _context3; return _regeneratorRuntime.wrap(function _callee3$(_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: this.initElement(options); this.clearFrame(); if (this.img) { _context4.next = 4; break; } return _context4.abrupt("return", false); case 4: _context4.next = 6; return this.getCurrentImage(); case 6: imageInstce = _context4.sent; if (imageInstce) { _context4.next = 10; break; } console.error("".concat(this.img, " load failed")); return _context4.abrupt("return", false); case 10: this.isLoadingImage = false; this.image = imageInstce; //持续时间 // if (typeof this.duration === 'string') { // let duration = this.duration.match(/^([\d|.]+)ms|([\d|.]+)s$/i); // duration = duration[1] || duration[2] * 1000; // this.duration = +duration; // } //持续时间 // if (typeof this.interval === 'string') { // let interval = this.interval.match(/^([\d|.]+)ms|([\d|.]+)s$/i); // interval = interval[1] || interval[2] * 1000; // this.interval = +interval; // } //每帧的坐标信息 for (idx = 0; idx < this.totalKeyNum; ++idx) { if (this.orient === 'left-right') { this.spriteArray.push({ x: idx * this.width, y: 0 }); } else { this.spriteArray.push({ x: 0, y: idx * this.height }); } } this.showCover(); if (this.autoplay) { this.start(); } else { _forEachInstanceProperty(_context3 = this.delayFunc).call(_context3, function (fn) { fn.call(_this); }); } case 15: case "end": return _context4.stop(); } }, _callee3, this); })); function init(_x2) { return _init.apply(this, arguments); } return init; }() }, { key: "start", value: function start() { var _this2 = this; if (!this.image) { this.delayFunc.push(this.start); return; } var ctx = this.canvasRef.getContext('2d'); var aniTimes = 0; //开始动画吧 if (this.isAnimating) { return; // 防止重复启动 } this.isAnimating = true; this[this.key] = _setTimeout(function () { drawImg(_this2, ctx); }, this.delay); function drawImg(self, ctx) { var end = false; ctx.clearRect(0, 0, self.width, self.height); ctx.drawImage(self.image, self.spriteArray[self.currentKey].x, self.spriteArray[self.currentKey].y, self.width, self.height, 0, 0, self.width, self.height); if (self.currentKey !== self.totalKeyNum - 1) { //到了最后一帧 self.currentKey++; } else { self.currentKey = 2; aniTimes++; end = true; if (self.count && aniTimes >= self.count) { //动画结束 self.emitEnd(); return; } } self[self.key] = _setTimeout(function () { drawImg(self, ctx); }, end && self.interval ? self.interval : self.duration / self.totalKeyNum); } } }, { key: "showCover", value: function showCover() { var canvas = this.canvasRef; if (!canvas) return; var ctx = canvas.getContext('2d'); //先画封面 ctx.drawImage(this.image, 0, 0, this.width, this.height, 0, 0, this.width, this.height); // 显示完封面,删除 if (this.fImage) { this.fImage.remove(); } } }, { key: "stop", value: function stop() { this.clearFrame(); } }, { key: "clearFrame", value: function clearFrame() { console.log('clearFrame'); this.isLoadingImage = true; this.isAnimating = false; clearTimeout(this[this.key]); } }, { key: "destroy", value: function destroy() { this.stop(); this.canvasRef.remove(); if (this.fImage) { this.fImage.remove(); } window[this.key] = null; } /** * 简单实现事件监听 * @param {*} type * @param {*} fn */ }, { key: "on", value: function on(type, fn) { var oldEvents = this.eventMap.get(type); if (oldEvents) { oldEvents.push(fn); } else { var events = [fn]; this.eventMap.set(type, events); } } }, { key: "emitEnd", value: function emitEnd() { var _context5; this.eventMap.get('end') && _forEachInstanceProperty(_context5 = this.eventMap.get('end')).call(_context5, function (fn) { return fn(); }); } }]); return SpriteFrameAnimation; }(); // 获取图片数据 function getImgData(url, isNeedCross) { return new _Promise(function (resolve) { var _context6; var image = new Image(); image.onload = function () { resolve(image); }; image.onerror = function () { resolve(null); }; image.src = _concatInstanceProperty(_context6 = "".concat(url, "?")).call(_context6, _Date$now()); }); } export { SpriteFrameAnimation as default }; //# sourceMappingURL=index.mjs.map