【问题标题】:How to create funky circle using svg path?如何使用 svg 路径创建时髦的圆圈?
【发布时间】:2021-07-15 07:32:47
【问题描述】:

我正在尝试复制 Patrick Heng (patrickheng.com) 在他的网站上所做的事情。当您将鼠标悬停在固定圆圈上时,我想创建这种时髦的效果。我最接近的方法是使用路径创建圆然后更改路径值,但这会产生非常糟糕的结果并且不受控制。

<path 
      d="
        M 25, 50
        a 25,25 0 1,1 50,0
        a 25,25 0 1,1 -50,0
        " />

我们可以改变Ma的值。

【问题讨论】:

  • 我认为它是用二次贝塞尔曲线完成的......
  • 请在问题中包含所有相关内容以避免链接腐烂。

标签: svg svg-animate


【解决方案1】:

这与 Quadratic Bezier 路径类似:

const angleFromCenter = (cx, cy, mx, my) => {
  const mAngle = Math.atan2(mx - cx, - my + cy);
  return mAngle > 0 ? mAngle : (Math.PI * 2 + mAngle);
};

const circlePath = (cx, cy, r, mx, my) => {
  const dist = Math.hypot(mx - cx, my - cy);
  let path = '';
  if (dist > r) {
    const angle = angleFromCenter(cx, cy, mx, my);
    const delta = Math.acos(r / dist); 
  
    const p0x = cx + r * Math.sin(angle - delta);
    const p0y = cy - r * Math.cos(angle - delta);
    const p2x = cx + r * Math.sin(angle + delta);
    const p2y = cy - r * Math.cos(angle + delta);
    const anchorR = dist > r * 2 ? r * 4 - dist : dist;
    const p1x = cx + anchorR * Math.sin(angle);
    const p1y = cy - anchorR * Math.cos(angle);
    path = `M ${p0x},${p0y} Q ${p1x},${p1y} ${p2x},${p2y}`;
  }
  return path + `M ${cx},${cy - r} A ${r},${r} 1 1 1 ${cx},${cy + r} A ${r},${r} 1 1 1 ${cx},${cy - r} Z`;
}

const svg = d3.select('svg')
const path = circlePath(100, 100, 50, 100, 100);
const circle = svg.append('path')
  .attr('d', path)
  .style('fill', 'blue');

svg.on('mousemove', (e) => {
  const d = circlePath(100, 100, 50, e.offsetX, e.offsetY);
  circle.attr('d', d);
});
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>

<svg width="200" height="200">
</svg>

【讨论】:

  • 对不起,我花了这么长时间才回复,但这正是我想要的。如果没有 d3 ,我们还能做一件事吗?问题是我没有在我的项目中使用 d3,并且只为 1 个效果导入整个库并不是很高效。但再次非常感谢您的帮助
  • @lovekesh 当然。您可以使用 jQuery 或 vanilla JS 来完成。 circlePath 功能保持不变。您唯一需要做的就是处理mousemove 事件
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
相关资源
最近更新 更多