canvas折叠丝带丝巾效果代码

代码语言:html

所属分类:其他

代码描述:canvas折叠丝带丝巾效果代码

代码标签: canvas 丝巾 丝带 折叠

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

<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">



    <style>
        canvas, .overlay {
          position: fixed;
          top: 0;
          left: 0;
          height: 100%;
          width: 100%;
        }
        
        canvas {
          cursor: pointer;
          background: #fc4248;
        }
        
        .overlay {
        
          pointer-events: none;
          opacity: 0.5;
        }
    </style>



</head>

<body>
    <canvas></canvas>
    <div class="overlay"></div>

    <script>
        const RIBBON_WIDTH = 60;
        const SEGMENT_LENGTH = 80;
        const C1 = "#f060d0";
        const C2 = "#f080f0";
        const MAX_SEGMENTS = 3;
        const MAX_FOLDS = 1000;
        const MAX_ATTEMPTS_PER_FOLD = 30;
        
        const DEBOUNCE_MS = 300;
        const QUALITY = 1; // Range: (0, 1]
        
        const canvas = document.querySelector("canvas");
        const ctx = canvas.getContext("2d");
        
        // Global state: canvas size.
        let w, h, maxX, maxY, offsetX, offsetY, scale;
        // Global state: ribbon.
        let position, prevDir, visited;
        
        function drawFrame(i, iteration) {
          if (iteration !== currentIteration) return true;
        
          const isOdd = i % 2;
          let len, dir, vec, nextPosition;
          let attempts = 0;
          do {
            len = Math.ceil(Math.random() * MAX_SEGMENTS);
            dir = Math.random() < 0.5 ? 1 : -1;
            vec = isOdd ? [dir, 0] : [0, dir];
            nextPosition = position.map((p, i) => p + vec[i] * len);
            if (++attempts > MAX_ATTEMPTS_PER_FOLD) return true;
          } while (
          visited[nextPosition.join("-")] ||
          nextPosition[0] < 0 ||
          nextPosition[1] < 0 ||
          nextPosition[0] > maxX ||
          nextPosition[1] > maxY);
        
        
          if (i) {
            // Draw the shadow.
            const shadowCoords1 = position.map(
            (p, i) =>
            p * SEGMENT_LENGTH - (i === isOdd ? prevDir * RIBBON_WIDTH / 2 : 0));
        
            const shadowCoords2 = position.map(
            (p, i) =>
            p * SEGMENT_LENGTH - (i === isOdd ? prevDir * RIBBON_WIDTH / 1.7 : 0));
        
            const gradient = ctx.createLinearGradient(...shadowCoords1, ...shadowCoords2);
            gradient.addColorStop(0, "rgba(0, 0, 0, 0.06)");
            gradient.addColorStop(0.1, "rgba(0, 0, 0, 0.055)");
            gradient.addColorStop(1, "rgba(0, 0, 0, 0)");
        
            ctx.strokeStyle = gradient;
        
            ctx.beginPath();
            ctx.moveTo(...shadowCoords1);
            ctx.lineTo(...shadowCoords2);
        
            ctx.stroke();
        
            // Draw the triangle.
            ctx.fillStyle = isOdd ? C2 : C1;
            ctx.beginPath();
            ctx.moveTo(
            position[0] * SEGMENT_LENGTH + prevDir * RIBBON_WIDTH / 2,
            position[1] * SEGMENT_LENGTH + dir * RIBBON_WIDTH / 2);
        
            ctx.lineTo(
            position[0] * SEGMENT_LENGTH - prevDir * RIBBON_WIDTH / 2,
            position[1] * SEGMENT_LENGTH - dir * RIBBON_WIDTH / 2);
        
            if.........完整代码请登录后点击上方下载按钮下载查看

网友评论0