如何强制元素的 CSS 动画从与上一个动画完成的位置相同的位置开始?
Posted
技术标签:
【中文标题】如何强制元素的 CSS 动画从与上一个动画完成的位置相同的位置开始?【英文标题】:How can I force a CSS animation of an element to start from the same location as the previous animation finished? 【发布时间】:2022-01-05 10:35:13 【问题描述】:我有一个图像,我想在每次单击鼠标时移动一定距离(始终相同)和特定方向(在数组中指定)。第一次单击将其移动到第一个数组元素中指定的方向,第二次单击第二个,依此类推。
除非我要求它连续两次向同一方向移动,否则这很好用。在这种情况下,它会立即移动到没有动画的结束位置,就好像它已经在那里开始了动画一样,尽管调试器显示了由 unitElement.style.left 定义的位置,与它在屏幕上的外观正确对应。
html,带有四个转换和一个要移动的图像:
<style>
.unit width: 60px; height: 60px; position: absolute;
@keyframes N 100% transform: translate(0px, -60px);
@keyframes E 100% transform: translate(60px, 0px);
@keyframes S 100% transform: translate(0px, 60px);
@keyframes W 100% transform: translate(-60px, 0px);
</style>
<body>
<img src="test.png" class="unit" id="F1" />
</body>
点击事件调用的函数:
function nextPulseAnimate()
pulse++;
for(var index = 0; index < units.length; index++)
var unit = units[index];
var direction = unit.moves[pulse-1]
var unitElement = document.getElementById(unit.name);
//ensure that the image is starting from the right place
unitElement.style.left = unit.start.x;
unitElement.style.top = unit.start.y;
unitElement.style.animation = direction + " 2s ease-in-out forwards";
//then re-set the locations ready for next pulse
//If this is not done, each animation will start from the unit's original location
for(var index = 0; index < units.length; index++)
var unit = units[index];
var direction = unit.moves[pulse-1]
switch (direction)
case "N":
unit.start.y -= 60;
break;
case "E":
unit.start.x += 60;
break;
case "S":
unit.start.y += 60;
break;
case "W":
unit.start.x -= 60;
break;
函数中提到的“单元”来自一个全局对象数组,看起来像这样(实际上它会有几十个元素):
units = [
name: "F1", start: x: 0, y: 0, moves: ["S", "E", "E", "E"]
];
为了完整起见,定义了另一个全局变量(并在上面使用): 脉冲 = 0
【问题讨论】:
提供 css.unit
规则定义。如何。您的 img 是静态的、相对的、绝对的还是固定的?一个最小的可重现代码会非常好。
当然。这是 .unit 的 css 定义: .unit width: 60px;高度:60px;位置:绝对;
我的意思是像.unit position: absolute; height:20px
这样的整个css规则。更新你的开场白/问题
在第二个 for 循环中,您将单位设置为固定坐标,它们实际上并不是它们的最后位置。有一个 DOM 事件 onAnimationEnd
您可以使用它来更新最后一个坐标。 developer.mozilla.org/en-US/docs/Web/API/HTMLElement/…
连续两次问题:当你设置相同的动画名称时,系统不会动画,因为它认为它已经完成了。您需要清除它并以某种方式重置。
【参考方案1】:
这就是我的意思:
units = [name: "F1", start: x: '0px', y: '0px',
moves: ["S", "E", "E", "N", "W", "W"]
,
name: "F2", start: x: '120px', y: '60px' ,
moves: ["N", "W", "W", "S", "E", "E"]
];
var pulse = 0;
function init()
document.body.addEventListener("click", nextPulseAnimate);
for (var index = 0; index < units.length; index++)
var unit = units[index];
var unitElement = document.getElementById(unit.name);
unitElement.style.left = unit.start.x;
unitElement.style.top = unit.start.y;
unitElement.addEventListener('animationend', (event) =>
document.body.addEventListener("click", nextPulseAnimate);
var e = event.target;
/* get position relative to viewport */
var r = e.getBoundingClientRect();
e.style.left = r.left + 'px';
e.style.top = r.top + 'px';
/* remove animation so that you can use it again */
e.style.animation = 'none';
);
function nextPulseAnimate()
pulse++;
if (pulse < 7)
document.getElementById('stats').innerText = 'Moves: ' + pulse + '/6';
//don't let user click while animation is going on
document.body.removeEventListener('click', nextPulseAnimate);
for (var index = 0; index < units.length; index++)
var unit = units[index];
var direction = unit.moves[pulse - 1]
var unitElement = document.getElementById(unit.name);
unitElement.style.animation = direction + " 2s ease-in-out forwards";
body
width: 90vw;
height: 90vh
p
position: fixed;
top: 40vh;
.unit width: 60px; height: 60px; position: absolute;
@keyframes N 100% transform: translate(0px, -60px);
@keyframes E 100% transform: translate(60px, 0px);
@keyframes S 100% transform: translate(0px, 60px);
@keyframes W 100% transform: translate(-60px, 0px);
<!DOCTYPE html>
<html>
<body onload="init()">
<img src="https://dummyimage.com/60x60/000/fff.jpg" class="unit" id="F1" />
<img src="https://dummyimage.com/60x60/a0a/fff.jpg" class="unit" id="F2" />
<p id=stats>Click anywhere to trigger moves</p>
</body>
</html>
【讨论】:
以上是关于如何强制元素的 CSS 动画从与上一个动画完成的位置相同的位置开始?的主要内容,如果未能解决你的问题,请参考以下文章
java - 如何在java脚本或css中完成动画后使元素可拖动?
您可以使用 JavaScript 将 CSS 关键帧动画“强制”到其最终状态吗?