无缝播放新的 css 动画
Play new css animation seamlessly
我创建了一个简单的 HTML 游戏,当我点击一个移动的方块时它会在屏幕下方消失。
但是,消失的动画从原始位置开始,而不是单击的位置。
我觉得0%的remove @keyframes
应该有点击的位置,但是找不到方法
我该怎么办?
(function () {
const charactersGroup = document.querySelectorAll('.character');
const stage = document.querySelector('.stage')
const clickHandler = (e) => {
const target = e.target;
if (target.classList.contains('character')) {
target.classList.remove(`f${target.dataset.id}`);
target.classList.add('f0');
target.classList.add('remove');
setTimeout(() => { stage.removeChild(target) }, 2000);
}
}
stage.addEventListener('click', clickHandler);
}());
.stage {
overflow: hidden;
position: relative;
background: #eeeeaa;
width: 40vw;
height: 20vw;
}
@keyframes moving {
0% {
transform: translateX(0);
}
100% {
transform: translateX(30vw);
}
}
@keyframes remove {
0% {
transform: translate(0);
}
100% {
transform: translateY(60vw);
}
}
.character {
position: absolute;
width: 50px;
height: 50px;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
animation: moving infinite alternate;
}
.remove {
animation: remove 0.2s cubic-bezier(.68,-0.55,.27,1.55) forwards;
}
.f0 {
background-color: black;
animation-duration: 2s;
}
.f1 {
left: 5%;
bottom: 5%;
animation-duration: 2s;
background-color: red;
}
<div class="stage">
<div class="character f1" data-id="1"></div>
</div>
如果您的用例是处理很多这样的框和复杂性,最好使用纯 JS 处理所有内容,但我试图通过对 JS 和 CSS 的最小更改来完成这项工作。
我已经为新的 JS 行添加了注释。
还冒昧地为动画 moving
单独设置了一个名为 moving
的 class,以便我们可以在单击时将其删除。
(function () {
const charactersGroup = document.querySelectorAll('.character');
const stage = document.querySelector('.stage')
const clickHandler = (e) => {
const target = e.target;
if (target.classList.contains('character')) {
target.classList.remove(`f${target.dataset.id}`);
target.classList.add('f0');
// remove the moving animation
target.classList.remove('moving');
// Get offsetWidth which is the half of width to substract later while calculating left for the target i.e our box.
const offsetWidth = parseInt(getComputedStyle(target).width)/2;
// e.clientX gives us the x coordinate of the mouse pointer
// target.getBoundingClientRect().left gives us left position of the bounding rectangle and acts as a good offset to get the accurate left for our box.
target.style.left = `${e.clientX -target.getBoundingClientRect().left - offsetWidth}px`;
target.classList.add('remove');
setTimeout(() => { stage.removeChild(target) }, 2000);
}
}
stage.addEventListener('click', clickHandler);
}());
.stage {
overflow: hidden;
position: relative;
background: #eeeeaa;
width: 40vw;
height: 20vw;
}
@keyframes moving {
0% {
transform: translateX(0);
}
100% {
transform: translateX(30vw);
}
}
@keyframes remove {
0% {
transform: translate(0vh);
}
100% {
transform: translateY(60vw);
}
}
.character {
position: absolute;
width: 50px;
height: 50px;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
}
.moving{
animation: moving infinite alternate;
}
.remove {
animation: remove 0.2s cubic-bezier(.68,-0.55,.27,1.55) forwards;
}
.f0 {
background-color: black;
animation-duration: 2s;
}
.f1 {
left: 5%;
bottom: 5%;
animation-duration: 2s;
background-color: red;
}
<div class="stage">
<div class="character moving f1" data-id="1"></div>
</div>
更改第一个动画以考虑 left
而不是翻译,然后将它们都附加到最初的元素,您只需在添加 remove
[=24= 时切换 animation-play-state
]
(function() {
const charactersGroup = document.querySelectorAll('.character');
const stage = document.querySelector('.stage')
const clickHandler = (e) => {
const target = e.target;
if (target.classList.contains('character')) {
target.classList.add('remove');
setTimeout(() => {
stage.removeChild(target)
}, 2000);
}
}
stage.addEventListener('click', clickHandler);
}());
.stage {
overflow: hidden;
position: relative;
background: #eeeeaa;
width: 40vw;
height: 20vw;
}
@keyframes moving {
100% {
left:calc(95% - 50px);
}
}
@keyframes remove {
50% {
transform: translateY(-30vh);
}
100% {
transform: translateY(60vw);
}
}
.character {
position: absolute;
width: 50px;
height: 50px;
background:red;
left: 5%;
bottom: 5%;
animation:
moving 2s infinite alternate,
remove 1s cubic-bezier(.68, -0.55, .27, 1.55) forwards paused;
}
.remove {
animation-play-state:paused,running;
background: black;
}
<div class="stage">
<div class="character f1" data-id="1"></div>
</div>
我创建了一个简单的 HTML 游戏,当我点击一个移动的方块时它会在屏幕下方消失。 但是,消失的动画从原始位置开始,而不是单击的位置。
我觉得0%的remove @keyframes
应该有点击的位置,但是找不到方法
我该怎么办?
(function () {
const charactersGroup = document.querySelectorAll('.character');
const stage = document.querySelector('.stage')
const clickHandler = (e) => {
const target = e.target;
if (target.classList.contains('character')) {
target.classList.remove(`f${target.dataset.id}`);
target.classList.add('f0');
target.classList.add('remove');
setTimeout(() => { stage.removeChild(target) }, 2000);
}
}
stage.addEventListener('click', clickHandler);
}());
.stage {
overflow: hidden;
position: relative;
background: #eeeeaa;
width: 40vw;
height: 20vw;
}
@keyframes moving {
0% {
transform: translateX(0);
}
100% {
transform: translateX(30vw);
}
}
@keyframes remove {
0% {
transform: translate(0);
}
100% {
transform: translateY(60vw);
}
}
.character {
position: absolute;
width: 50px;
height: 50px;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
animation: moving infinite alternate;
}
.remove {
animation: remove 0.2s cubic-bezier(.68,-0.55,.27,1.55) forwards;
}
.f0 {
background-color: black;
animation-duration: 2s;
}
.f1 {
left: 5%;
bottom: 5%;
animation-duration: 2s;
background-color: red;
}
<div class="stage">
<div class="character f1" data-id="1"></div>
</div>
如果您的用例是处理很多这样的框和复杂性,最好使用纯 JS 处理所有内容,但我试图通过对 JS 和 CSS 的最小更改来完成这项工作。
我已经为新的 JS 行添加了注释。
还冒昧地为动画 moving
单独设置了一个名为 moving
的 class,以便我们可以在单击时将其删除。
(function () {
const charactersGroup = document.querySelectorAll('.character');
const stage = document.querySelector('.stage')
const clickHandler = (e) => {
const target = e.target;
if (target.classList.contains('character')) {
target.classList.remove(`f${target.dataset.id}`);
target.classList.add('f0');
// remove the moving animation
target.classList.remove('moving');
// Get offsetWidth which is the half of width to substract later while calculating left for the target i.e our box.
const offsetWidth = parseInt(getComputedStyle(target).width)/2;
// e.clientX gives us the x coordinate of the mouse pointer
// target.getBoundingClientRect().left gives us left position of the bounding rectangle and acts as a good offset to get the accurate left for our box.
target.style.left = `${e.clientX -target.getBoundingClientRect().left - offsetWidth}px`;
target.classList.add('remove');
setTimeout(() => { stage.removeChild(target) }, 2000);
}
}
stage.addEventListener('click', clickHandler);
}());
.stage {
overflow: hidden;
position: relative;
background: #eeeeaa;
width: 40vw;
height: 20vw;
}
@keyframes moving {
0% {
transform: translateX(0);
}
100% {
transform: translateX(30vw);
}
}
@keyframes remove {
0% {
transform: translate(0vh);
}
100% {
transform: translateY(60vw);
}
}
.character {
position: absolute;
width: 50px;
height: 50px;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
}
.moving{
animation: moving infinite alternate;
}
.remove {
animation: remove 0.2s cubic-bezier(.68,-0.55,.27,1.55) forwards;
}
.f0 {
background-color: black;
animation-duration: 2s;
}
.f1 {
left: 5%;
bottom: 5%;
animation-duration: 2s;
background-color: red;
}
<div class="stage">
<div class="character moving f1" data-id="1"></div>
</div>
更改第一个动画以考虑 left
而不是翻译,然后将它们都附加到最初的元素,您只需在添加 remove
[=24= 时切换 animation-play-state
]
(function() {
const charactersGroup = document.querySelectorAll('.character');
const stage = document.querySelector('.stage')
const clickHandler = (e) => {
const target = e.target;
if (target.classList.contains('character')) {
target.classList.add('remove');
setTimeout(() => {
stage.removeChild(target)
}, 2000);
}
}
stage.addEventListener('click', clickHandler);
}());
.stage {
overflow: hidden;
position: relative;
background: #eeeeaa;
width: 40vw;
height: 20vw;
}
@keyframes moving {
100% {
left:calc(95% - 50px);
}
}
@keyframes remove {
50% {
transform: translateY(-30vh);
}
100% {
transform: translateY(60vw);
}
}
.character {
position: absolute;
width: 50px;
height: 50px;
background:red;
left: 5%;
bottom: 5%;
animation:
moving 2s infinite alternate,
remove 1s cubic-bezier(.68, -0.55, .27, 1.55) forwards paused;
}
.remove {
animation-play-state:paused,running;
background: black;
}
<div class="stage">
<div class="character f1" data-id="1"></div>
</div>