帮助:沙盒

QWERTY770留言 | 贡献2021年1月20日 (三) 14:03的版本 (// Edit via Wikiplus)

沙盒(Sandbox)是供Wiki内所有贡献者测试编辑效果用的,管理员有义务定期清理。

如果您在此保存的内容被清理了,可以通过右上角的历史找回。

如果您不希望自己的内容被他人覆盖,请在自己的用户页创建沙盒

请在这行文字下测试您的编辑

<script> /**

  • 搬运须知: 您必须在**显眼处**标识来源“MCBBS Wiki”与作者“Salt_lovely”, **不**接受任何形式的简称或不署名。
  • Notice: You have to mark origin "MCBBS Wiki" and author "Salt_lovely" in CONSPICUOS PLACE, abbreviation or omissions are NOT allowed.
  • 许可证: CC BY-NC-SA 4.0
  • License: CC BY-NC-SA 4.0
  • 灵感来源: https://codepen.io/jackrugile/pen/acAgx 作者 Jack Rugile
  • Inspired By: https://codepen.io/jackrugile/pen/acAgx Author Jack Rugile
  • /

"use strict"; (() => {

 // src/utils/utils.ts
 function docReady(fn) {
   if (document.readyState === "loading") {
     window.addEventListener("DOMContentLoaded", fn);
   } else {
     fn();
   }
 }
 function randomChoice(arr) {
   if (arr.length < 1) {
     return null;
   }
   return arr[Math.floor(Math.random() * arr.length)];
 }
 // widget/SaltFirework/widget.ts
 if (document.getElementById("saltFireWorkCanvas"))
   throw new Error("同一页面中只能有一个烟花");
 //! 颜色范围
 var hueRange;
 //! 颜色变化区间
 var hueDiff;
 //! 粒子效果数量
 var count;
 var baseRange = [1, 4];
 var baseSpeed = [0.3, 2, 3];
 var fallSpeed = 1.1 / 60;
 var fadeSpeed = 0.65;
 var tail = 15;
 var canvas = document.createElement("canvas");
 var context = canvas.getContext("2d");
 var particles = [];
 var lastLength = 0;
 var zeroFrame = 0;
 docReady(init);
 function init() {
   const getValue = (id, defaultValue, min, max) => {
     const e = document.getElementById(id);
     if (!e)
       return defaultValue;
     const c = parseInt(e.textContent || "");
     if (isNaN(c) || c < min || c > max)
       return defaultValue;
     return c;
   };
   hueRange = (() => {
     const defaultValue = (() => {
       var x = [];
       for (let i = 1; i < 361; i++)
         x.push(i);
       return x;
     })();
     const e = document.getElementById("saltFireworkHueRange");
     if (!e)
       return defaultValue;
     const c = (e.textContent || "").replace(/[\s\n_]+/g, "").replace(/[\;\/\|\/\\,;、\-]+/g, ",").split(",").map((v) => parseInt(v)).filter(Boolean).filter((v) => v > 0 && v < 361);
     if (!c || c.length < 1 || c.length > 360)
       return defaultValue;
     return c;
   })();
   hueDiff = getValue("saltFireworkHueDiff", 30, 0, 180);
   count = getValue("saltFireworkCount", 110, 1, 500);
   canvas.id = "saltFireWorkCanvas";
   canvas.style.left = "0";
   canvas.style.top = "0";
   canvas.style.position = "fixed";
   canvas.style.pointerEvents = "none";
   canvas.style.zIndex = "99999";
   document.body.appendChild(canvas);
   resizeCanvas();
   window.addEventListener("resize", resizeCanvas, false);
   tick();
   document.addEventListener("mousedown", function(e) {
     createFireworks(e.clientX, e.clientY);
   });
 }
 function resizeCanvas() {
   canvas.width = window.innerWidth;
   canvas.height = window.innerHeight;
 }
 function rightRandom(base, size) {
   return base + (Math.random() * size - Math.random() * size) / 2;
 }
 function createFireworks(x, y) {
   let hue = randomChoice(hueRange);
   for (let i = 0; i < count; i++) {
     const spd = rightRandom((baseSpeed[1] + baseSpeed[0]) / 2, baseSpeed[1] - baseSpeed[0]);
     const rad = Math.random() * 2 * Math.PI;
     particles.push({
       x,
       y,
       spdX: Math.cos(rad) * spd,
       spdY: Math.sin(rad) * spd,
       spdFall: baseSpeed[2],
       size: rightRandom((baseRange[1] + baseRange[0]) / 2, baseRange[1] - baseRange[0]),
       hue: hueRandom(),
       bright: rightRandom(72, 16),
       alpha: rightRandom(75, 30)
     });
   }
   function hueRandom() {
     let h = Math.floor(rightRandom(hue, hueDiff));
     if (h > 360)
       h -= 360;
     else if (h < 0)
       h += 360;
     return h;
   }
 }
 function drawParticles() {
   if (!particles.length)
     return;
   context.globalCompositeOperation = "lighter";
   for (let i = 0; i < particles.length; i++) {
     let p = particles[i];
     if (!p)
       continue;
     p.x += p.spdX * p.spdFall;
     p.y += p.spdY * p.spdFall;
     p.spdY += fallSpeed;
     p.spdFall *= 0.978;
     p.alpha -= fadeSpeed;
     context.beginPath();
     context.arc(p.x, p.y, p.size, 0, Math.PI * 2, false);
     context.closePath();
     context.fillStyle = `hsla(${p.hue},100%,${p.bright}%,${p.alpha / 100})`;
     context.fill();
     //! 标记已经透明到看不见的粒子
     if (p.alpha < fadeSpeed)
       particles[i] = null;
   }
   if (lastLength === 0 && particles.length === 0) {
     zeroFrame += 1;
     if (zeroFrame === 30)
       canvas.height = window.innerHeight;
   } else {
     zeroFrame = 0;
   }
   lastLength = particles.length;
 }
 function drawTail() {
   if (zeroFrame >= 30)
     return;
   //! 保留前一刻的图案作为尾迹
   context.globalCompositeOperation = "destination-out";
   context.fillStyle = `rgba(0,0,0,${1 / tail})`;
   context.fillRect(0, 0, canvas.width, canvas.height);
 }
 function clearParticles() {
   if (!particles.length)
     return;
   let cp = [];
   for (let p of particles)
     if (p)
       cp.push(p);
   if (cp.length !== particles.length)
     particles = cp;
 }
 function tick() {
   //! 画尾迹 -> 画这一帧的粒子 -> 删除运算完毕的粒子
   drawTail();
   drawParticles();
   clearParticles();
   if (false) {
     const el = document.getElementById("saltFWInfo");
     if (el) {
       el.innerHTML = particles.map((p) => JSON.stringify(p)).join("
"); } } requestAnimationFrame(tick); }

})(); </script>