美文网首页
弹幕组件分解-绘画svg线条,并让弹幕沿着线条运动

弹幕组件分解-绘画svg线条,并让弹幕沿着线条运动

作者: skoll | 来源:发表于2020-10-29 10:33 被阅读0次
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/animejs/3.2.0/anime.min.js"></script>
    <style>
        #icon{
            width:50px;
            height:50px;
            background: red;
            position: absolute;
            left: 0;
            top: 0;
        }
    </style>
</head>
<body>
        <svg style="width:100vw;height:100vh" id="svg">
            <path style="fill: none; stroke: black; stroke-width: 1;"
                  id="path"
            ></path>        
        </svg>
        <div id="icon">
            
        </div>
    <script>
        ;(function() {
  const $body = document.querySelector('body')
  const $svgEl = document.querySelector("#svg")
  const $path = document.querySelector('#path')
  const $path2 = document.querySelector('#path2')
  window.addEventListener('mousedown', () => {
    $path.setAttribute('d', '')
    const points = []
    function draw(e) {
      const x = e.pageX
      const y = e.pageY
      points.push(x, y)
      if (points.length >= 10) {
        const pathString = solve(points, 1.5)
        $path.setAttribute('d', pathString)
      }
    //   const path2String=solve([667,93,312,117,249,339],1.5)
    //   $path2.setAttribute('d',path2String)
    // 利用生成的曲线确实是很平滑的。说明这个函数没问题,还是现在的点太密了,或者还是需要拟合操作

    }
    window.addEventListener('mousemove', draw)
    window.addEventListener('mouseup', () => {
      if (points.length >= 10) {
        runAnimation($path.getAttribute('d'))
      }
      points.length = 0
      window.removeEventListener('mousemove', draw)
    })
  })
  /**
   * 将折线修改为圆滑曲线
   * @param {*} data  [x1,y1,x2,y2,x3,y3...] 长度必须大于4, 长度必须是偶数
   * @param {*} k 拟合系数, 数字
   */
  function solve(data, k =1) {
    const size = data.length
    const last = size - 4
    let path = `M${data[0]},${data[1]}`
    for (let i = 0; i < size - 2; i += 2) {
      const x0 = i ? data[i - 2] : data[0]
      const y0 = i ? data[i - 1] : data[1]
    // 第一个点

      const x1 = data[i + 0]
      const y1 = data[i + 1]
    //第二个点

    // x2 和 y2 作为终点坐标
      const x2 = data[i + 2]
      const y2 = data[i + 3]
    
      const x3 = i !== last ? data[i + 4] : x2
      const y3 = i !== last ? data[i + 5] : y2
      // 计算控制点
      const cp1x = x1 + ((x2 - x0) / 6) * k
      const cp1y = y1 + ((y2 - y0) / 6) * k

      const cp2x = x2 - ((x3 - x1) / 6) * k
      const cp2y = y2 - ((y3 - y1) / 6) * k

      path += ` C${cp1x},${cp1y},${cp2x},${cp2y},${x2},${y2}`
    }

    return path
  }

  /**
   * @description 运行动画
   * @date 2019-08-23
   * @param {*} path
   */
  function runAnimation() {
    // 设置移动点样式
    
    const path=anime.path('#path')
    console.log(path)
    anime({
        targets:'#icon',
        translateX:path('x'),
        translateY:path('y'),
        rotate:path('angle'),
        // 因为这样形成的曲线的太不平滑,所以需要去掉角度旋转。感觉还是要优化下算法吗,或者采用点生成曲线的方法
        // 需要曲线拟合。
        easing:'linear',
        duration:9000,
        loop:true,
    })
  }
})()
    </script>
    
</body>
</html>

相关文章

网友评论

      本文标题:弹幕组件分解-绘画svg线条,并让弹幕沿着线条运动

      本文链接:https://www.haomeiwen.com/subject/tulkvktx.html