繁体   English   中英

如何在 Anime.js 中按照 SVG 路径“完美”居中 object?

[英]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 使用 top/left/margin 居中(即使是负值)
  • 这里object 仅使用顶部/左侧居中(具有负值)

发生这种情况是因为您的 object(正方形)确实在遵循该路径。 但是,object 是根据左上角的第一个像素值转换的(因此,如果您制作一个1px x 1px的正方形,您应该会看到正方形很好地跟随路径)。 这就是为什么对象的左上角总是粘在这条线上的原因。 你想要的是让 object 的中间部分坚持到底。

使用静态和手动计算的值(框的原始宽度和高度的 50%)是合理的(例如,给topleft都赋予-10px )。 但是,当有许多对象被动画时,您可能不想这样做(因为当发生更改时,您需要更新所有 CSS 代码)。 相反,我们可以在.square上使用伪元素::after并将其向左平移 50% 的宽度,向顶部平移 50% 的高度。 这样,物体的附着在直线上的点就是正方形的中心部分。 现在,当您更新原始.square元素的宽度和高度时,您不需要更新topleft的值。 您不能简单地将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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM