当前位置:   article > 正文

(三款)Html5+Css+JavaScript实现2023年跨年代码烟花设计_跨年代码可复制2024

跨年代码可复制2024

简介

一共是三款烟花设计

Html5+Css+JavaScript实现2023年跨年代码烟花设计

主题

 

第一款

(有雪花设计没有音乐)

index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>计算机基础与编程</title>
  6. <style>
  7. html,
  8. body {
  9. margin: 0px;
  10. width: 100%;
  11. height: 100%;
  12. overflow: hidden;
  13. background: #000;
  14. }
  15. </style>
  16. </head>
  17. <body>
  18. <canvas
  19. id="canvas"
  20. style="position: absolute; width: 100%; height: 100%; z-index: 8888"
  21. ></canvas>
  22. <canvas
  23. style="position: absolute; width: 100%; height: 100%; z-index: 9999"
  24. class="canvas"
  25. ></canvas>
  26. <div class="overlay">
  27. <div class="tabs">
  28. <div class="tabs-labels">
  29. <span class="tabs-label">Commands</span
  30. ><span class="tabs-label">Info</span
  31. ><span class="tabs-label">Share</span>
  32. </div>
  33. <div class="tabs-panels">
  34. <ul class="tabs-panel commands"></ul>
  35. </div>
  36. </div>
  37. </div>
  38. <script>
  39. function initVars() {
  40. pi = Math.PI;
  41. ctx = canvas.getContext("2d");
  42. canvas.width = canvas.clientWidth;
  43. canvas.height = canvas.clientHeight;
  44. cx = canvas.width / 2;
  45. cy = canvas.height / 2;
  46. playerZ = -25;
  47. playerX =
  48. playerY =
  49. playerVX =
  50. playerVY =
  51. playerVZ =
  52. pitch =
  53. yaw =
  54. pitchV =
  55. yawV =
  56. 0;
  57. scale = 600;
  58. seedTimer = 0;
  59. (seedInterval = 5), (seedLife = 100);
  60. gravity = 0.02;
  61. seeds = new Array();
  62. sparkPics = new Array();
  63. s = "https://cantelope.org/NYE/";
  64. for (i = 1; i <= 10; ++i) {
  65. sparkPic = new Image();
  66. sparkPic.src = s + "spark" + i + ".png";
  67. sparkPics.push(sparkPic);
  68. }
  69. sparks = new Array();
  70. pow1 = new Audio(s + "pow1.ogg");
  71. pow2 = new Audio(s + "pow2.ogg");
  72. pow3 = new Audio(s + "pow3.ogg");
  73. pow4 = new Audio(s + "pow4.ogg");
  74. frames = 0;
  75. }
  76. function rasterizePoint(x, y, z) {
  77. var p, d;
  78. x -= playerX;
  79. y -= playerY;
  80. z -= playerZ;
  81. p = Math.atan2(x, z);
  82. d = Math.sqrt(x * x + z * z);
  83. x = Math.sin(p - yaw) * d;
  84. z = Math.cos(p - yaw) * d;
  85. p = Math.atan2(y, z);
  86. d = Math.sqrt(y * y + z * z);
  87. y = Math.sin(p - pitch) * d;
  88. z = Math.cos(p - pitch) * d;
  89. var rx1 = -1000,
  90. ry1 = 1,
  91. rx2 = 1000,
  92. ry2 = 1,
  93. rx3 = 0,
  94. ry3 = 0,
  95. rx4 = x,
  96. ry4 = z,
  97. uc = (ry4 - ry3) * (rx2 - rx1) - (rx4 - rx3) * (ry2 - ry1);
  98. if (!uc) return { x: 0, y: 0, d: -1 };
  99. var ua = ((rx4 - rx3) * (ry1 - ry3) - (ry4 - ry3) * (rx1 - rx3)) / uc;
  100. var ub = ((rx2 - rx1) * (ry1 - ry3) - (ry2 - ry1) * (rx1 - rx3)) / uc;
  101. if (!z) z = 0.000000001;
  102. if (ua > 0 && ua < 1 && ub > 0 && ub < 1) {
  103. return {
  104. x: cx + (rx1 + ua * (rx2 - rx1)) * scale,
  105. y: cy + (y / z) * scale,
  106. d: Math.sqrt(x * x + y * y + z * z),
  107. };
  108. } else {
  109. return {
  110. x: cx + (rx1 + ua * (rx2 - rx1)) * scale,
  111. y: cy + (y / z) * scale,
  112. d: -1,
  113. };
  114. }
  115. }
  116. function spawnSeed() {
  117. seed = new Object();
  118. seed.x = -50 + Math.random() * 100;
  119. seed.y = 25;
  120. seed.z = -50 + Math.random() * 100;
  121. seed.vx = 0.1 - Math.random() * 0.2;
  122. seed.vy = -1.5; //*(1+Math.random()/2);
  123. seed.vz = 0.1 - Math.random() * 0.2;
  124. seed.born = frames;
  125. seeds.push(seed);
  126. }
  127. function splode(x, y, z) {
  128. t = 5 + parseInt(Math.random() * 150);
  129. sparkV = 1 + Math.random() * 2.5;
  130. type = parseInt(Math.random() * 3);
  131. switch (type) {
  132. case 0:
  133. pic1 = parseInt(Math.random() * 10);
  134. break;
  135. case 1:
  136. pic1 = parseInt(Math.random() * 10);
  137. do {
  138. pic2 = parseInt(Math.random() * 10);
  139. } while (pic2 == pic1);
  140. break;
  141. case 2:
  142. pic1 = parseInt(Math.random() * 10);
  143. do {
  144. pic2 = parseInt(Math.random() * 10);
  145. } while (pic2 == pic1);
  146. do {
  147. pic3 = parseInt(Math.random() * 10);
  148. } while (pic3 == pic1 || pic3 == pic2);
  149. break;
  150. }
  151. for (m = 1; m < t; ++m) {
  152. spark = new Object();
  153. spark.x = x;
  154. spark.y = y;
  155. spark.z = z;
  156. p1 = pi * 2 * Math.random();
  157. p2 = pi * Math.random();
  158. v = sparkV * (1 + Math.random() / 6);
  159. spark.vx = Math.sin(p1) * Math.sin(p2) * v;
  160. spark.vz = Math.cos(p1) * Math.sin(p2) * v;
  161. spark.vy = Math.cos(p2) * v;
  162. switch (type) {
  163. case 0:
  164. spark.img = sparkPics[pic1];
  165. break;
  166. case 1:
  167. spark.img = sparkPics[parseInt(Math.random() * 2) ? pic1 : pic2];
  168. break;
  169. case 2:
  170. switch (parseInt(Math.random() * 3)) {
  171. case 0:
  172. spark.img = sparkPics[pic1];
  173. break;
  174. case 1:
  175. spark.img = sparkPics[pic2];
  176. break;
  177. case 2:
  178. spark.img = sparkPics[pic3];
  179. break;
  180. }
  181. break;
  182. }
  183. spark.radius = 25 + Math.random() * 50;
  184. spark.alpha = 1;
  185. spark.trail = new Array();
  186. sparks.push(spark);
  187. }
  188. switch (parseInt(Math.random() * 4)) {
  189. case 0:
  190. pow = new Audio(s + "pow1.ogg");
  191. break;
  192. case 1:
  193. pow = new Audio(s + "pow2.ogg");
  194. break;
  195. case 2:
  196. pow = new Audio(s + "pow3.ogg");
  197. break;
  198. case 3:
  199. pow = new Audio(s + "pow4.ogg");
  200. break;
  201. }
  202. d = Math.sqrt(
  203. (x - playerX) * (x - playerX) +
  204. (y - playerY) * (y - playerY) +
  205. (z - playerZ) * (z - playerZ)
  206. );
  207. pow.volume = 1.5 / (1 + d / 10);
  208. pow.play();
  209. }
  210. function doLogic() {
  211. if (seedTimer < frames) {
  212. seedTimer = frames + seedInterval * Math.random() * 10;
  213. spawnSeed();
  214. }
  215. for (i = 0; i < seeds.length; ++i) {
  216. seeds[i].vy += gravity;
  217. seeds[i].x += seeds[i].vx;
  218. seeds[i].y += seeds[i].vy;
  219. seeds[i].z += seeds[i].vz;
  220. if (frames - seeds[i].born > seedLife) {
  221. splode(seeds[i].x, seeds[i].y, seeds[i].z);
  222. seeds.splice(i, 1);
  223. }
  224. }
  225. for (i = 0; i < sparks.length; ++i) {
  226. if (sparks[i].alpha > 0 && sparks[i].radius > 5) {
  227. sparks[i].alpha -= 0.01;
  228. sparks[i].radius /= 1.02;
  229. sparks[i].vy += gravity;
  230. point = new Object();
  231. point.x = sparks[i].x;
  232. point.y = sparks[i].y;
  233. point.z = sparks[i].z;
  234. if (sparks[i].trail.length) {
  235. x = sparks[i].trail[sparks[i].trail.length - 1].x;
  236. y = sparks[i].trail[sparks[i].trail.length - 1].y;
  237. z = sparks[i].trail[sparks[i].trail.length - 1].z;
  238. d =
  239. (point.x - x) * (point.x - x) +
  240. (point.y - y) * (point.y - y) +
  241. (point.z - z) * (point.z - z);
  242. if (d > 9) {
  243. sparks[i].trail.push(point);
  244. }
  245. } else {
  246. sparks[i].trail.push(point);
  247. }
  248. if (sparks[i].trail.length > 5) sparks[i].trail.splice(0, 1);
  249. sparks[i].x += sparks[i].vx;
  250. sparks[i].y += sparks[i].vy;
  251. sparks[i].z += sparks[i].vz;
  252. sparks[i].vx /= 1.075;
  253. sparks[i].vy /= 1.075;
  254. sparks[i].vz /= 1.075;
  255. } else {
  256. sparks.splice(i, 1);
  257. }
  258. }
  259. p = Math.atan2(playerX, playerZ);
  260. d = Math.sqrt(playerX * playerX + playerZ * playerZ);
  261. d += Math.sin(frames / 80) / 1.25;
  262. t = Math.sin(frames / 200) / 40;
  263. playerX = Math.sin(p + t) * d;
  264. playerZ = Math.cos(p + t) * d;
  265. yaw = pi + p + t;
  266. }
  267. function rgb(col) {
  268. var r = parseInt((0.5 + Math.sin(col) * 0.5) * 16);
  269. var g = parseInt((0.5 + Math.cos(col) * 0.5) * 16);
  270. var b = parseInt((0.5 - Math.sin(col) * 0.5) * 16);
  271. return "#" + r.toString(16) + g.toString(16) + b.toString(16);
  272. }
  273. function draw() {
  274. ctx.clearRect(0, 0, cx * 2, cy * 2);
  275. ctx.fillStyle = "#ff8";
  276. for (i = -100; i < 100; i += 3) {
  277. for (j = -100; j < 100; j += 4) {
  278. x = i;
  279. z = j;
  280. y = 25;
  281. point = rasterizePoint(x, y, z);
  282. if (point.d != -1) {
  283. size = 250 / (1 + point.d);
  284. d = Math.sqrt(x * x + z * z);
  285. a = 0.75 - Math.pow(d / 100, 6) * 0.75;
  286. if (a > 0) {
  287. ctx.globalAlpha = a;
  288. ctx.fillRect(
  289. point.x - size / 2,
  290. point.y - size / 2,
  291. size,
  292. size
  293. );
  294. }
  295. }
  296. }
  297. }
  298. ctx.globalAlpha = 1;
  299. for (i = 0; i < seeds.length; ++i) {
  300. point = rasterizePoint(seeds[i].x, seeds[i].y, seeds[i].z);
  301. if (point.d != -1) {
  302. size = 200 / (1 + point.d);
  303. ctx.fillRect(point.x - size / 2, point.y - size / 2, size, size);
  304. }
  305. }
  306. point1 = new Object();
  307. for (i = 0; i < sparks.length; ++i) {
  308. point = rasterizePoint(sparks[i].x, sparks[i].y, sparks[i].z);
  309. if (point.d != -1) {
  310. size = (sparks[i].radius * 200) / (1 + point.d);
  311. if (sparks[i].alpha < 0) sparks[i].alpha = 0;
  312. if (sparks[i].trail.length) {
  313. point1.x = point.x;
  314. point1.y = point.y;
  315. switch (sparks[i].img) {
  316. case sparkPics[0]:
  317. ctx.strokeStyle = "#f84";
  318. break;
  319. case sparkPics[1]:
  320. ctx.strokeStyle = "#84f";
  321. break;
  322. case sparkPics[2]:
  323. ctx.strokeStyle = "#8ff";
  324. break;
  325. case sparkPics[3]:
  326. ctx.strokeStyle = "#fff";
  327. break;
  328. case sparkPics[4]:
  329. ctx.strokeStyle = "#4f8";
  330. break;
  331. case sparkPics[5]:
  332. ctx.strokeStyle = "#f44";
  333. break;
  334. case sparkPics[6]:
  335. ctx.strokeStyle = "#f84";
  336. break;
  337. case sparkPics[7]:
  338. ctx.strokeStyle = "#84f";
  339. break;
  340. case sparkPics[8]:
  341. ctx.strokeStyle = "#fff";
  342. break;
  343. case sparkPics[9]:
  344. ctx.strokeStyle = "#44f";
  345. break;
  346. }
  347. for (j = sparks[i].trail.length - 1; j >= 0; --j) {
  348. point2 = rasterizePoint(
  349. sparks[i].trail[j].x,
  350. sparks[i].trail[j].y,
  351. sparks[i].trail[j].z
  352. );
  353. if (point2.d != -1) {
  354. ctx.globalAlpha =
  355. ((j / sparks[i].trail.length) * sparks[i].alpha) / 2;
  356. ctx.beginPath();
  357. ctx.moveTo(point1.x, point1.y);
  358. ctx.lineWidth =
  359. 1 +
  360. (sparks[i].radius * 10) /
  361. (sparks[i].trail.length - j) /
  362. (1 + point2.d);
  363. ctx.lineTo(point2.x, point2.y);
  364. ctx.stroke();
  365. point1.x = point2.x;
  366. point1.y = point2.y;
  367. }
  368. }
  369. }
  370. ctx.globalAlpha = sparks[i].alpha;
  371. ctx.drawImage(
  372. sparks[i].img,
  373. point.x - size / 2,
  374. point.y - size / 2,
  375. size,
  376. size
  377. );
  378. }
  379. }
  380. }
  381. function frame() {
  382. if (frames > 100000) {
  383. seedTimer = 0;
  384. frames = 0;
  385. }
  386. frames++;
  387. draw();
  388. doLogic();
  389. requestAnimationFrame(frame);
  390. }
  391. window.addEventListener("resize", () => {
  392. canvas.width = canvas.clientWidth;
  393. canvas.height = canvas.clientHeight;
  394. cx = canvas.width / 2;
  395. cy = canvas.height / 2;
  396. });
  397. initVars();
  398. frame();
  399. </script>
  400. <script src="js/index.js"></script>
  401. <div id="page_end_html">
  402. <!--放大图片-->
  403. <link
  404. rel="stylesheet"
  405. type="text/css"
  406. href="https://blog-static.cnblogs.com/files/zouwangblog/zoom.css"
  407. />
  408. <script src="https://cdn.bootcss.com/jquery/1.8.3/jquery.min.js"></script>
  409. <script src="https://cdn.bootcss.com/bootstrap/3.2.0/js/transition.js"></script>
  410. <script src="https://blog-static.cnblogs.com/files/zouwangblog/zoom.js"></script>
  411. <script type="text/javascript">
  412. $("#cnblogs_post_body img").attr("data-action", "zoom");
  413. </script>
  414. <!--放大图片end-->
  415. <!--鼠标特效-->
  416. <script src="https://blog-static.cnblogs.com/files/zouwangblog/mouse-click.js"></script>
  417. <canvas
  418. width="1777"
  419. height="841"
  420. style="
  421. position: fixed;
  422. left: 0px;
  423. top: 0px;
  424. z-index: 2147483647;
  425. pointer-events: none;
  426. "
  427. ></canvas>
  428. <!--鼠标特效 end-->
  429. <!-- require APlayer -->
  430. <link
  431. rel="stylesheet"
  432. href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css"
  433. />
  434. <script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
  435. <!-- require MetingJS -->
  436. <script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>
  437. <!-- // 随机线条 -->
  438. <script>
  439. !(function () {
  440. function n(n, e, t) {
  441. return n.getAttribute(e) || t;
  442. }
  443. function e(n) {
  444. return document.getElementsByTagName(n);
  445. }
  446. function t() {
  447. var t = e("script"),
  448. o = t.length,
  449. i = t[o - 1];
  450. return {
  451. l: o,
  452. z: n(i, "zIndex", -1),
  453. o: n(i, "opacity", 0.6),
  454. c: n(i, "color", "148,0,211"),
  455. n: n(i, "count", 99),
  456. };
  457. }
  458. function o() {
  459. (a = m.width =
  460. window.innerWidth ||
  461. document.documentElement.clientWidth ||
  462. document.body.clientWidth),
  463. (c = m.height =
  464. window.innerHeight ||
  465. document.documentElement.clientHeight ||
  466. document.body.clientHeight);
  467. }
  468. function i() {
  469. r.clearRect(0, 0, a, c);
  470. var n, e, t, o, m, l;
  471. s.forEach(function (i, x) {
  472. for (
  473. i.x += i.xa,
  474. i.y += i.ya,
  475. i.xa *= i.x > a || i.x < 0 ? -1 : 1,
  476. i.ya *= i.y > c || i.y < 0 ? -1 : 1,
  477. r.fillRect(i.x - 0.5, i.y - 0.5, 1, 1),
  478. e = x + 1;
  479. e < u.length;
  480. e++
  481. )
  482. (n = u[e]),
  483. null !== n.x &&
  484. null !== n.y &&
  485. ((o = i.x - n.x),
  486. (m = i.y - n.y),
  487. (l = o * o + m * m),
  488. l < n.max &&
  489. (n === y &&
  490. l >= n.max / 2 &&
  491. ((i.x -= 0.03 * o), (i.y -= 0.03 * m)),
  492. (t = (n.max - l) / n.max),
  493. r.beginPath(),
  494. (r.lineWidth = t / 2),
  495. (r.strokeStyle = "rgba(" + d.c + "," + (t + 0.2) + ")"),
  496. r.moveTo(i.x, i.y),
  497. r.lineTo(n.x, n.y),
  498. r.stroke()));
  499. }),
  500. x(i);
  501. }
  502. var a,
  503. c,
  504. u,
  505. m = document.createElement("canvas"),
  506. d = t(),
  507. l = "c_n" + d.l,
  508. r = m.getContext("2d"),
  509. x =
  510. window.requestAnimationFrame ||
  511. window.webkitRequestAnimationFrame ||
  512. window.mozRequestAnimationFrame ||
  513. window.oRequestAnimationFrame ||
  514. window.msRequestAnimationFrame ||
  515. function (n) {
  516. window.setTimeout(n, 1e3 / 45);
  517. },
  518. w = Math.random,
  519. y = { x: null, y: null, max: 2e4 };
  520. (m.id = l),
  521. (m.style.cssText =
  522. "position:fixed;top:0;left:0;z-index:" + d.z + ";opacity:" + d.o),
  523. e("body")[0].appendChild(m),
  524. o(),
  525. (window.onresize = o),
  526. (window.onmousemove = function (n) {
  527. (n = n || window.event), (y.x = n.clientX), (y.y = n.clientY);
  528. }),
  529. (window.onmouseout = function () {
  530. (y.x = null), (y.y = null);
  531. });
  532. for (var s = [], f = 0; d.n > f; f++) {
  533. var h = w() * a,
  534. g = w() * c,
  535. v = 2 * w() - 1,
  536. p = 2 * w() - 1;
  537. s.push({ x: h, y: g, xa: v, ya: p, max: 6e3 });
  538. }
  539. (u = s.concat([y])),
  540. setTimeout(function () {
  541. i();
  542. }, 100);
  543. })();
  544. </script>
  545. <!-- 雪花特效 -->
  546. <script type="text/javascript">
  547. (function ($) {
  548. $.fn.snow = function (options) {
  549. var $flake = $('<div id="snowbox" />')
  550. .css({ position: "absolute", "z-index": "9999", top: "-50px" })
  551. .html("❄"),
  552. documentHeight = $(document).height(),
  553. documentWidth = $(document).width(),
  554. defaults = {
  555. minSize: 10,
  556. maxSize: 20,
  557. newOn: 1000,
  558. flakeColor:
  559. "#00CED1" /* 此处可以定义雪花颜色,若要白色可以改为#FFFFFF */,
  560. },
  561. options = $.extend({}, defaults, options);
  562. var interval = setInterval(function () {
  563. var startPositionLeft = Math.random() * documentWidth - 100,
  564. startOpacity = 0.5 + Math.random(),
  565. sizeFlake = options.minSize + Math.random() * options.maxSize,
  566. endPositionTop = documentHeight - 200,
  567. endPositionLeft = startPositionLeft - 500 + Math.random() * 500,
  568. durationFall = documentHeight * 10 + Math.random() * 5000;
  569. $flake
  570. .clone()
  571. .appendTo("body")
  572. .css({
  573. left: startPositionLeft,
  574. opacity: startOpacity,
  575. "font-size": sizeFlake,
  576. color: options.flakeColor,
  577. })
  578. .animate(
  579. {
  580. top: endPositionTop,
  581. left: endPositionLeft,
  582. opacity: 0.2,
  583. },
  584. durationFall,
  585. "linear",
  586. function () {
  587. $(this).remove();
  588. }
  589. );
  590. }, options.newOn);
  591. };
  592. })(jQuery);
  593. $(function () {
  594. $.fn.snow({
  595. minSize: 5 /* 定义雪花最小尺寸 */,
  596. maxSize: 80 /* 定义雪花最大尺寸 */,
  597. newOn: 200 /* 定义密集程度,数字越小越密集 */,
  598. });
  599. });
  600. </script>
  601. </body>
  602. </html>

