在缩放对象上弹跳动画
Bounce animation on a scaled object
让对象缩放然后在返回原始缩放因子之前以该缩放因子执行反弹动画的最佳方法是什么。我意识到我可以做一些事情,比如将它缩放到 2.2,然后是 1.8,然后是 2.0,但我正在寻找一种方法,你只需要在比例因子上执行反弹动画,因为我的比例因子会改变。
这是我的例子。基本上我想像我说的那样将两者结合起来工作,但正如您所看到的,弹跳动画根据缩放前的图像大小执行。
我需要图像的所有边都像示例一样反弹。
function myFunction() {
var image = document.getElementById('test');
image.style.WebkitTransform = ('scale(2,2)');
image.classList.remove('bounce');
image.offsetWidth = image.offsetWidth;
image.classList.add('bounce') ;
}
div#test {
position:relative;
display: block;
width: 50px;
height: 50px;
background-color: blue;
margin: 50px auto;
transition-duration: 1s;
}
.bounce {
animation: bounce 450ms;
animation-timing-function: linear;
}
@keyframes bounce{
25%{transform: scale(1.15);}
50%{transform: scale(0.9);}
75%{transform: scale(1.1);}
100%{transform: scale(1.0);}
}
<div id='test'> </div>
<button class = 'butt' onclick = 'myFunction()'>FIRST</button>
您可以尝试使用 CSS 变量来使比例因子在关键帧内动态变化:
function myFunction(id,s) {
var image = document.querySelectorAll('.test')[id];
image.style.setProperty("--s", s);
image.classList.remove('bounce');
image.offsetWidth = image.offsetWidth;
image.classList.add('bounce');
}
div.test {
display: inline-block;
width: 50px;
height: 50px;
background-color: blue;
margin: 50px;
transform:scale(var(--s,1));
}
.bounce {
animation: bounce 450ms;
animation-timing-function: linear;
}
@keyframes bounce {
25% {
transform: scale(calc(var(--s,1) + 0.2));
}
50% {
transform: scale(calc(var(--s,1) - 0.1));
}
75% {
transform: scale(calc(var(--s,1) + 0.1));
}
100% {
transform: scale(var(--s,1));
}
}
<div class='test'> </div>
<div class='test'> </div>
<div class='test'> </div>
<div>
<button class='butt' onclick='myFunction(0,"2")'>first</button>
<button class='butt' onclick='myFunction(1,"3")'>Second</button>
<button class='butt' onclick='myFunction(2,"0.5")'>third</button>
<button class='butt' onclick='myFunction(1,"1")'>second again</button>
</div>
在不同的包装元素上分派每个转换。
通过这种方式,您可以实现多个级别的转换,所有转换都相对于它们的父包装器。
然后您只需将动画设置为在等于过渡持续时间的延迟后触发:
btn.onclick = e => {
// in order to have two directions, we need to be a bit verbose in here...
const test = document.querySelector('.test');
const classList = test.classList;
const state = classList.contains('zoomed-in');
// first remove previous
classList.remove('zoomed-' + (state ? 'in' : 'out'));
// force reflow
test.offsetWidth;
// set new one
classList.add('zoomed-' + (state ? 'out' : 'in'));
};
div.test {
position: relative;
display: inline-block;
margin: 50px 50px;
}
div.test div{
width: 100%;
height: 100%;
transition: transform 1s;
}
div.test.zoomed-in .scaler {
transform: scale(2);
}
div.test.zoomed-in .bouncer,
div.test.zoomed-out .bouncer {
animation: bounce .25s 1s;/* transition's duration delay */
}
div.test .inner {
background-color: blue;
width: 50px;
height: 50px;
}
@keyframes bounce {
0% {
transform: scale(1.15);
}
33% {
transform: scale(0.9);
}
66% {
transform: scale(1.1);
}
100% {
transform: scale(1.0);
}
}
<div class="test">
<div class="scaler">
<div class="bouncer">
<div class="inner"></div>
</div>
</div>
</div>
<button id="btn">toggle zoom</button>
让对象缩放然后在返回原始缩放因子之前以该缩放因子执行反弹动画的最佳方法是什么。我意识到我可以做一些事情,比如将它缩放到 2.2,然后是 1.8,然后是 2.0,但我正在寻找一种方法,你只需要在比例因子上执行反弹动画,因为我的比例因子会改变。
这是我的例子。基本上我想像我说的那样将两者结合起来工作,但正如您所看到的,弹跳动画根据缩放前的图像大小执行。
我需要图像的所有边都像示例一样反弹。
function myFunction() {
var image = document.getElementById('test');
image.style.WebkitTransform = ('scale(2,2)');
image.classList.remove('bounce');
image.offsetWidth = image.offsetWidth;
image.classList.add('bounce') ;
}
div#test {
position:relative;
display: block;
width: 50px;
height: 50px;
background-color: blue;
margin: 50px auto;
transition-duration: 1s;
}
.bounce {
animation: bounce 450ms;
animation-timing-function: linear;
}
@keyframes bounce{
25%{transform: scale(1.15);}
50%{transform: scale(0.9);}
75%{transform: scale(1.1);}
100%{transform: scale(1.0);}
}
<div id='test'> </div>
<button class = 'butt' onclick = 'myFunction()'>FIRST</button>
您可以尝试使用 CSS 变量来使比例因子在关键帧内动态变化:
function myFunction(id,s) {
var image = document.querySelectorAll('.test')[id];
image.style.setProperty("--s", s);
image.classList.remove('bounce');
image.offsetWidth = image.offsetWidth;
image.classList.add('bounce');
}
div.test {
display: inline-block;
width: 50px;
height: 50px;
background-color: blue;
margin: 50px;
transform:scale(var(--s,1));
}
.bounce {
animation: bounce 450ms;
animation-timing-function: linear;
}
@keyframes bounce {
25% {
transform: scale(calc(var(--s,1) + 0.2));
}
50% {
transform: scale(calc(var(--s,1) - 0.1));
}
75% {
transform: scale(calc(var(--s,1) + 0.1));
}
100% {
transform: scale(var(--s,1));
}
}
<div class='test'> </div>
<div class='test'> </div>
<div class='test'> </div>
<div>
<button class='butt' onclick='myFunction(0,"2")'>first</button>
<button class='butt' onclick='myFunction(1,"3")'>Second</button>
<button class='butt' onclick='myFunction(2,"0.5")'>third</button>
<button class='butt' onclick='myFunction(1,"1")'>second again</button>
</div>
在不同的包装元素上分派每个转换。
通过这种方式,您可以实现多个级别的转换,所有转换都相对于它们的父包装器。
然后您只需将动画设置为在等于过渡持续时间的延迟后触发:
btn.onclick = e => {
// in order to have two directions, we need to be a bit verbose in here...
const test = document.querySelector('.test');
const classList = test.classList;
const state = classList.contains('zoomed-in');
// first remove previous
classList.remove('zoomed-' + (state ? 'in' : 'out'));
// force reflow
test.offsetWidth;
// set new one
classList.add('zoomed-' + (state ? 'out' : 'in'));
};
div.test {
position: relative;
display: inline-block;
margin: 50px 50px;
}
div.test div{
width: 100%;
height: 100%;
transition: transform 1s;
}
div.test.zoomed-in .scaler {
transform: scale(2);
}
div.test.zoomed-in .bouncer,
div.test.zoomed-out .bouncer {
animation: bounce .25s 1s;/* transition's duration delay */
}
div.test .inner {
background-color: blue;
width: 50px;
height: 50px;
}
@keyframes bounce {
0% {
transform: scale(1.15);
}
33% {
transform: scale(0.9);
}
66% {
transform: scale(1.1);
}
100% {
transform: scale(1.0);
}
}
<div class="test">
<div class="scaler">
<div class="bouncer">
<div class="inner"></div>
</div>
</div>
</div>
<button id="btn">toggle zoom</button>