在缩放对象上反弹动画

时间:2019-01-20 23:23:42

标签: javascript html css css-animations css-transforms

具有对象比例并在返回原始比例因子之前以该比例因子执行弹跳动画的最佳方法是什么。我意识到我可以做一些事情,例如将其缩放到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>

2 个答案:

答案 0 :(得分:2)

您可以尝试使用CSS变量来使比例因子在关键帧内动态化:

env:
  browser: true
  es6: true
extends: 'airbnb-base/legacy'
parser: 'babel-eslint'
parserOptions:
  ecmaVersion: 2017
  sourceType: module
  experimentalObjectRestSpread: true
rules:
  indent:
    - error
    - 4
  linebreak-style:
    - error
    - unix
  quotes:
    - error
    - single
  semi:
    - error
    - always
  no-console:
    - off
  prefer-spread: "error"
  import/prefer-default-export: "error"
globals:
  CONFIG: false
  queryParams: false
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));
  }
}

答案 1 :(得分:1)

在不同的包装元素上分配每个变换。
这样,您就可以实现相对于其父包装器而言所有级别的转换。

然后,您只需将动画设置为在等于过渡持续时间的延迟后触发:

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>