index.js

 

  1. var S = {
  2. init: function () {
  3. var action = window.location.href,
  4. i = action.indexOf('?a=');
  5. S.Drawing.init('.canvas');
  6. document.body.classList.add('body--ready');
  7. if (i !== -1) {
  8. S.UI.simulate(decodeURI(action).substring(i + 3));
  9. } else {
  10. S.UI.simulate('|#countdown 3||2023|新年快乐||#rectangle|');
  11. // S.UI.simulate('|写|尽|千|山|落|笔|是|你|#rectangle|');
  12. }
  13. S.Drawing.loop(function () {
  14. S.Shape.render();
  15. });
  16. }
  17. };
  18. S.Drawing = (function () {
  19. var canvas,
  20. context,
  21. renderFn
  22. requestFrame = window.requestAnimationFrame ||
  23. window.webkitRequestAnimationFrame ||
  24. window.mozRequestAnimationFrame ||
  25. window.oRequestAnimationFrame ||
  26. window.msRequestAnimationFrame ||
  27. function(callback) {
  28. window.setTimeout(callback, 1000 / 60);
  29. };
  30. return {
  31. init: function (el) {
  32. canvas = document.querySelector(el);
  33. context = canvas.getContext('2d');
  34. this.adjustCanvas();
  35. window.addEventListener('resize', function (e) {
  36. S.Drawing.adjustCanvas();
  37. });
  38. },
  39. loop: function (fn) {
  40. renderFn = !renderFn ? fn : renderFn;
  41. this.clearFrame();
  42. renderFn();
  43. requestFrame.call(window, this.loop.bind(this));
  44. },
  45. adjustCanvas: function () {
  46. canvas.width = window.innerWidth;
  47. canvas.height = window.innerHeight;
  48. },
  49. clearFrame: function () {
  50. context.clearRect(0, 0, canvas.width, canvas.height);
  51. },
  52. getArea: function () {
  53. return { w: canvas.width, h: canvas.height };
  54. },
  55. drawCircle: function (p, c) {
  56. context.fillStyle = c.render();
  57. context.beginPath();
  58. context.arc(p.x, p.y, p.z, 0, 2 * Math.PI, true);
  59. context.closePath();
  60. context.fill();
  61. }
  62. }
  63. }());
  64. S.UI = (function () {
  65. var canvas = document.querySelector('.canvas'),
  66. interval,
  67. isTouch = false, //('ontouchstart' in window || navigator.msMaxTouchPoints),
  68. currentAction,
  69. resizeTimer,
  70. time,
  71. maxShapeSize = 30,
  72. firstAction = true,
  73. sequence = [],
  74. cmd = '#';
  75. function formatTime(date) {
  76. var h = date.getHours(),
  77. m = date.getMinutes(),
  78. m = m < 10 ? '0' + m : m;
  79. return h + ':' + m;
  80. }
  81. function getValue(value) {
  82. return value && value.split(' ')[1];
  83. }
  84. function getAction(value) {
  85. value = value && value.split(' ')[0];
  86. return value && value[0] === cmd && value.substring(1);
  87. }
  88. function timedAction(fn, delay, max, reverse) {
  89. clearInterval(interval);
  90. currentAction = reverse ? max : 1;
  91. fn(currentAction);
  92. if (!max || (!reverse && currentAction < max) || (reverse && currentAction > 0)) {
  93. interval = setInterval(function () {
  94. currentAction = reverse ? currentAction - 1 : currentAction + 1;
  95. fn(currentAction);
  96. if ((!reverse && max && currentAction === max) || (reverse && currentAction === 0)) {
  97. clearInterval(interval);
  98. }
  99. }, delay);
  100. }
  101. }
  102. function reset(destroy) {
  103. clearInterval(interval);
  104. sequence = [];
  105. time = null;
  106. destroy && S.Shape.switchShape(S.ShapeBuilder.letter(''));
  107. }
  108. function performAction(value) {
  109. var action,
  110. value,
  111. current;
  112. // overlay.classList.remove('overlay--visible');
  113. sequence = typeof(value) === 'object' ? value : sequence.concat(value.split('|'));
  114. // input.value = '';
  115. // checkInputWidth();
  116. timedAction(function (index) {
  117. current = sequence.shift();
  118. action = getAction(current);
  119. value = getValue(current);
  120. switch (action) {
  121. case 'countdown':
  122. value = parseInt(value) || 10;
  123. value = value > 0 ? value : 10;
  124. timedAction(function (index) {
  125. if (index === 0) {
  126. if (sequence.length === 0) {
  127. S.Shape.switchShape(S.ShapeBuilder.letter(''));
  128. } else {
  129. performAction(sequence);
  130. }
  131. } else {
  132. S.Shape.switchShape(S.ShapeBuilder.letter(index), true);
  133. }
  134. }, 1000, value, true);
  135. break;
  136. case 'rectangle':
  137. value = value && value.split('x');
  138. value = (value && value.length === 2) ? value : [maxShapeSize, maxShapeSize / 2];
  139. S.Shape.switchShape(S.ShapeBuilder.rectangle(Math.min(maxShapeSize, parseInt(value[0])), Math.min(maxShapeSize, parseInt(value[1]))));
  140. break;
  141. case 'circle':
  142. value = parseInt(value) || maxShapeSize;
  143. value = Math.min(value, maxShapeSize);
  144. S.Shape.switchShape(S.ShapeBuilder.circle(value));
  145. break;
  146. case 'time':
  147. var t = formatTime(new Date());
  148. if (sequence.length > 0) {
  149. S.Shape.switchShape(S.ShapeBuilder.letter(t));
  150. } else {
  151. timedAction(function () {
  152. t = formatTime(new Date());
  153. if (t !== time) {
  154. time = t;
  155. S.Shape.switchShape(S.ShapeBuilder.letter(time));
  156. }
  157. }, 1000);
  158. }
  159. break;
  160. default:
  161. S.Shape.switchShape(S.ShapeBuilder.letter(current[0] === cmd ? 'What?' : current));
  162. }
  163. }, 2000, sequence.length);
  164. }
  165. function checkInputWidth(e) {
  166. if (input.value.length > 18) {
  167. ui.classList.add('ui--wide');
  168. } else {
  169. ui.classList.remove('ui--wide');
  170. }
  171. if (firstAction && input.value.length > 0) {
  172. ui.classList.add('ui--enter');
  173. } else {
  174. ui.classList.remove('ui--enter');
  175. }
  176. }
  177. function bindEvents() {
  178. document.body.addEventListener('keydown', function (e) {
  179. input.focus();
  180. if (e.keyCode === 13) {
  181. firstAction = false;
  182. reset();
  183. performAction(input.value);
  184. }
  185. });
  186. // input.addEventListener('input', checkInputWidth);
  187. // input.addEventListener('change', checkInputWidth);
  188. // input.addEventListener('focus', checkInputWidth);
  189. // help.addEventListener('click', function (e) {
  190. // overlay.classList.toggle('overlay--visible');
  191. // overlay.classList.contains('overlay--visible') && reset(true);
  192. // });
  193. // commands.addEventListener('click', function (e) {
  194. // var el,
  195. // info,
  196. // demo,
  197. // tab,
  198. // active,
  199. // url;
  200. //
  201. // if (e.target.classList.contains('commands-item')) {
  202. // el = e.target;
  203. // } else {
  204. // el = e.target.parentNode.classList.contains('commands-item') ? e.target.parentNode : e.target.parentNode.parentNode;
  205. // }
  206. //
  207. // info = el && el.querySelector('.commands-item-info');
  208. // demo = el && info.getAttribute('data-demo');
  209. // url = el && info.getAttribute('data-url');
  210. //
  211. // if (info) {
  212. // overlay.classList.remove('overlay--visible');
  213. //
  214. // if (demo) {
  215. // input.value = demo;
  216. //
  217. // if (isTouch) {
  218. // reset();
  219. // performAction(input.value);
  220. // } else {
  221. // input.focus();
  222. // }
  223. // } else if (url) {
  224. // //window.location = url;
  225. // }
  226. // }
  227. // });
  228. canvas.addEventListener('click', function (e) {
  229. overlay.classList.remove('overlay--visible');
  230. });
  231. }
  232. function init() {
  233. bindEvents();
  234. // input.focus();
  235. isTouch && document.body.classList.add('touch');
  236. }
  237. // Init
  238. init();
  239. return {
  240. simulate: function (action) {
  241. performAction(action);
  242. }
  243. }
  244. }());
  245. S.UI.Tabs = (function () {
  246. var tabs = document.querySelector('.tabs'),
  247. labels = document.querySelector('.tabs-labels'),
  248. triggers = document.querySelectorAll('.tabs-label'),
  249. panels = document.querySelectorAll('.tabs-panel');
  250. function activate(i) {
  251. triggers[i].classList.add('tabs-label--active');
  252. panels[i].classList.add('tabs-panel--active');
  253. }
  254. function bindEvents() {
  255. labels.addEventListener('click', function (e) {
  256. var el = e.target,
  257. index;
  258. if (el.classList.contains('tabs-label')) {
  259. for (var t = 0; t < triggers.length; t++) {
  260. triggers[t].classList.remove('tabs-label--active');
  261. panels[t].classList.remove('tabs-panel--active');
  262. if (el === triggers[t]) {
  263. index = t;
  264. }
  265. }
  266. activate(index);
  267. }
  268. });
  269. }
  270. function init() {
  271. activate(0);
  272. bindEvents();
  273. }
  274. // Init
  275. init();
  276. }());
  277. S.Point = function (args) {
  278. this.x = args.x;
  279. this.y = args.y;
  280. this.z = args.z;
  281. this.a = args.a;
  282. this.h = args.h;
  283. };
  284. S.Color = function (r, g, b, a) {
  285. this.r = r;
  286. this.g = g;
  287. this.b = b;
  288. this.a = a;
  289. };
  290. S.Color.prototype = {
  291. render: function () {
  292. return 'rgba(' + this.r + ',' + + this.g + ',' + this.b + ',' + this.a + ')';
  293. }
  294. };
  295. S.Dot = function (x, y) {
  296. this.p = new S.Point({
  297. x: x,
  298. y: y,
  299. z: 5,
  300. a: 1,
  301. h: 0
  302. });
  303. this.e = 0.07;
  304. this.s = true;
  305. this.c = new S.Color(255, 255, 255, this.p.a);
  306. this.t = this.clone();
  307. this.q = [];
  308. };
  309. S.Dot.prototype = {
  310. clone: function () {
  311. return new S.Point({
  312. x: this.x,
  313. y: this.y,
  314. z: this.z,
  315. a: this.a,
  316. h: this.h
  317. });
  318. },
  319. _draw: function () {
  320. this.c.a = this.p.a;
  321. S.Drawing.drawCircle(this.p, this.c);
  322. },
  323. _moveTowards: function (n) {
  324. var details = this.distanceTo(n, true),
  325. dx = details[0],
  326. dy = details[1],
  327. d = details[2],
  328. e = this.e * d;
  329. if (this.p.h === -1) {
  330. this.p.x = n.x;
  331. this.p.y = n.y;
  332. return true;
  333. }
  334. if (d > 1) {
  335. this.p.x -= ((dx / d) * e);
  336. this.p.y -= ((dy / d) * e);
  337. } else {
  338. if (this.p.h > 0) {
  339. this.p.h--;
  340. } else {
  341. return true;
  342. }
  343. }
  344. return false;
  345. },
  346. _update: function () {
  347. if (this._moveTowards(this.t)) {
  348. var p = this.q.shift();
  349. if (p) {
  350. this.t.x = p.x || this.p.x;
  351. this.t.y = p.y || this.p.y;
  352. this.t.z = p.z || this.p.z;
  353. this.t.a = p.a || this.p.a;
  354. this.p.h = p.h || 0;
  355. } else {
  356. if (this.s) {
  357. this.p.x -= Math.sin(Math.random() * 3.142);
  358. this.p.y -= Math.sin(Math.random() * 3.142);
  359. } else {
  360. this.move(new S.Point({
  361. x: this.p.x + (Math.random() * 50) - 25,
  362. y: this.p.y + (Math.random() * 50) - 25,
  363. }));
  364. }
  365. }
  366. }
  367. d = this.p.a - this.t.a;
  368. this.p.a = Math.max(0.1, this.p.a - (d * 0.05));
  369. d = this.p.z - this.t.z;
  370. this.p.z = Math.max(1, this.p.z - (d * 0.05));
  371. },
  372. distanceTo: function (n, details) {
  373. var dx = this.p.x - n.x,
  374. dy = this.p.y - n.y,
  375. d = Math.sqrt(dx * dx + dy * dy);
  376. return details ? [dx, dy, d] : d;
  377. },
  378. move: function (p, avoidStatic) {
  379. if (!avoidStatic || (avoidStatic && this.distanceTo(p) > 1)) {
  380. this.q.push(p);
  381. }
  382. },
  383. render: function () {
  384. this._update();
  385. this._draw();
  386. }
  387. }
  388. S.ShapeBuilder = (function () {
  389. var gap = 13,
  390. shapeCanvas = document.createElement('canvas'),
  391. shapeContext = shapeCanvas.getContext('2d'),
  392. fontSize = 500,
  393. fontFamily = 'Avenir, Helvetica Neue, Helvetica, Arial, sans-serif';
  394. function fit() {
  395. shapeCanvas.width = Math.floor(window.innerWidth / gap) * gap;
  396. shapeCanvas.height = Math.floor(window.innerHeight / gap) * gap;
  397. shapeContext.fillStyle = 'red';
  398. shapeContext.textBaseline = 'middle';
  399. shapeContext.textAlign = 'center';
  400. }
  401. function processCanvas() {
  402. var pixels = shapeContext.getImageData(0, 0, shapeCanvas.width, shapeCanvas.height).data;
  403. dots = [],
  404. pixels,
  405. x = 0,
  406. y = 0,
  407. fx = shapeCanvas.width,
  408. fy = shapeCanvas.height,
  409. w = 0,
  410. h = 0;
  411. for (var p = 0; p < pixels.length; p += (4 * gap)) {
  412. if (pixels[p + 3] > 0) {
  413. dots.push(new S.Point({
  414. x: x,
  415. y: y
  416. }));
  417. w = x > w ? x : w;
  418. h = y > h ? y : h;
  419. fx = x < fx ? x : fx;
  420. fy = y < fy ? y : fy;
  421. }
  422. x += gap;
  423. if (x >= shapeCanvas.width) {
  424. x = 0;
  425. y += gap;
  426. p += gap * 4 * shapeCanvas.width;
  427. }
  428. }
  429. return { dots: dots, w: w + fx, h: h + fy };
  430. }
  431. function setFontSize(s) {
  432. shapeContext.font = 'bold ' + s + 'px ' + fontFamily;
  433. }
  434. function isNumber(n) {
  435. return !isNaN(parseFloat(n)) && isFinite(n);
  436. }
  437. function init() {
  438. fit();
  439. window.addEventListener('resize', fit);
  440. }
  441. // Init
  442. init();
  443. return {
  444. imageFile: function (url, callback) {
  445. var image = new Image(),
  446. a = S.Drawing.getArea();
  447. image.onload = function () {
  448. shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
  449. shapeContext.drawImage(this, 0, 0, a.h * 0.6, a.h * 0.6);
  450. callback(processCanvas());
  451. };
  452. image.onerror = function () {
  453. callback(S.ShapeBuilder.letter('What?'));
  454. }
  455. image.src = url;
  456. },
  457. circle: function (d) {
  458. var r = Math.max(0, d) / 2;
  459. shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
  460. shapeContext.beginPath();
  461. shapeContext.arc(r * gap, r * gap, r * gap, 0, 2 * Math.PI, false);
  462. shapeContext.fill();
  463. shapeContext.closePath();
  464. return processCanvas();
  465. },
  466. letter: function (l) {
  467. var s = 0;
  468. setFontSize(fontSize);
  469. s = Math.min(fontSize,
  470. (shapeCanvas.width / shapeContext.measureText(l).width) * 0.8 * fontSize,
  471. (shapeCanvas.height / fontSize) * (isNumber(l) ? 1 : 0.45) * fontSize);
  472. setFontSize(s);
  473. shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
  474. shapeContext.fillText(l, shapeCanvas.width / 2, shapeCanvas.height / 2);
  475. return processCanvas();
  476. },
  477. rectangle: function (w, h) {
  478. var dots = [],
  479. width = gap * w,
  480. height = gap * h;
  481. for (var y = 0; y < height; y += gap) {
  482. for (var x = 0; x < width; x += gap) {
  483. dots.push(new S.Point({
  484. x: x,
  485. y: y,
  486. }));
  487. }
  488. }
  489. return { dots: dots, w: width, h: height };
  490. }
  491. };
  492. }());
  493. S.Shape = (function () {
  494. var dots = [],
  495. width = 0,
  496. height = 0,
  497. cx = 0,
  498. cy = 0;
  499. function compensate() {
  500. var a = S.Drawing.getArea();
  501. cx = a.w / 2 - width / 2;
  502. cy = a.h / 2 - height / 2;
  503. }
  504. return {
  505. shuffleIdle: function () {
  506. var a = S.Drawing.getArea();
  507. for (var d = 0; d < dots.length; d++) {
  508. if (!dots[d].s) {
  509. dots[d].move({
  510. x: Math.random() * a.w,
  511. y: Math.random() * a.h
  512. });
  513. }
  514. }
  515. },
  516. switchShape: function (n, fast) {
  517. var size,
  518. a = S.Drawing.getArea();
  519. width = n.w;
  520. height = n.h;
  521. compensate();
  522. if (n.dots.length > dots.length) {
  523. size = n.dots.length - dots.length;
  524. for (var d = 1; d <= size; d++) {
  525. dots.push(new S.Dot(a.w / 2, a.h / 2));
  526. }
  527. }
  528. var d = 0,
  529. i = 0;
  530. while (n.dots.length > 0) {
  531. i = Math.floor(Math.random() * n.dots.length);
  532. dots[d].e = fast ? 0.25 : (dots[d].s ? 0.14 : 0.11);
  533. if (dots[d].s) {
  534. dots[d].move(new S.Point({
  535. z: Math.random() * 20 + 10,
  536. a: Math.random(),
  537. h: 18
  538. }));
  539. } else {
  540. dots[d].move(new S.Point({
  541. z: Math.random() * 5 + 5,
  542. h: fast ? 18 : 30
  543. }));
  544. }
  545. dots[d].s = true;
  546. dots[d].move(new S.Point({
  547. x: n.dots[i].x + cx,
  548. y: n.dots[i].y + cy,
  549. a: 1,
  550. z: 5,
  551. h: 0
  552. }));
  553. n.dots = n.dots.slice(0, i).concat(n.dots.slice(i + 1));
  554. d++;
  555. }
  556. for (var i = d; i < dots.length; i++) {
  557. if (dots[i].s) {
  558. dots[i].move(new S.Point({
  559. z: Math.random() * 20 + 10,
  560. a: Math.random(),
  561. h: 20
  562. }));
  563. dots[i].s = false;
  564. dots[i].e = 0.04;
  565. dots[i].move(new S.Point({
  566. x: Math.random() * a.w,
  567. y: Math.random() * a.h,
  568. a: 0.3, //.4
  569. z: Math.random() * 4,
  570. h: 0
  571. }));
  572. }
  573. }
  574. },
  575. render: function () {
  576. for (var d = 0; d < dots.length; d++) {
  577. dots[d].render();
  578. }
  579. }
  580. }
  581. }());
  582. S.init();

