|
@@ -0,0 +1,209 @@
|
|
|
+/**
|
|
|
+ * 烟花特效
|
|
|
+ */
|
|
|
+function Event() {
|
|
|
+ this.events = {};
|
|
|
+}
|
|
|
+Event.prototype.addEventListener = function(type, listener) {
|
|
|
+ this.events[type] = this.events[type] || [];
|
|
|
+ this.events[type].push(listener);
|
|
|
+};
|
|
|
+Event.prototype.trigger = function() {
|
|
|
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
|
|
+ args[_key] = arguments[_key];
|
|
|
+ }
|
|
|
+
|
|
|
+ var type = args[0];
|
|
|
+ var params = args.slice(1);
|
|
|
+ if (!!this.events[type]) {
|
|
|
+ // console.log("type:",type);
|
|
|
+ this.events[type].forEach(function(listener) {
|
|
|
+ try {
|
|
|
+ listener.apply(null, params);
|
|
|
+ } catch (e) {
|
|
|
+ console.error(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+};
|
|
|
+// get a random number within a range
|
|
|
+function random(min, max) {
|
|
|
+ return Math.random() * (max - min) + min;
|
|
|
+}
|
|
|
+
|
|
|
+// calculate the distance between two points
|
|
|
+function calculateDistance(p1x, p1y, p2x, p2y) {
|
|
|
+ var xDistance = p1x - p2x,
|
|
|
+ yDistance = p1y - p2y;
|
|
|
+ return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// create firework
|
|
|
+var Firework = function Firework(image, typeImage, direction, tx, ty, cw, ch) {
|
|
|
+ this.event = new Event();
|
|
|
+ //图片信息
|
|
|
+ this.image = image;
|
|
|
+ this.typeImage = typeImage;
|
|
|
+ this.direction = direction;
|
|
|
+ this.position = {
|
|
|
+ "EF_baozha_0": [0, 0, 312, 312],
|
|
|
+ "EF_baozha_1": [312, 0, 312, 312],
|
|
|
+ "EF_baozha_2": [624, 0, 312, 312],
|
|
|
+ "EF_baozha_3": [936, 0, 312, 312],
|
|
|
+ "EF_baozha_4": [0, 312, 312, 312],
|
|
|
+ "EF_baozha_5": [312, 312, 312, 312],
|
|
|
+ "EF_baozha_6": [624, 312, 312, 312],
|
|
|
+ "EF_baozha_7": [936, 312, 312, 312],
|
|
|
+ "EF_baozha_8": [0, 624, 312, 312],
|
|
|
+ "EF_baozha_9": [312, 624, 312, 312],
|
|
|
+ "EF_baozha_10": [624, 624, 312, 312],
|
|
|
+ "EF_baozha_11": [936, 624, 312, 312],
|
|
|
+ "EF_baozha_12": [0, 936, 312, 312],
|
|
|
+ "EF_baozha_13": [312, 936, 312, 312],
|
|
|
+ "EF_baozha_14": [624, 936, 312, 312],
|
|
|
+ "EF_baozha_15": [936, 936, 312, 312],
|
|
|
+ "EF_baozha_16": [0, 1248, 312, 312],
|
|
|
+ "EF_baozha_17": [312, 1248, 312, 312],
|
|
|
+ "EF_baozha_18": [624, 1248, 312, 312],
|
|
|
+ "EF_baozha_19": [936, 1248, 312, 312]
|
|
|
+ };
|
|
|
+ // target coordinates
|
|
|
+ this.tx = tx;
|
|
|
+ this.ty = ty;
|
|
|
+
|
|
|
+ this.cw = cw;
|
|
|
+ this.ch = ch;
|
|
|
+
|
|
|
+ this.index = 0;
|
|
|
+ // let _this = this;
|
|
|
+ // this.animationInstance = new Animation({
|
|
|
+ // timing: 'easeIn',
|
|
|
+ // duration: 1000,
|
|
|
+ // onProcess: function onProcess(process) {
|
|
|
+ // _this.event.trigger('renderProcess', process);
|
|
|
+
|
|
|
+ // },
|
|
|
+ // onAnimationFinish: function onAnimationFinish() {
|
|
|
+ // _this.event.trigger('renderComplete');
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+}
|
|
|
+
|
|
|
+Firework.prototype.addEventListener = function(type, listener) {
|
|
|
+ this.event.addEventListener(type, listener);
|
|
|
+};
|
|
|
+
|
|
|
+// draw firework
|
|
|
+Firework.prototype.draw = function(ctx, callback) {
|
|
|
+ if (this.index > 19) return;
|
|
|
+ let i = this.index;
|
|
|
+ let temp = this.position["EF_baozha_" + i];
|
|
|
+ // console.log("draw:"+this.direction);
|
|
|
+ let tempX = this.tx * this.direction;
|
|
|
+ let tempValue = this.direction < 0 ? 20 : -20
|
|
|
+ ctx.drawImage(this.image.path,
|
|
|
+ temp[0] //截取原始图片的 x坐标
|
|
|
+ , temp[1] //截取原始图片的 y坐标
|
|
|
+ , 312 //截取原始图片的 宽度
|
|
|
+ , 312 // 截取的高度
|
|
|
+ , tempX - 164 * 0.5 - tempValue //图片在canvas画布上的x坐标
|
|
|
+ , 0 //图片在canvas画布上的y坐标
|
|
|
+ , 164 //绘制图片的宽度
|
|
|
+ , 164 //绘制图片的高度
|
|
|
+ );
|
|
|
+ let _r = this.index / 19;
|
|
|
+ ctx.save();
|
|
|
+ //如果是相反绘制,需要加多一个自身位置偏移
|
|
|
+ let _pos = this.direction < 0 ? this.typeImage.width : 0;
|
|
|
+ //左边位置
|
|
|
+ let left = (this.typeImage.width + tempX - 164 * 0.5) - (this.typeImage.width / 2 - _pos) * _r + 20 - tempValue;
|
|
|
+ // 中心点 this.cw / 2 - this.typeImage.width / 2 * _r
|
|
|
+ ctx.translate(left, this.ch / 2 - this.typeImage.height / 2 * _r);
|
|
|
+ ctx.scale(_r * this.direction, _r);
|
|
|
+ ctx.drawImage(this.typeImage.path, 0, 0);
|
|
|
+ ctx.restore();
|
|
|
+ if (i === 19 && callback) {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ this.index++;
|
|
|
+
|
|
|
+}
|
|
|
+var Timing = {
|
|
|
+ easeIn: function easeIn(pos) {
|
|
|
+ return Math.pow(pos, 3);
|
|
|
+ },
|
|
|
+ easeOut: function easeOut(pos) {
|
|
|
+ return Math.pow(pos - 1, 3) + 1;
|
|
|
+ },
|
|
|
+ easeInOut: function easeInOut(pos) {
|
|
|
+ if ((pos /= 0.5) < 1) {
|
|
|
+ return 0.5 * Math.pow(pos, 3);
|
|
|
+ } else {
|
|
|
+ return 0.5 * (Math.pow(pos - 2, 3) + 2);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ linear: function linear(pos) {
|
|
|
+ return pos;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+function Animation(opts) {
|
|
|
+ this.isStop = false;
|
|
|
+ opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
|
|
|
+ opts.timing = opts.timing || 'linear';
|
|
|
+ var delay = 17;
|
|
|
+
|
|
|
+ function createAnimationFrame() {
|
|
|
+ if (typeof setTimeout !== 'undefined') {
|
|
|
+ return function(step, delay) {
|
|
|
+ setTimeout(function() {
|
|
|
+ var timeStamp = +new Date();
|
|
|
+ step(timeStamp);
|
|
|
+ }, delay);
|
|
|
+ };
|
|
|
+ } else if (typeof requestAnimationFrame !== 'undefined') {
|
|
|
+ return requestAnimationFrame;
|
|
|
+ } else {
|
|
|
+ return function(step) {
|
|
|
+ step(null);
|
|
|
+ };
|
|
|
+ }
|
|
|
+ };
|
|
|
+ var animationFrame = createAnimationFrame();
|
|
|
+ var startTimeStamp = null;
|
|
|
+ var _step = function step(timestamp) {
|
|
|
+ if (timestamp === null || this.isStop === true) {
|
|
|
+ opts.onProcess && opts.onProcess(1);
|
|
|
+ opts.onAnimationFinish && opts.onAnimationFinish();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (startTimeStamp === null) {
|
|
|
+ startTimeStamp = timestamp;
|
|
|
+ }
|
|
|
+ if (timestamp - startTimeStamp < opts.duration) {
|
|
|
+ var process = (timestamp - startTimeStamp) / opts.duration;
|
|
|
+ var timingFunction = Timing[opts.timing];
|
|
|
+ process = timingFunction(process);
|
|
|
+
|
|
|
+ opts.onProcess && opts.onProcess(process);
|
|
|
+ animationFrame(_step, delay);
|
|
|
+ } else {
|
|
|
+ opts.onProcess && opts.onProcess(1);
|
|
|
+ opts.onAnimationFinish && opts.onAnimationFinish();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ _step = _step.bind(this);
|
|
|
+ animationFrame(_step, delay);
|
|
|
+}
|
|
|
+
|
|
|
+// stop animation immediately
|
|
|
+// and tigger onAnimationFinish
|
|
|
+Animation.prototype.stop = function() {
|
|
|
+ this.isStop = true;
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+if (typeof module === "object" && typeof module.exports === "object") {
|
|
|
+ module.exports = Firework;
|
|
|
+}
|