firework.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * 烟花特效
  3. */
  4. function Event() {
  5. this.events = {};
  6. }
  7. Event.prototype.addEventListener = function(type, listener) {
  8. this.events[type] = this.events[type] || [];
  9. this.events[type].push(listener);
  10. };
  11. Event.prototype.trigger = function() {
  12. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  13. args[_key] = arguments[_key];
  14. }
  15. var type = args[0];
  16. var params = args.slice(1);
  17. if (!!this.events[type]) {
  18. // console.log("type:",type);
  19. this.events[type].forEach(function(listener) {
  20. try {
  21. listener.apply(null, params);
  22. } catch (e) {
  23. console.error(e);
  24. }
  25. });
  26. }
  27. };
  28. // get a random number within a range
  29. function random(min, max) {
  30. return Math.random() * (max - min) + min;
  31. }
  32. // calculate the distance between two points
  33. function calculateDistance(p1x, p1y, p2x, p2y) {
  34. var xDistance = p1x - p2x,
  35. yDistance = p1y - p2y;
  36. return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
  37. }
  38. // create firework
  39. var Firework = function Firework(image, typeImage, direction, tx, ty, cw, ch) {
  40. this.event = new Event();
  41. //图片信息
  42. this.image = image;
  43. this.typeImage = typeImage;
  44. this.direction = direction;
  45. this.position = {
  46. "EF_baozha_0": [0, 0, 312, 312],
  47. "EF_baozha_1": [312, 0, 312, 312],
  48. "EF_baozha_2": [624, 0, 312, 312],
  49. "EF_baozha_3": [936, 0, 312, 312],
  50. "EF_baozha_4": [0, 312, 312, 312],
  51. "EF_baozha_5": [312, 312, 312, 312],
  52. "EF_baozha_6": [624, 312, 312, 312],
  53. "EF_baozha_7": [936, 312, 312, 312],
  54. "EF_baozha_8": [0, 624, 312, 312],
  55. "EF_baozha_9": [312, 624, 312, 312],
  56. "EF_baozha_10": [624, 624, 312, 312],
  57. "EF_baozha_11": [936, 624, 312, 312],
  58. "EF_baozha_12": [0, 936, 312, 312],
  59. "EF_baozha_13": [312, 936, 312, 312],
  60. "EF_baozha_14": [624, 936, 312, 312],
  61. "EF_baozha_15": [936, 936, 312, 312],
  62. "EF_baozha_16": [0, 1248, 312, 312],
  63. "EF_baozha_17": [312, 1248, 312, 312],
  64. "EF_baozha_18": [624, 1248, 312, 312],
  65. "EF_baozha_19": [936, 1248, 312, 312]
  66. };
  67. // target coordinates
  68. this.tx = tx;
  69. this.ty = ty;
  70. this.cw = cw;
  71. this.ch = ch;
  72. this.index = 0;
  73. // let _this = this;
  74. // this.animationInstance = new Animation({
  75. // timing: 'easeIn',
  76. // duration: 1000,
  77. // onProcess: function onProcess(process) {
  78. // _this.event.trigger('renderProcess', process);
  79. // },
  80. // onAnimationFinish: function onAnimationFinish() {
  81. // _this.event.trigger('renderComplete');
  82. // }
  83. // });
  84. this.hiddenMidImage = false;
  85. const innerAudioContext = uni.createInnerAudioContext();
  86. innerAudioContext.autoplay = true;
  87. innerAudioContext.src = '/static/elect/hit.mp3';
  88. innerAudioContext.onPlay(() => {
  89. // console.log('开始播放');
  90. });
  91. innerAudioContext.onError((res) => {
  92. console.log(res.errMsg);
  93. console.log(res.errCode);
  94. });
  95. setTimeout(()=>{
  96. innerAudioContext.destroy();
  97. },800)
  98. }
  99. Firework.prototype.addEventListener = function(type, listener) {
  100. this.event.addEventListener(type, listener);
  101. };
  102. // draw firework
  103. Firework.prototype.draw = function(ctx, callback) {
  104. if (this.index > 19) return;
  105. let i = this.index;
  106. let temp = this.position["EF_baozha_" + i];
  107. // console.log("draw:"+this.direction);
  108. let tempX = this.tx * this.direction;
  109. let tempValue = this.direction < 0 ? 65 : -25
  110. ctx.drawImage(this.image.path,
  111. temp[0] //截取原始图片的 x坐标
  112. , temp[1] //截取原始图片的 y坐标
  113. , 312 //截取原始图片的 宽度
  114. , 312 // 截取的高度
  115. , tempX - 164 * 0.5 - tempValue //图片在canvas画布上的x坐标
  116. , 0 //图片在canvas画布上的y坐标
  117. , 164 //绘制图片的宽度
  118. , 164 //绘制图片的高度
  119. );
  120. if(!this.hiddenMidImage){
  121. let _r = this.index / 19;
  122. ctx.save();
  123. //如果是相反绘制,需要加多一个自身位置偏移
  124. let _pos = this.direction < 0 ? this.typeImage.width : 0;
  125. //左边位置
  126. let left = (this.typeImage.width + tempX - 164 * 0.5) - (this.typeImage.width / 2 - _pos) * _r + 20 - tempValue;
  127. // 中心点 this.cw / 2 - this.typeImage.width / 2 * _r
  128. ctx.translate(left, this.ch / 2 - this.typeImage.height / 2 * _r);
  129. ctx.scale(_r * this.direction, _r);
  130. ctx.drawImage(this.typeImage.path, 0, 0);
  131. ctx.restore();
  132. }
  133. if (i === 19 && callback) {
  134. callback();
  135. }
  136. this.index++;
  137. }
  138. var Timing = {
  139. easeIn: function easeIn(pos) {
  140. return Math.pow(pos, 3);
  141. },
  142. easeOut: function easeOut(pos) {
  143. return Math.pow(pos - 1, 3) + 1;
  144. },
  145. easeInOut: function easeInOut(pos) {
  146. if ((pos /= 0.5) < 1) {
  147. return 0.5 * Math.pow(pos, 3);
  148. } else {
  149. return 0.5 * (Math.pow(pos - 2, 3) + 2);
  150. }
  151. },
  152. linear: function linear(pos) {
  153. return pos;
  154. }
  155. };
  156. function Animation(opts) {
  157. this.isStop = false;
  158. opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
  159. opts.timing = opts.timing || 'linear';
  160. var delay = 17;
  161. function createAnimationFrame() {
  162. if (typeof setTimeout !== 'undefined') {
  163. return function(step, delay) {
  164. setTimeout(function() {
  165. var timeStamp = +new Date();
  166. step(timeStamp);
  167. }, delay);
  168. };
  169. } else if (typeof requestAnimationFrame !== 'undefined') {
  170. return requestAnimationFrame;
  171. } else {
  172. return function(step) {
  173. step(null);
  174. };
  175. }
  176. };
  177. var animationFrame = createAnimationFrame();
  178. var startTimeStamp = null;
  179. var _step = function step(timestamp) {
  180. if (timestamp === null || this.isStop === true) {
  181. opts.onProcess && opts.onProcess(1);
  182. opts.onAnimationFinish && opts.onAnimationFinish();
  183. return;
  184. }
  185. if (startTimeStamp === null) {
  186. startTimeStamp = timestamp;
  187. }
  188. if (timestamp - startTimeStamp < opts.duration) {
  189. var process = (timestamp - startTimeStamp) / opts.duration;
  190. var timingFunction = Timing[opts.timing];
  191. process = timingFunction(process);
  192. opts.onProcess && opts.onProcess(process);
  193. animationFrame(_step, delay);
  194. } else {
  195. opts.onProcess && opts.onProcess(1);
  196. opts.onAnimationFinish && opts.onAnimationFinish();
  197. }
  198. };
  199. _step = _step.bind(this);
  200. animationFrame(_step, delay);
  201. }
  202. // stop animation immediately
  203. // and tigger onAnimationFinish
  204. Animation.prototype.stop = function() {
  205. this.isStop = true;
  206. };
  207. if (typeof module === "object" && typeof module.exports === "object") {
  208. module.exports = Firework;
  209. }