[英]How do I “perfectly” center an object following an SVG path in Anime.js?
我正在使用Anime.js在 SVG 中围绕圆形路径移动一个 20 像素的正方形。 然而,正方形在它的圆形路径中并不完全居中:
anime({
targets: '.square',
translateX: path('x'),
translateY: path('y'),
rotate: path('angle'),
easing: 'linear',
duration: 10000,
loop: true,
});
https://codepen.io/gremo/pen/wvKjrMW
我找到了类似的例子,但我无法理解这项工作的数学原理:
发生这种情况是因为您的 object(正方形)确实在遵循该路径。 但是,object 是根据左上角的第一个像素值转换的(因此,如果您制作一个1px x 1px
的正方形,您应该会看到正方形很好地跟随路径)。 这就是为什么对象的左上角总是粘在这条线上的原因。 你想要的是让 object 的中间部分坚持到底。
使用静态和手动计算的值(框的原始宽度和高度的 50%)是合理的(例如,给top
和left
都赋予-10px
)。 但是,当有许多对象被动画时,您可能不想这样做(因为当发生更改时,您需要更新所有 CSS 代码)。 相反,我们可以在.square
上使用伪元素::after
并将其向左平移 50% 的宽度,向顶部平移 50% 的高度。 这样,物体的附着在直线上的点就是正方形的中心部分。 现在,当您更新原始.square
元素的宽度和高度时,您不需要更新top
和left
的值。 您不能简单地将transform: translate(-50%, -50%)
值添加到原始.square
div,因为它将使用 Anime.js 进行动画处理,并且初始变换值将丢失。 从 JS 获取计算出的初始变换值很棘手。
document.addEventListener('DOMContentLoaded', function() { const path = anime.path('.circle path'); anime({ targets: '.square', translateX: path('x'), translateY: path('y'), easing: 'linear', duration: 10000, loop: true, }); });
body { background-color: #001f3f; }.container { position: relative; margin: 0 auto; max-width: 500px; }.circle { fill: none; stroke: #b10dc9; }.square { position: absolute; top: 0; left: 0; display: inline-block; width: 20px; height: 20px; }.square::after { content: ''; position: absolute; width: 100%; height: 100%; transform: translate(-50%, -50%); background-color: #f012be; }
<script src="https://unpkg.com/animejs@3.2.0/lib/anime.min.js"></script> <div class="container"> <svg class="circle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> <path d="M400,250c0,82.84-67.16,150-150,150s-150-67.16-150-150s67.16-150,150-150S400,167.16,400,250z" /> </svg> <span class="square"></span> </div>
要了解逻辑,请添加另一个具有不同宽度/高度的元素以查看每个 object 的参考:
document.addEventListener('DOMContentLoaded', function() { const path = anime.path('.circle path'); anime({ targets: '.square', translateX:path('x'), translateY: path('y'), easing: 'linear', duration: 10000, loop: true, }); anime({ targets: '.square2', translateX: path('x'), translateY: path('y'), easing: 'linear', duration: 10000, loop: true, }); });
body { background-color: #001f3f; }.container { position: relative; margin: 0 auto; max-width: 500px; }.circle { fill: none; stroke: #b10dc9; }.square { position: absolute; top: 0; left: 0; display: inline-block; width: 20px; height: 20px; background-color: #f012be; }.square2 { position: absolute; top: 0; left: 0; display: inline-block; width: 40px; height: 40px; background-color: blue; }
<script src="https://unpkg.com/animejs@3.2.0/lib/anime.min.js"></script> <div class="container"> <svg class="circle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> <path d="M400,250c0,82.84-67.16,150-150,150s-150-67.16-150-150s67.16-150,150-150S400,167.16,400,250z" /> </svg> <span class="square2"></span> <span class="square"></span> </div>
如您所见,上/左角跟随路径。 为避免这种情况,您可以使用负左/上来偏移元素并使其居中,或者使用不同的 CSS 来制作通用的东西。
我制作了 0 维的元素,并考虑使用box-shadw
来创建方形:
document.addEventListener('DOMContentLoaded', function() { const path = anime.path('.circle path'); anime({ targets: '.square', translateX:path('x'), translateY: path('y'), easing: 'linear', duration: 10000, loop: true, }); anime({ targets: '.square2', translateX: path('x'), translateY: path('y'), easing: 'linear', duration: 10000, loop: true, }); });
body { background-color: #001f3f; }.container { position: relative; margin: 0 auto; max-width: 500px; }.circle { fill: none; stroke: #b10dc9; }.square { content:""; position: absolute; left:0; right:0; width: 0; height: 0; box-shadow:0 0 0 10px #f012be; }.square2 { position: absolute; top: 0; left: 0; width: 0; height: 0; box-shadow:0 0 0 20px blue; }
<script src="https://unpkg.com/animejs@3.2.0/lib/anime.min.js"></script> <div class="container"> <svg class="circle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> <path d="M400,250c0,82.84-67.16,150-150,150s-150-67.16-150-150s67.16-150,150-150S400,167.16,400,250z" /> </svg> <span class="square2"></span> <span class="square"></span> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.