动画变换仅一个属性(比例)覆盖其他(翻译) [英] Animate transform only one property (scale) override other (translate)

查看:23
本文介绍了动画变换仅一个属性(比例)覆盖其他(翻译)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是 transform 属性的值有多个部分,如 translatescale 等.

这是一个关于元素的理论问题,让 .loader 具有 transform:translate(10px, 10px) 并且在动画中我想为 设置动画scale 属性.在这种情况下,浏览器不会采用 transform:translate(10px, 10px) 而只会采用 scale.

我正在寻找解决此问题的方法.

这是这个问题的一个例子.请注意,我不是在寻找这个特定示例的答案(例如:包装元素或将 translate 值添加到动画定义中),而是通用解决方案(如果存在,当然).

.loading {位置:相对;宽度:100px;高度:100px;背景:#eee;}.加载:之前,.loading:after {内容: "";宽度:50%;高度:50%;-moz-border-radius: 50%;-webkit-border-radius: 50%;边界半径:50%;背景色:#fff;不透明度:0.6;位置:绝对;顶部:0;左:0;/* 浏览器不接受这个 */变换:翻译(100px,300px);-webkit-animation:弹跳 2 秒无限缓入;动画:弹跳 2 秒无限缓入;}.loading:after {-webkit-animation-delay: -1s;动画延迟:-1s;}@关键帧反弹{0%, 100% {变换:比例(0);-webkit-transform: scale(0);}50%{变换:比例(1);-webkit-transform: scale(1);}}

<div class="loading"></div>

解决方案

通常,当您添加 animation 并更改 transform 属性时,在基础元素也应该保留在动画的关键帧中.也就是说,新的转换(动画的一部分)应该添加到现有的 transform 之上,而不是覆盖它.下面是它应该如何完成.

.loading {位置:相对;宽度:200px;高度:200px;背景:#eee;}.加载:之前,.loading:after {内容: "";宽度:50%;高度:50%;边界半径:50%;背景色:#fff;不透明度:0.6;位置:绝对;顶部:0;左:0;变换:翻译(100px,300px);动画:弹跳 2 秒无限缓入;}.loading:after {动画延迟:-1s;}@keyframes 反弹 {0%, 100% {变换:缩放(0)平移(100px,300px);}50%{变换:缩放(1)平移(100px,300px);}}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script><div class="loading"></div>

我写了一个类似的答案 here 关于在元素上添加多个动画的问题,其中每个动画修改 transform 属性的值独立于其他.我把它链接到这里仅供参考,不要认为它们是重复的.

<小时>

综上所述,当您尝试创建动画库或尝试将每个动画拆分为单独的类时,将原始变换添加到每个动画的 kefyrames 是不可能的.例如,您想将相同的 bounce 动画添加到多个元素,并且每个元素都有不同的初始 transform 设置,然后就不可能将其添加到动画的关键帧.

在这种情况下,您仍然可以使用 CSS 实现所需的输出,但使用单个元素完成它会非常困难(在我看来几乎是不可能的).

您有哪些选择?嗯,一种选择是让您在包装元素上添加动画.

.loading-wrapper {位置:相对;宽度:200px;高度:200px;背景:#eee;}.loading-before, .loading-after {位置:绝对;宽度:50%;高度:50%;顶部:0px;左:0px;动画:弹跳 2 秒无限缓入;}.loading-before:before,.loading-after:before {内容: "";宽度:100%;高度:100%;边界半径:50%;背景色:#fff;不透明度:0.6;位置:绝对;顶部:0;左:0;变换:翻译(100px,300px);}.loading-after {动画延迟:-1s;}@关键帧反弹{0%, 100% {变换:比例(0);}50%{变换:比例(1);}}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script><div class="loading-wrapper"><div class="loading-before"></div><div class="loading-after"></div>

<小时>

该解决方案非常通用,您几乎可以将其应用于所有此类情况.缺点是,如果您想堆叠多个这样的转换,那么您最终可能会得到多个这样的包装器.除了在动画的关键帧中添加原始转换之外,没有纯 CSS 方法.

下面的代码片段是另一个示例.

.move-n-scale {位置:相对;高度:100px;宽度:100px;背景:沙棕色;边框:1px纯巧克力;变换:比例(0.5);动画:移动 1s 线性无限交替反转;}.移动 {位置:相对;显示:内联块;动画:仅移动 1 秒线性无限交替反向;}.规模 {位置:绝对;高度:100px;宽度:100px;顶部:0px;左:0px;背景:沙棕色;边框:1px纯巧克力;变换:比例(0.5);}@关键帧移动{从 {变换:translateX(0px)比例(0.5);}到 {变换:translateX(300px)比例(0.5);}}@keyframes 只移动 {从 {变换:translateX(0px);}到 {变换:translateX(300px);}}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script><div class='move-n-scale'></div><div class='move'><div class='scale'></div>

<块引用>

注意: 只是为了澄清,我确实注意到您提到过不想要一个非常针对此问题的解决方案,例如包装等.但是,我仍然将此解决方案添加为回答,因为它是我所知道的唯一通用解决方案.我添加了第二个片段只是为了表明它确实是通用的.

The problem is that the transform property's value has multiple part like translate, scale etc.

This is a theoretical question about element, let's .loader that has transform:translate(10px, 10px) and in the animation I want to animate the scale property. In this case, the browser will not take the transform:translate(10px, 10px) and will take only the scale.

I am looking for a way around this problem.

Here is an example to this question. Please, keep attention that I'm not looking for an answer to this particular example (like: wrap the element or add the translate value to the animation definition) but a generic solution (if exist, of course).

.loading {
  position: relative;
  width: 100px;
  height: 100px;
  background: #eee;
}
.loading:before,
.loading:after {
  content: "";
  width: 50%;
  height: 50%;
  -moz-border-radius: 50%;
  -webkit-border-radius: 50%;
  border-radius: 50%;
  background-color: #fff;
  opacity: 0.6;
  position: absolute;
  top: 0;
  left: 0;
  /* the broswer doesn't take this */
  transform: translate(100px, 300px);
  -webkit-animation: bounce 2s infinite ease-in-out;
  animation: bounce 2s infinite ease-in-out;
}
.loading:after {
  -webkit-animation-delay: -1s;
  animation-delay: -1s;
}
@keyframes bounce {
  0%, 100% {
    transform: scale(0);
    -webkit-transform: scale(0);
  }
  50% {
    transform: scale(1);
    -webkit-transform: scale(1);
  }
}

<div class="loading"></div>

解决方案

Generally when you add an animation with changes to the transform property then the transforms that are specified in the base element should also be carried over to be present within the animation's keyframes also. That is, the new transforms (that are part of the animation) should be added over on top of the existing transform and not overwrite it. Below is how it should be done.

.loading {
  position: relative;
  width: 200px;
  height: 200px;
  background: #eee;
}
.loading:before,
.loading:after {
  content: "";
  width: 50%;
  height: 50%;
  border-radius: 50%;
  background-color: #fff;
  opacity: 0.6;
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(100px, 300px);
  animation: bounce 2s infinite ease-in-out;
}
.loading:after {
  animation-delay: -1s;
}
@keyframes bounce {
  0%, 100% {
    transform: scale(0) translate(100px, 300px);
  }
  50% {
    transform: scale(1) translate(100px, 300px);
  }
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="loading"></div>

I wrote a similar answer here to a question about adding multiple animations on an element with each of those animations modifying the transform property's values independent of the other. I am linking it here only for reference and don't think they are duplicates.


Having said the above, adding the the original transform to each animation's kefyrames is not possible when you are trying to create animation libraries or trying to split each animation into a separate class. Say for example, you want to add the same bounce animation to multiple elements and each of them have a different initial transform setting then it becomes impossible to add it to animation's keyframe.

In such cases, you can still achieve the desired output using CSS but it would be very difficult (almost impossible in my opinion) to get it done with a single element.

What options do you have? Well, one option is for you to add the animation on a wrapper element.

.loading-wrapper {
  position: relative;
  width: 200px;
  height: 200px;
  background: #eee;
}
.loading-before, .loading-after {
  position: absolute;
  width: 50%;
  height: 50%;
  top: 0px;
  left: 0px;
  animation: bounce 2s infinite ease-in-out;
}
.loading-before:before,.loading-after:before {
  content: "";
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #fff;
  opacity: 0.6;
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(100px, 300px);
}
.loading-after {
  animation-delay: -1s;
}
@keyframes bounce {
  0%, 100% {
    transform: scale(0);
  }
  50% {
    transform: scale(1);
  }
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="loading-wrapper">
  <div class="loading-before"></div>
  <div class="loading-after"></div>
</div>


The solution is quite generic and you can apply it to almost all such cases. The drawback is that if you want to stack multiple such transformations then you'd likely end up with multiple such wrappers. There is no pure CSS way other than adding original transformations within the animation's keyframes also.

The below snippet is another sample.

.move-n-scale {
  position: relative;
  height: 100px;
  width: 100px;
  background: sandybrown;
  border: 1px solid chocolate;
  transform: scale(0.5);
  animation: move 1s linear infinite alternate-reverse;
}
.move {
  position: relative;
  display: inline-block;
  animation: move-only 1s linear infinite alternate-reverse;
}
.scale {
  position: absolute;
  height: 100px;
  width: 100px;
  top: 0px;
  left: 0px;
  background: sandybrown;
  border: 1px solid chocolate;
  transform: scale(0.5);
}
@keyframes move {
  from {
    transform: translateX(0px) scale(0.5);
  }
  to {
    transform: translateX(300px) scale(0.5);
  }
}
@keyframes move-only {
  from {
    transform: translateX(0px);
  }
  to {
    transform: translateX(300px);
  }
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='move-n-scale'></div>
<div class='move'>
  <div class='scale'></div>
</div>

Note: Just to clarify, I did notice that you had mentioned about not wanting a solution which is very specific to this problem like wrap it etc. But, I had still added this solution as an answer because it is the only generic solution which I am aware of. I had added the second snippet only to show that is is indeed generic.

这篇关于动画变换仅一个属性(比例)覆盖其他(翻译)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