如何将CSS翻译添加到现有翻译中?

4

我正在使用CSS translate在屏幕上放置一个DIV元素。这个方法很好用,但是当相同的元素稍后被移位时,原始的偏移量就会被丢弃。

通过JavaScript设置CSS起始位置

div.style.transform ="translate(800px, 400px)";

使用JavaScript随机设置起始位置后,CSS动画会将其重置回原始位置。
CSS动画
@keyframes testanimation {
  0% {
    transform: translateY(20px);
  }

  100% {
    transform: translateY(80px);
  }
}

我该如何结合CSS变换,以考虑之前的位移?在这种情况下,目标是从随机位置开始动画。20px - 80px 应该是相对的。


把你的元素放在另一个 div 里面!并在这个 div 上设置动画! - ibrahim mahrir
那可能是最好的解决方案了?你能把它发表为一个答案吗? - Kokodoko
我已经发布了一个例子。 - ibrahim mahrir
4个回答

2

我猜最好的方法是获取先前的变换,将一些值添加到这些值中,然后应用新的变换。

另一个建议是使用positionlefttop设置元素的位置。例如,可以使用以下代码:

div.style.position = "absolute";
div.style.left = "800px";
div.style.top = "400px";

那样,转换就会应用于该位置,而不是相对于您先前的转换。

谢谢,使用位置左上角可以解决这个具体问题!尽管我更喜欢以某种方式使用相对的CSS变换。 - Kokodoko

0

我上面评论的一个例子:

#wrapperDiv {
  width: 100px;
  height: 100px;
  background: green;

  transform: translate(400px, 200px) rotate(50deg);
}

#yourDiv {
  width: 100px;
  height: 100px;
  background: red;
  
  animation: testanimation 2s infinite;
}

@keyframes testanimation {
  0% {
    transform: translateY(20px) rotate(0deg);
  }

  100% {
    transform: translateY(80px) rotate(40deg);
  }
}
<div id="wrapperDiv">
  <div id="yourDiv">
  <div>
<div>

div#yourDiv将相对于其父元素div#wrapperDiv进行变换。


0
如果只是关于转换,那么您需要重置动画中的每个值,否则它将被动画规则覆盖。
例如:

div {/* translate value reduced to fit in snippet window */
  border:solid;
  height:40px;
  width:40px;
  transform:translatex(180px) translatey(140px);
  animation:2s testanimation forwards;
}
@keyframes testanimation {
  0% {
    transform:translatex(180px) translatey(150px)
  }

  100% {
    transform:translatex(180px) translatey(180px)
  }
}
<div></div>

你应该应用于开始宽度的样式为:

div.style.transform ="translatex(800px) translatey(400px)";

还有动画:

@keyframes testanimation {
  0% {
    transform:translatex(800px) translatey(420px)
  }

  100% {
    transform:translatex(800px) translatey(480px)
  }
}

为了仅更新translatey的值

translate或position:relative +坐标具有相同的效果/结果。

您还可以将它们结合使用

div {/* value reduced to fit window's demo */
  border:solid;
  height:40px;
  width:40px;
  position:relative;
  transform:translate(80px,40px);
  animation:2s testanimation forwards;
}
@keyframes testanimation {
  0% {
    top : 20px
  }

  100% {
    top:40px
  }
}
<div></div>

反过来也可以:

div {
  /* value reduced to fit window's demo */
  border: solid;
  height: 40px;
  width: 40px;
  position: relative;
  left: 80px;
  top: 40px;
  animation: 2s testanimation forwards;
}

@keyframes testanimation {
  0% {
    transform: translatey(20px)
  }
  100% {
    transform: translatey(40px)
  }
}
<div></div>


是的,但重点是我用JavaScript动态初始化起始值,然后CSS样式表再次重置这些值。 - Kokodoko
@Kokodoko 我理解了,通过js重置坐标并让transform完成它的工作,CSS无法捕获和添加早期值,而js可以。你的方法需要重新考虑。父级和子级要分发js值和css动画,或者一起使用相对和变换来避免值被重置。 - G-Cyrillus
@Kokodoko position:relative + transform也可以。如果更新js麻烦,可以在动画中设置相对坐标而不是使用transform。您可以跳过那个额外的包装器 :) - G-Cyrillus

-1

我认为一个更通用的解决方案是解析CSS transform属性,因为这样可以让你继续对元素进行动画处理,而不必担心其状态。

这是我在这种情况下使用的解决方案:

parseTransformMatrix = function(str){
  const match_float = "[+\\-]?(?:0|[1-9]\\d*)(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?"
  const match_sep = "\\s*,?\\s*"
  m = str.match(RegExp(`matrix\\((${match_float}(?:${match_sep}${match_float})*)\\)`))
  if(!m || !m.length || m.length < 2) return null
  return m[1].match(RegExp(match_float, 'g')).map(x => parseFloat(x))
}
// Test parseTransformMatrix method
console.log(parseTransformMatrix("matrix(1, 0, 0, 1, 96.2351, 309.123)"));

getElementTranslate = function(e){
  let t = e.css("transform")
  let r = { left: 0, top: 0 }
  if(!t) return r
  mat = parseTransformMatrix(t)
  if(!mat || !mat.length || mat.length != 6) return r
  r.left = mat[4]
  r.top = mat[5]
  return r
}

这里,e 是一个jQuery元素,但是如果你不想要这个依赖,你可以轻松地使用getPropertyValue代替它。
使用这些函数,你可以做像这样的事情:
let t = getElementTranslate(e)
e.css({transform:`translate(${t.left+20}px,${t.top+80}px)`})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接