svg+js实现随机破碎效果代码

代码语言:html

所属分类:其他

代码描述:svg+js实现随机破碎效果代码,点击可更换破碎效果。

代码标签: svg 破碎

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">





    <style>
        body {
          width: 100vw; height: 100vh;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          background-color: #000;
          margin: 0;
          padding: 0;
          color: #999;
          font-family: sans-serif;
        }
        #controls {
          padding: 20px;
        }
        .row {
          margin-bottom: 10px;
          text-align: center;
        }
        .container {
          display: flex;
          flex-direction: column;
          filter: url(#goo);
        }
    </style>

</head>

<body>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="600" viewBox="0 0 600 600">
  <defs>
    <linearGradient id="grad" x1="0%" y1="100%" x2="10%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:0.2" />
      <stop offset="100%" style="stop-color:rgb(255,255,255);stop-opacity:0.1" />
    </linearGradient>
  </defs>
  <rect x="0" y="0" width="600" height="600" fill="rgb(252,68,63)" />
  <!--  filter="url(#goo)" -->
  <g id="content">
  </g>
</svg>

    <div id="controls">
        <div class="row">
            <button id="exportpng">Export PNG</button> <button id="exportsvg">Export SVG</button>
        </div>
        <div class="row">
            <input type="checkbox" checked name="autoplay" id="autoplay" /> <label for="autoplay">Autoplay</label>
        </div>
    </div>


    <script>
        const ns = 'http://www.w3.org/2000/svg';
        
        const svg = document.querySelector('svg');
        const content = svg.getElementById('content');
        
        const element = (type, attrs) => {
          const el = document.createElementNS(ns, type);
          for (let key in attrs) {
            el.setAttribute(key, attrs[key]);
          }
          return el;
        };
        
        const rand = (a, b) =>
        Math.random() * (b - a) + a;
        
        const add = (a, b) => a.map((v, i) => v + b[i]);
        const scale = (a, k) => a.map(v => v * k);
        const sub = (a, b) => add(a, scale(b, -1));
        const dist = (a, b) => Math.hypot(...add(a, scale(b, -1)));
        const lerp = (a, b, t) => a.map((v, i) => v * (1 - t) + b[i] * t);
        
        const hslToRgb = (h, s, l) => {
          let r, g, b;
        
          if (s == 0) {
            r = g = b = l; // achromatic
          } else {
            const hue2rgb = (p, q, t) => {
              if (t < 0) t += 1;
              if (t > 1) t -= 1;
              if (t < 1 / 6) return p + (q - p) * 6 * t;
              if (t < 1 / 2) return q;
              if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
              return p;
            };
        
            var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
            var p = 2 * l - q;
            r = hue2rgb(p, q, h + 1 / 3);
            g = hue2rgb(p, q, h);
            b = hue2rgb(p, q, h - 1 / 3);
          }
        
          return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
        };
        
        const d = (instructions) =>
        instructions.map(([type, ...pts]) => type + pts.map(pt => ` ${pt[0].toFixed(4)} ${pt[1].toFixed(4)}`).join('')).join(' ');
        
        const append = el => content.appendChild(el);
        
        const clear = () => {
          while (content.firstChild) {
            content.removeChild(content.firstChild);
          }
        };
        
        const generate = () => {
          clear();
        
          const contours = [
          [[100, 100], [500, 100], [500, 500], [100, 500]]];
        
        
          const totalLength = contour => {
            let total = 0;
            for (let i = 0; i < contour.length; i++) {
              total += dist(contour[(i + 1) % contour.length], contour[i]);
            }
            return total;
          };
          const pointAtLength = (contour, len) => {
            let lenSoFar = 0;
            let idx = 0;
            for (let i = 0;; i = (i + 1) % contour.length) {
              const nextLen = dist(contour[i], contour[(i + 1) % contour.length]);
              if (lenSoFar + nextLen > len) {
                idx = i + (lenSoFar + nextLen - len) / nextLen;
                break;
              } else {
                lenSoFar += nextLen;
              }
            }
        
            pt = lerp(
            contour[Math.floor(idx)],
            contour[Math.ceil(idx) % contour.length],
            idx - Math.floor(idx));
            return [pt, idx];
          };
        
          const split = pts => {
            const sideLengths = pts.map((pt, i) => dist(pt, pts[(i + 1) % pts.length]));
            const sideIndices = pts.map((_, i) => i).sort((a, b) => sideLengths[b] - sideLengths[a]);
            const id1 = rand(sideIndices[0], sideIndices[0] + 1);
            //const id2 = rand(sideIndices[1], sideIndices[1]+1);
            const id2 = (Math.floor(id1) + 2 + (1 - (id1 - Math.........完整代码请登录后点击上方下载按钮下载查看

网友评论0