关注文章底部微信公众号主页回复“2023新年烟花1”即可获取

 

第二款

(没有雪花设计有音乐)

源码分享

index.html

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>计算机基础与编程</title>
  6. <style>
  7. html,body{
  8. margin:0px;
  9. width:100%;
  10. height:100%;
  11. overflow:hidden;
  12. background:#000;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <audio id="a1" loop="loop">
  18. <source src="https://music.163.com/song/media/outer/url?id=1877996649.mp3">
  19. </audio>
  20. <canvas id="canvas" style="position:absolute;width:100%;height:100%;z-index:8888"></canvas>
  21. <canvas style="position:absolute;width:100%;height:100%;z-index:9999" class="canvas" ></canvas>
  22. <div class="overlay">
  23. <div class="tabs">
  24. <div class="tabs-labels"><span class="tabs-label">Commands</span><span class="tabs-label">Info</span><span class="tabs-label">Share</span></div>
  25. <div class="tabs-panels">
  26. <ul class="tabs-panel commands">
  27. </ul>
  28. </div>
  29. </div>
  30. </div>
  31. <script>
  32. window.onload=function () {
  33. let oA=document.querySelector("#a1");
  34. let timer=null;
  35. function autoPlay() {
  36. if (oA.paused) {
  37. oA.paused=false;
  38. oA.volume=0.5;
  39. oA.play();
  40. }else {
  41. clearInterval(timer);
  42. }
  43. }
  44. timer=setInterval(autoPlay,1);
  45. }
  46. function initVars(){
  47. pi=Math.PI;
  48. ctx=canvas.getContext("2d");
  49. canvas.width=canvas.clientWidth;
  50. canvas.height=canvas.clientHeight;
  51. cx=canvas.width/2;
  52. cy=canvas.height/2;
  53. playerZ=-25;
  54. playerX=playerY=playerVX=playerVY=playerVZ=pitch=yaw=pitchV=yawV=0;
  55. scale=600;
  56. seedTimer=0;seedInterval=5,seedLife=100;gravity=.02;
  57. seeds=new Array();
  58. sparkPics=new Array();
  59. s="https://cantelope.org/NYE/";
  60. for(i=1;i<=10;++i){
  61. sparkPic=new Image();
  62. sparkPic.src=s+"spark"+i+".png";
  63. sparkPics.push(sparkPic);
  64. }
  65. sparks=new Array();
  66. pow1=new Audio(s+"pow1.ogg");
  67. pow2=new Audio(s+"pow2.ogg");
  68. pow3=new Audio(s+"pow3.ogg");
  69. pow4=new Audio(s+"pow4.ogg");
  70. frames = 0;
  71. }
  72. function rasterizePoint(x,y,z){
  73. var p,d;
  74. x-=playerX;
  75. y-=playerY;
  76. z-=playerZ;
  77. p=Math.atan2(x,z);
  78. d=Math.sqrt(x*x+z*z);
  79. x=Math.sin(p-yaw)*d;
  80. z=Math.cos(p-yaw)*d;
  81. p=Math.atan2(y,z);
  82. d=Math.sqrt(y*y+z*z);
  83. y=Math.sin(p-pitch)*d;
  84. z=Math.cos(p-pitch)*d;
  85. var rx1=-1000,ry1=1,rx2=1000,ry2=1,rx3=0,ry3=0,rx4=x,ry4=z,uc=(ry4-ry3)*(rx2-rx1)-(rx4-rx3)*(ry2-ry1);
  86. if(!uc) return {x:0,y:0,d:-1};
  87. var ua=((rx4-rx3)*(ry1-ry3)-(ry4-ry3)*(rx1-rx3))/uc;
  88. var ub=((rx2-rx1)*(ry1-ry3)-(ry2-ry1)*(rx1-rx3))/uc;
  89. if(!z)z=.000000001;
  90. if(ua>0&&ua<1&&ub>0&&ub<1){
  91. return {
  92. x:cx+(rx1+ua*(rx2-rx1))*scale,
  93. y:cy+y/z*scale,
  94. d:Math.sqrt(x*x+y*y+z*z)
  95. };
  96. }else{
  97. return {
  98. x:cx+(rx1+ua*(rx2-rx1))*scale,
  99. y:cy+y/z*scale,
  100. d:-1
  101. };
  102. }
  103. }
  104. function spawnSeed(){
  105. seed=new Object();
  106. seed.x=-50+Math.random()*100;
  107. seed.y=25;
  108. seed.z=-50+Math.random()*100;
  109. seed.vx=.1-Math.random()*.2;
  110. seed.vy=-1.5;//*(1+Math.random()/2);
  111. seed.vz=.1-Math.random()*.2;
  112. seed.born=frames;
  113. seeds.push(seed);
  114. }
  115. function splode(x,y,z){
  116. t=5+parseInt(Math.random()*150);
  117. sparkV=1+Math.random()*2.5;
  118. type=parseInt(Math.random()*3);
  119. switch(type){
  120. case 0:
  121. pic1=parseInt(Math.random()*10);
  122. break;
  123. case 1:
  124. pic1=parseInt(Math.random()*10);
  125. do{ pic2=parseInt(Math.random()*10); }while(pic2==pic1);
  126. break;
  127. case 2:
  128. pic1=parseInt(Math.random()*10);
  129. do{ pic2=parseInt(Math.random()*10); }while(pic2==pic1);
  130. do{ pic3=parseInt(Math.random()*10); }while(pic3==pic1 || pic3==pic2);
  131. break;
  132. }
  133. for(m=1;m<t;++m){
  134. spark=new Object();
  135. spark.x=x; spark.y=y; spark.z=z;
  136. p1=pi*2*Math.random();
  137. p2=pi*Math.random();
  138. v=sparkV*(1+Math.random()/6)
  139. spark.vx=Math.sin(p1)*Math.sin(p2)*v;
  140. spark.vz=Math.cos(p1)*Math.sin(p2)*v;
  141. spark.vy=Math.cos(p2)*v;
  142. switch(type){
  143. case 0: spark.img=sparkPics[pic1]; break;
  144. case 1:
  145. spark.img=sparkPics[parseInt(Math.random()*2)?pic1:pic2];
  146. break;
  147. case 2:
  148. switch(parseInt(Math.random()*3)){
  149. case 0: spark.img=sparkPics[pic1]; break;
  150. case 1: spark.img=sparkPics[pic2]; break;
  151. case 2: spark.img=sparkPics[pic3]; break;
  152. }
  153. break;
  154. }
  155. spark.radius=25+Math.random()*50;
  156. spark.alpha=1;
  157. spark.trail=new Array();
  158. sparks.push(spark);
  159. }
  160. switch(parseInt(Math.random()*4)){
  161. case 0: pow=new Audio(s+"pow1.ogg"); break;
  162. case 1: pow=new Audio(s+"pow2.ogg"); break;
  163. case 2: pow=new Audio(s+"pow3.ogg"); break;
  164. case 3: pow=new Audio(s+"pow4.ogg"); break;
  165. }
  166. d=Math.sqrt((x-playerX)*(x-playerX)+(y-playerY)*(y-playerY)+(z-playerZ)*(z-playerZ));
  167. pow.volume=1.5/(1+d/10);
  168. pow.play();
  169. }
  170. function doLogic(){
  171. if(seedTimer<frames){
  172. seedTimer=frames+seedInterval*Math.random()*10;
  173. spawnSeed();
  174. }
  175. for(i=0;i<seeds.length;++i){
  176. seeds[i].vy+=gravity;
  177. seeds[i].x+=seeds[i].vx;
  178. seeds[i].y+=seeds[i].vy;
  179. seeds[i].z+=seeds[i].vz;
  180. if(frames-seeds[i].born>seedLife){
  181. splode(seeds[i].x,seeds[i].y,seeds[i].z);
  182. seeds.splice(i,1);
  183. }
  184. }
  185. for(i=0;i<sparks.length;++i){
  186. if(sparks[i].alpha>0 && sparks[i].radius>5){
  187. sparks[i].alpha-=.01;
  188. sparks[i].radius/=1.02;
  189. sparks[i].vy+=gravity;
  190. point=new Object();
  191. point.x=sparks[i].x;
  192. point.y=sparks[i].y;
  193. point.z=sparks[i].z;
  194. if(sparks[i].trail.length){
  195. x=sparks[i].trail[sparks[i].trail.length-1].x;
  196. y=sparks[i].trail[sparks[i].trail.length-1].y;
  197. z=sparks[i].trail[sparks[i].trail.length-1].z;
  198. d=((point.x-x)*(point.x-x)+(point.y-y)*(point.y-y)+(point.z-z)*(point.z-z));
  199. if(d>9){
  200. sparks[i].trail.push(point);
  201. }
  202. }else{
  203. sparks[i].trail.push(point);
  204. }
  205. if(sparks[i].trail.length>5)sparks[i].trail.splice(0,1);
  206. sparks[i].x+=sparks[i].vx;
  207. sparks[i].y+=sparks[i].vy;
  208. sparks[i].z+=sparks[i].vz;
  209. sparks[i].vx/=1.075;
  210. sparks[i].vy/=1.075;
  211. sparks[i].vz/=1.075;
  212. }else{
  213. sparks.splice(i,1);
  214. }
  215. }
  216. p=Math.atan2(playerX,playerZ);
  217. d=Math.sqrt(playerX*playerX+playerZ*playerZ);
  218. d+=Math.sin(frames/80)/1.25;
  219. t=Math.sin(frames/200)/40;
  220. playerX=Math.sin(p+t)*d;
  221. playerZ=Math.cos(p+t)*d;
  222. yaw=pi+p+t;
  223. }
  224. function rgb(col){
  225. var r = parseInt((.5+Math.sin(col)*.5)*16);
  226. var g = parseInt((.5+Math.cos(col)*.5)*16);
  227. var b = parseInt((.5-Math.sin(col)*.5)*16);
  228. return "#"+r.toString(16)+g.toString(16)+b.toString(16);
  229. }
  230. function draw(){
  231. ctx.clearRect(0,0,cx*2,cy*2);
  232. ctx.fillStyle="#ff8";
  233. for(i=-100;i<100;i+=3){
  234. for(j=-100;j<100;j+=4){
  235. x=i;z=j;y=25;
  236. point=rasterizePoint(x,y,z);
  237. if(point.d!=-1){
  238. size=250/(1+point.d);
  239. d = Math.sqrt(x * x + z * z);
  240. a = 0.75 - Math.pow(d / 100, 6) * 0.75;
  241. if(a>0){
  242. ctx.globalAlpha = a;
  243. ctx.fillRect(point.x-size/2,point.y-size/2,size,size);
  244. }
  245. }
  246. }
  247. }
  248. ctx.globalAlpha=1;
  249. for(i=0;i<seeds.length;++i){
  250. point=rasterizePoint(seeds[i].x,seeds[i].y,seeds[i].z);
  251. if(point.d!=-1){
  252. size=200/(1+point.d);
  253. ctx.fillRect(point.x-size/2,point.y-size/2,size,size);
  254. }
  255. }
  256. point1=new Object();
  257. for(i=0;i<sparks.length;++i){
  258. point=rasterizePoint(sparks[i].x,sparks[i].y,sparks[i].z);
  259. if(point.d!=-1){
  260. size=sparks[i].radius*200/(1+point.d);
  261. if(sparks[i].alpha<0)sparks[i].alpha=0;
  262. if(sparks[i].trail.length){
  263. point1.x=point.x;
  264. point1.y=point.y;
  265. switch(sparks[i].img){
  266. case sparkPics[0]:ctx.strokeStyle="#f84";break;
  267. case sparkPics[1]:ctx.strokeStyle="#84f";break;
  268. case sparkPics[2]:ctx.strokeStyle="#8ff";break;
  269. case sparkPics[3]:ctx.strokeStyle="#fff";break;
  270. case sparkPics[4]:ctx.strokeStyle="#4f8";break;
  271. case sparkPics[5]:ctx.strokeStyle="#f44";break;
  272. case sparkPics[6]:ctx.strokeStyle="#f84";break;
  273. case sparkPics[7]:ctx.strokeStyle="#84f";break;
  274. case sparkPics[8]:ctx.strokeStyle="#fff";break;
  275. case sparkPics[9]:ctx.strokeStyle="#44f";break;
  276. }
  277. for(j=sparks[i].trail.length-1;j>=0;--j){
  278. point2=rasterizePoint(sparks[i].trail[j].x,sparks[i].trail[j].y,sparks[i].trail[j].z);
  279. if(point2.d!=-1){
  280. ctx.globalAlpha=j/sparks[i].trail.length*sparks[i].alpha/2;
  281. ctx.beginPath();
  282. ctx.moveTo(point1.x,point1.y);
  283. ctx.lineWidth=1+sparks[i].radius*10/(sparks[i].trail.length-j)/(1+point2.d);
  284. ctx.lineTo(point2.x,point2.y);
  285. ctx.stroke();
  286. point1.x=point2.x;
  287. point1.y=point2.y;
  288. }
  289. }
  290. }
  291. ctx.globalAlpha=sparks[i].alpha;
  292. ctx.drawImage(sparks[i].img,point.x-size/2,point.y-size/2,size,size);
  293. }
  294. }
  295. }
  296. function frame(){
  297. if(frames>100000){
  298. seedTimer=0;
  299. frames=0;
  300. }
  301. frames++;
  302. draw();
  303. doLogic();
  304. requestAnimationFrame(frame);
  305. }
  306. window.addEventListener("resize",()=>{
  307. canvas.width=canvas.clientWidth;
  308. canvas.height=canvas.clientHeight;
  309. cx=canvas.width/2;
  310. cy=canvas.height/2;
  311. });
  312. initVars();
  313. frame();
  314. </script>
  315. <script src="js/index.js"></script>
  316. </body>
  317. </html>

index.js

  1. /*
  2. Shape Shifter
  3. =============
  4. A canvas experiment by Kenneth Cachia
  5. http://www.kennethcachia.com
  6. Updated code
  7. ------------
  8. https://github.com/kennethcachia/Shape-Shifter
  9. */
  10. var S = {
  11. init: function () {
  12. var action = window.location.href,
  13. i = action.indexOf('?a=');
  14. S.Drawing.init('.canvas');
  15. document.body.classList.add('body--ready');
  16. if (i !== -1) {
  17. S.UI.simulate(decodeURI(action).substring(i + 3));
  18. } else {
  19. // 倒计时修改这句中的数字,不需要倒计时删除“|#countdown 3|”,换内容修改文字
  20. S.UI.simulate('|#countdown 3||2023|新|年|快|乐|#rectangle|');
  21. }
  22. S.Drawing.loop(function () {
  23. S.Shape.render();
  24. });
  25. }
  26. };
  27. S.Drawing = (function () {
  28. var canvas,
  29. context,
  30. renderFn
  31. requestFrame = window.requestAnimationFrame ||
  32. window.webkitRequestAnimationFrame ||
  33. window.mozRequestAnimationFrame ||
  34. window.oRequestAnimationFrame ||
  35. window.msRequestAnimationFrame ||
  36. function(callback) {
  37. window.setTimeout(callback, 1000 / 60);
  38. };
  39. return {
  40. init: function (el) {
  41. canvas = document.querySelector(el);
  42. context = canvas.getContext('2d');
  43. this.adjustCanvas();
  44. window.addEventListener('resize', function (e) {
  45. S.Drawing.adjustCanvas();
  46. });
  47. },
  48. loop: function (fn) {
  49. renderFn = !renderFn ? fn : renderFn;
  50. this.clearFrame();
  51. renderFn();
  52. requestFrame.call(window, this.loop.bind(this));
  53. },
  54. adjustCanvas: function () {
  55. canvas.width = window.innerWidth;
  56. canvas.height = window.innerHeight;
  57. },
  58. clearFrame: function () {
  59. context.clearRect(0, 0, canvas.width, canvas.height);
  60. },
  61. getArea: function () {
  62. return { w: canvas.width, h: canvas.height };
  63. },
  64. drawCircle: function (p, c) {
  65. context.fillStyle = c.render();
  66. context.beginPath();
  67. context.arc(p.x, p.y, p.z, 0, 2 * Math.PI, true);
  68. context.closePath();
  69. context.fill();
  70. }
  71. }
  72. }());
  73. S.UI = (function () {
  74. var canvas = document.querySelector('.canvas'),
  75. interval,
  76. isTouch = false, //('ontouchstart' in window || navigator.msMaxTouchPoints),
  77. currentAction,
  78. resizeTimer,
  79. time,
  80. maxShapeSize = 30,
  81. firstAction = true,
  82. sequence = [],
  83. cmd = '#';
  84. function formatTime(date) {
  85. var h = date.getHours(),
  86. m = date.getMinutes(),
  87. m = m < 10 ? '0' + m : m;
  88. return h + ':' + m;
  89. }
  90. function getValue(value) {
  91. return value && value.split(' ')[1];
  92. }
  93. function getAction(value) {
  94. value = value && value.split(' ')[0];
  95. return value && value[0] === cmd && value.substring(1);
  96. }
  97. function timedAction(fn, delay, max, reverse) {
  98. clearInterval(interval);
  99. currentAction = reverse ? max : 1;
  100. fn(currentAction);
  101. if (!max || (!reverse && currentAction < max) || (reverse && currentAction > 0)) {
  102. interval = setInterval(function () {
  103. currentAction = reverse ? currentAction - 1 : currentAction + 1;
  104. fn(currentAction);
  105. if ((!reverse && max && currentAction === max) || (reverse && currentAction === 0)) {
  106. clearInterval(interval);
  107. }
  108. }, delay);
  109. }
  110. }
  111. function reset(destroy) {
  112. clearInterval(interval);
  113. sequence = [];
  114. time = null;
  115. destroy && S.Shape.switchShape(S.ShapeBuilder.letter(''));
  116. }
  117. function performAction(value) {
  118. var action,
  119. value,
  120. current;
  121. // overlay.classList.remove('overlay--visible');
  122. sequence = typeof(value) === 'object' ? value : sequence.concat(value.split('|'));
  123. // input.value = '';
  124. // checkInputWidth();
  125. timedAction(function (index) {
  126. current = sequence.shift();
  127. action = getAction(current);
  128. value = getValue(current);
  129. switch (action) {
  130. case 'countdown':
  131. value = parseInt(value) || 10;
  132. value = value > 0 ? value : 10;
  133. timedAction(function (index) {
  134. if (index === 0) {
  135. if (sequence.length === 0) {
  136. S.Shape.switchShape(S.ShapeBuilder.letter(''));
  137. } else {
  138. performAction(sequence);
  139. }
  140. } else {
  141. S.Shape.switchShape(S.ShapeBuilder.letter(index), true);
  142. }
  143. }, 1000, value, true);
  144. break;
  145. case 'rectangle':
  146. value = value && value.split('x');
  147. value = (value && value.length === 2) ? value : [maxShapeSize, maxShapeSize / 2];
  148. S.Shape.switchShape(S.ShapeBuilder.rectangle(Math.min(maxShapeSize, parseInt(value[0])), Math.min(maxShapeSize, parseInt(value[1]))));
  149. break;
  150. case 'circle':
  151. value = parseInt(value) || maxShapeSize;
  152. value = Math.min(value, maxShapeSize);
  153. S.Shape.switchShape(S.ShapeBuilder.circle(value));
  154. break;
  155. case 'time':
  156. var t = formatTime(new Date());
  157. if (sequence.length > 0) {
  158. S.Shape.switchShape(S.ShapeBuilder.letter(t));
  159. } else {
  160. timedAction(function () {
  161. t = formatTime(new Date());
  162. if (t !== time) {
  163. time = t;
  164. S.Shape.switchShape(S.ShapeBuilder.letter(time));
  165. }
  166. }, 1000);
  167. }
  168. break;
  169. default:
  170. S.Shape.switchShape(S.ShapeBuilder.letter(current[0] === cmd ? 'What?' : current));
  171. }
  172. }, 2000, sequence.length);
  173. }
  174. function checkInputWidth(e) {
  175. if (input.value.length > 18) {
  176. ui.classList.add('ui--wide');
  177. } else {
  178. ui.classList.remove('ui--wide');
  179. }
  180. if (firstAction && input.value.length > 0) {
  181. ui.classList.add('ui--enter');
  182. } else {
  183. ui.classList.remove('ui--enter');
  184. }
  185. }
  186. function bindEvents() {
  187. document.body.addEventListener('keydown', function (e) {
  188. input.focus();
  189. if (e.keyCode === 13) {
  190. firstAction = false;
  191. reset();
  192. performAction(input.value);
  193. }
  194. });
  195. // input.addEventListener('input', checkInputWidth);
  196. // input.addEventListener('change', checkInputWidth);
  197. // input.addEventListener('focus', checkInputWidth);
  198. // help.addEventListener('click', function (e) {
  199. // overlay.classList.toggle('overlay--visible');
  200. // overlay.classList.contains('overlay--visible') && reset(true);
  201. // });
  202. // commands.addEventListener('click', function (e) {
  203. // var el,
  204. // info,
  205. // demo,
  206. // tab,
  207. // active,
  208. // url;
  209. //
  210. // if (e.target.classList.contains('commands-item')) {
  211. // el = e.target;
  212. // } else {
  213. // el = e.target.parentNode.classList.contains('commands-item') ? e.target.parentNode : e.target.parentNode.parentNode;
  214. // }
  215. //
  216. // info = el && el.querySelector('.commands-item-info');
  217. // demo = el && info.getAttribute('data-demo');
  218. // url = el && info.getAttribute('data-url');
  219. //
  220. // if (info) {
  221. // overlay.classList.remove('overlay--visible');
  222. //
  223. // if (demo) {
  224. // input.value = demo;
  225. //
  226. // if (isTouch) {
  227. // reset();
  228. // performAction(input.value);
  229. // } else {
  230. // input.focus();
  231. // }
  232. // } else if (url) {
  233. // //window.location = url;
  234. // }
  235. // }
  236. // });
  237. canvas.addEventListener('click', function (e) {
  238. overlay.classList.remove('overlay--visible');
  239. });
  240. }
  241. function init() {
  242. bindEvents();
  243. // input.focus();
  244. isTouch && document.body.classList.add('touch');
  245. }
  246. // Init
  247. init();
  248. return {
  249. simulate: function (action) {
  250. performAction(action);
  251. }
  252. }
  253. }());
  254. S.UI.Tabs = (function () {
  255. var tabs = document.querySelector('.tabs'),
  256. labels = document.querySelector('.tabs-labels'),
  257. triggers = document.querySelectorAll('.tabs-label'),
  258. panels = document.querySelectorAll('.tabs-panel');
  259. function activate(i) {
  260. triggers[i].classList.add('tabs-label--active');
  261. panels[i].classList.add('tabs-panel--active');
  262. }
  263. function bindEvents() {
  264. labels.addEventListener('click', function (e) {
  265. var el = e.target,
  266. index;
  267. if (el.classList.contains('tabs-label')) {
  268. for (var t = 0; t < triggers.length; t++) {
  269. triggers[t].classList.remove('tabs-label--active');
  270. panels[t].classList.remove('tabs-panel--active');
  271. if (el === triggers[t]) {
  272. index = t;
  273. }
  274. }
  275. activate(index);
  276. }
  277. var a = document.getElementById("dd");
  278. a.onload();
  279. a.onplay();
  280. });
  281. }
  282. function init() {
  283. activate(0);
  284. bindEvents();
  285. }
  286. // Init
  287. init();
  288. }());
  289. S.Point = function (args) {
  290. this.x = args.x;
  291. this.y = args.y;
  292. this.z = args.z;
  293. this.a = args.a;
  294. this.h = args.h;
  295. };
  296. S.Color = function (r, g, b, a) {
  297. this.r = r;
  298. this.g = g;
  299. this.b = b;
  300. this.a = a;
  301. };
  302. S.Color.prototype = {
  303. render: function () {
  304. return 'rgba(' + this.r + ',' + + this.g + ',' + this.b + ',' + this.a + ')';
  305. }
  306. };
  307. S.Dot = function (x, y) {
  308. this.p = new S.Point({
  309. x: x,
  310. y: y,
  311. z: 5,
  312. a: 1,
  313. h: 0
  314. });
  315. this.e = 0.07;
  316. this.s = true;
  317. this.c = new S.Color(255, 255, 255, this.p.a);
  318. this.t = this.clone();
  319. this.q = [];
  320. };
  321. S.Dot.prototype = {
  322. clone: function () {
  323. return new S.Point({
  324. x: this.x,
  325. y: this.y,
  326. z: this.z,
  327. a: this.a,
  328. h: this.h
  329. });
  330. },
  331. _draw: function () {
  332. this.c.a = this.p.a;
  333. S.Drawing.drawCircle(this.p, this.c);
  334. },
  335. _moveTowards: function (n) {
  336. var details = this.distanceTo(n, true),
  337. dx = details[0],
  338. dy = details[1],
  339. d = details[2],
  340. e = this.e * d;
  341. if (this.p.h === -1) {
  342. this.p.x = n.x;
  343. this.p.y = n.y;
  344. return true;
  345. }
  346. if (d > 1) {
  347. this.p.x -= ((dx / d) * e);
  348. this.p.y -= ((dy / d) * e);
  349. } else {
  350. if (this.p.h > 0) {
  351. this.p.h--;
  352. } else {
  353. return true;
  354. }
  355. }
  356. return false;
  357. },
  358. _update: function () {
  359. if (this._moveTowards(this.t)) {
  360. var p = this.q.shift();
  361. if (p) {
  362. this.t.x = p.x || this.p.x;
  363. this.t.y = p.y || this.p.y;
  364. this.t.z = p.z || this.p.z;
  365. this.t.a = p.a || this.p.a;
  366. this.p.h = p.h || 0;
  367. } else {
  368. if (this.s) {
  369. this.p.x -= Math.sin(Math.random() * 3.142);
  370. this.p.y -= Math.sin(Math.random() * 3.142);
  371. } else {
  372. this.move(new S.Point({
  373. x: this.p.x + (Math.random() * 50) - 25,
  374. y: this.p.y + (Math.random() * 50) - 25,
  375. }));
  376. }
  377. }
  378. }
  379. d = this.p.a - this.t.a;
  380. this.p.a = Math.max(0.1, this.p.a - (d * 0.05));
  381. d = this.p.z - this.t.z;
  382. this.p.z = Math.max(1, this.p.z - (d * 0.05));
  383. },
  384. distanceTo: function (n, details) {
  385. var dx = this.p.x - n.x,
  386. dy = this.p.y - n.y,
  387. d = Math.sqrt(dx * dx + dy * dy);
  388. return details ? [dx, dy, d] : d;
  389. },
  390. move: function (p, avoidStatic) {
  391. if (!avoidStatic || (avoidStatic && this.distanceTo(p) > 1)) {
  392. this.q.push(p);
  393. }
  394. },
  395. render: function () {
  396. this._update();
  397. this._draw();
  398. }
  399. }
  400. S.ShapeBuilder = (function () {
  401. var gap = 13,
  402. shapeCanvas = document.createElement('canvas'),
  403. shapeContext = shapeCanvas.getContext('2d'),
  404. fontSize = 500,
  405. fontFamily = 'Avenir, Helvetica Neue, Helvetica, Arial, sans-serif';
  406. function fit() {
  407. shapeCanvas.width = Math.floor(window.innerWidth / gap) * gap;
  408. shapeCanvas.height = Math.floor(window.innerHeight / gap) * gap;
  409. shapeContext.fillStyle = 'red';
  410. shapeContext.textBaseline = 'middle';
  411. shapeContext.textAlign = 'center';
  412. }
  413. function processCanvas() {
  414. var pixels = shapeContext.getImageData(0, 0, shapeCanvas.width, shapeCanvas.height).data;
  415. dots = [],
  416. pixels,
  417. x = 0,
  418. y = 0,
  419. fx = shapeCanvas.width,
  420. fy = shapeCanvas.height,
  421. w = 0,
  422. h = 0;
  423. for (var p = 0; p < pixels.length; p += (4 * gap)) {
  424. if (pixels[p + 3] > 0) {
  425. dots.push(new S.Point({
  426. x: x,
  427. y: y
  428. }));
  429. w = x > w ? x : w;
  430. h = y > h ? y : h;
  431. fx = x < fx ? x : fx;
  432. fy = y < fy ? y : fy;
  433. }
  434. x += gap;
  435. if (x >= shapeCanvas.width) {
  436. x = 0;
  437. y += gap;
  438. p += gap * 4 * shapeCanvas.width;
  439. }
  440. }
  441. return { dots: dots, w: w + fx, h: h + fy };
  442. }
  443. function setFontSize(s) {
  444. shapeContext.font = 'bold ' + s + 'px ' + fontFamily;
  445. }
  446. function isNumber(n) {
  447. return !isNaN(parseFloat(n)) && isFinite(n);
  448. }
  449. function init() {
  450. fit();
  451. window.addEventListener('resize', fit);
  452. }
  453. // Init
  454. init();
  455. return {
  456. imageFile: function (url, callback) {
  457. var image = new Image(),
  458. a = S.Drawing.getArea();
  459. image.onload = function () {
  460. shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
  461. shapeContext.drawImage(this, 0, 0, a.h * 0.6, a.h * 0.6);
  462. callback(processCanvas());
  463. };
  464. image.onerror = function () {
  465. callback(S.ShapeBuilder.letter('What?'));
  466. }
  467. image.src = url;
  468. },
  469. circle: function (d) {
  470. var r = Math.max(0, d) / 2;
  471. shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
  472. shapeContext.beginPath();
  473. shapeContext.arc(r * gap, r * gap, r * gap, 0, 2 * Math.PI, false);
  474. shapeContext.fill();
  475. shapeContext.closePath();
  476. return processCanvas();
  477. },
  478. letter: function (l) {
  479. var s = 0;
  480. setFontSize(fontSize);
  481. s = Math.min(fontSize,
  482. (shapeCanvas.width / shapeContext.measureText(l).width) * 0.8 * fontSize,
  483. (shapeCanvas.height / fontSize) * (isNumber(l) ? 1 : 0.45) * fontSize);
  484. setFontSize(s);
  485. shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
  486. shapeContext.fillText(l, shapeCanvas.width / 2, shapeCanvas.height / 2);
  487. return processCanvas();
  488. },
  489. rectangle: function (w, h) {
  490. var dots = [],
  491. width = gap * w,
  492. height = gap * h;
  493. for (var y = 0; y < height; y += gap) {
  494. for (var x = 0; x < width; x += gap) {
  495. dots.push(new S.Point({
  496. x: x,
  497. y: y,
  498. }));
  499. }
  500. }
  501. return { dots: dots, w: width, h: height };
  502. }
  503. };
  504. }());
  505. S.Shape = (function () {
  506. var dots = [],
  507. width = 0,
  508. height = 0,
  509. cx = 0,
  510. cy = 0;
  511. function compensate() {
  512. var a = S.Drawing.getArea();
  513. cx = a.w / 2 - width / 2;
  514. cy = a.h / 2 - height / 2;
  515. }
  516. return {
  517. shuffleIdle: function () {
  518. var a = S.Drawing.getArea();
  519. for (var d = 0; d < dots.length; d++) {
  520. if (!dots[d].s) {
  521. dots[d].move({
  522. x: Math.random() * a.w,
  523. y: Math.random() * a.h
  524. });
  525. }
  526. }
  527. },
  528. switchShape: function (n, fast) {
  529. var size,
  530. a = S.Drawing.getArea();
  531. width = n.w;
  532. height = n.h;
  533. compensate();
  534. if (n.dots.length > dots.length) {
  535. size = n.dots.length - dots.length;
  536. for (var d = 1; d <= size; d++) {
  537. dots.push(new S.Dot(a.w / 2, a.h / 2));
  538. }
  539. }
  540. var d = 0,
  541. i = 0;
  542. while (n.dots.length > 0) {
  543. i = Math.floor(Math.random() * n.dots.length);
  544. dots[d].e = fast ? 0.25 : (dots[d].s ? 0.14 : 0.11);
  545. if (dots[d].s) {
  546. dots[d].move(new S.Point({
  547. z: Math.random() * 20 + 10,
  548. a: Math.random(),
  549. h: 18
  550. }));
  551. } else {
  552. dots[d].move(new S.Point({
  553. z: Math.random() * 5 + 5,
  554. h: fast ? 18 : 30
  555. }));
  556. }
  557. dots[d].s = true;
  558. dots[d].move(new S.Point({
  559. x: n.dots[i].x + cx,
  560. y: n.dots[i].y + cy,
  561. a: 1,
  562. z: 5,
  563. h: 0
  564. }));
  565. n.dots = n.dots.slice(0, i).concat(n.dots.slice(i + 1));
  566. d++;
  567. }
  568. for (var i = d; i < dots.length; i++) {
  569. if (dots[i].s) {
  570. dots[i].move(new S.Point({
  571. z: Math.random() * 20 + 10,
  572. a: Math.random(),
  573. h: 20
  574. }));
  575. dots[i].s = false;
  576. dots[i].e = 0.04;
  577. dots[i].move(new S.Point({
  578. x: Math.random() * a.w,
  579. y: Math.random() * a.h,
  580. a: 0.3, //.4
  581. z: Math.random() * 4,
  582. h: 0
  583. }));
  584. }
  585. }
  586. },
  587. render: function () {
  588. for (var d = 0; d < dots.length; d++) {
  589. dots[d].render();
  590. }
  591. }
  592. }
  593. }());
  594. S.init();

微信公众号主页回复“2023新年烟花2”即可获取

第三款

视频链接处获取

Html5+js实现烟花效果

当然在CSDN也是可以下载的

链接:(三款)Html5+Css+JavaScript实现2023年跨年代码烟花设计.zip-Javascript文档类资源-CSDN下载

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/85264
推荐阅读
相关标签
  

闽ICP备14008679号