【问题标题】:How to animate with relative transforms in css?如何在css中使用相对变换制作动画?
【发布时间】:2016-09-21 02:47:18
【问题描述】:

我有两个盒子:

<div class='item' style='transform:translateY(100px)'>
</div>

<div class='item' style='transform:translateY(300px)'>
</div>

他们都使用同一个类:

.item {
    position:absolute;
    background:red;
  animation:float 3s ease-in-out infinite;
  width:100px;
  height:100px;
}

动画长这样:

@keyframes float {
    from, to { transform: translateY(-10px); }
    50% { transform: translateY(10px); }
}

但这会使两个框都在 -10 到 10px 之间。我想要的是它与框的当前值相关。

所以 y:100px 处的 box1 会从 90px 动画到 110px y:300px 处的 box2 将从 290px 动画到 310px

是否可以在 css 中做到这一点?我宁愿每个盒子都没有特定的动画。因为我可能有几百个盒子。

jsfiddle: https://jsfiddle.net/foreyez/1n1en8uk/

这表明在动画点上,两个盒子都在同一个地方……但如果是相对动画,它们只会在当前位置上下浮动。

注意:请不要使用 top/left 来获取相对位置 我正在寻找相对 TRANSFORMS。 (如果您必须知道为什么我在 3d 中为 z 轴执行此操作,因为 x,y 已被使用)。

【问题讨论】:

  • from, to css 语法对于 @keyframes 是否有效?
  • 是的,否则它不会动画
  • 相对定位元素应该可以解决这个问题 -> jsfiddle.net/adeneo/1n1en8uk/2
  • 不,它没有,300 像素的 y 看起来与您的解决方案不同
  • 你是对的,所以我会坚持我原来的评论,样式被重置,它不会在原来的样式上增加 10px,这不是它的工作原理。跨度>

标签: javascript html css


【解决方案1】:

您可以将position.item 元素设置为relative;使用:nth-of-type() 伪选择器将每个元素的top 属性设置为初始位置,在该位置元素应该在20px 范围内相对于其.item 兄弟进行动画处理。

.item {
  position: relative;
  background: red;
  animation: float 3s infinite ease-in-out;
  width: 100px;
  height: 100px;
}
.item:nth-of-type(1) {
  top: 100px;
}
.item:nth-of-type(2) {
  top: 300px;
}
@keyframes float {
  from, to {
    transform: translateY(-10px);
  }
  50% {
    transform: translateY(10px);
  }
}
<div class="item">
</div>
<div class="item">
</div>

jsfiddle https://jsfiddle.net/1n1en8uk/3/

【讨论】:

  • 谢谢,我忘了补充我不能使用顶部或左侧。我实际上在 3 维中使用它,因此需要在 Z 变换上执行此操作,并且我所有的框都将值设置为 TranslateZ。所以这必须在 Z 中工作。但是,使用 top/left 来获得相对的 hack 是一个很好的方法。
  • 也可以代替第 n 个类型,只在 div 样式中设置顶部。
  • @foreyez “我忘了添加我不能使用 top 或 left。” 原始问题不包括不能使用 topleft 属性满足要求。
  • 是的,但在 90% 的情况下,您的解决方案都很棒。不幸的是,我正在寻找 z 轴动画。应该更清楚。
【解决方案2】:

这是一个令人讨厌的 javascript 解决方案(是的,我正在寻找一个 CSS 解决方案,这就是为什么我不会将其标记为答案的原因),它将动态关键帧注入页面:

我猜只要少于 100 个盒子就可以了。

https://jsfiddle.net/foreyez/6v7n4ro3/

function getTranslateY(obj)
{
 var transformMatrix = obj.css("-webkit-transform") ||
   obj.css("-moz-transform")    ||
   obj.css("-ms-transform")     ||
   obj.css("-o-transform")      ||
   obj.css("transform");
 var matrix = transformMatrix.replace(/[^0-9\-.,]/g, '').split(',');
 var x = matrix[12] || matrix[4];//translate x
 var y = matrix[13] || matrix[5];//translate y
  return parseInt(y);
}

function insertAnimation(idx, yy)
{
  var style1 = document.documentElement.appendChild(document.createElement("style")),
  rule1 = "@keyframes float" + idx + " {\
    from, to { transform: translateY("+ (yy-10) +"px); }\
    50% { transform: translateY(" + (yy+10) + "px); }\
  }";

  style1.sheet.insertRule(rule1, 0);
}

$(".item").each(function(idx) {

var currentTranslateY = getTranslateY($(this));
insertAnimation(idx, currentTranslateY);
  $(this).css('animation','float' + idx + ' 3s ease-in-out infinite');
});

【讨论】:

  • OP 的原始要求似乎是使用css? “如何在 css 中使用相对变换制作动画?” ?
  • "是的,但不幸的是没有办法。:( "你确定只使用css就“没有办法”吗?或者只是不使用css要求的一部分?
  • “目前还没有办法,但希望有人能来证明我错了。”嗯,有一种方法可以使用top,尽管排除了topleft 未在原始问题中描述。另外,原始问题是“如何在 css 中使用相对变换进行动画处理?”,而不是 cssjavascript?
  • 问题中包含javascript 标签。如果您认为您对问题的回答是最好的,您可以接受您自己的回答。见Can I answer my own question?
  • 如果您正在寻找css 解决方案,为什么要发布javascript 解决方案?描述引用css 解决方案的“没有办法”?这是您的问题,但如果实际要求是使用css,为什么还要邀请其他javascript 答案?这是一个很好的css 问题。
【解决方案3】:

注意:请不要使用顶部/左侧来获取我正在寻找的相对位置 专门用于相对 TRANSFORMS。

您可以将html 调整为单个.item 元素作为容器元素的子元素,其中transform 设置为translateY(100px)position 设置为absolute;在.item 元素上使用css :after 伪元素,并将transform 设置为translateY(200px)

.float {
  transform: translateY(100px);
  position: absolute;
}
.item {
  animation: float 3s infinite ease-in-out;
}
.item, .item:after {
  display: block;
  position: relative;
  background: red;
  width: 100px;
  height: 100px;
}
.item:after {
  content: "";
  transform: translateY(200px);
}
@keyframes float {
  from, to {
    transform: translateY(-10px);
  }
  50% {
    transform: translateY(10px);
  }
}
<div class="float">
  <div class="item">
  </div>
</div>

jsfiddle https://jsfiddle.net/1n1en8uk/5/

【讨论】:

    猜你喜欢
    • 2022-12-16
    • 1970-01-01
    • 2017-07-04
    • 2020-05-14
    • 2013-07-14
    • 2023-03-18
    • 2016-02-26
    • 1970-01-01
    • 2017-10-21
    相关资源
    最近更新 更多