使用Javascript触发和反转CSS转换

使用Javascript触发和反转CSS转换,javascript,html,css,animation,css-transitions,Javascript,Html,Css,Animation,Css Transitions,我目前正在探索将所有CSS转换减少为转换和不透明度(因为GPU加速)的可能性。它涉及直接使用Javascript操作样式。虽然触发这样的转变并不困难,但我发现自己无法逆转。通常,当您停止悬停时,CSS中定义的转换(例如悬停)会自动反转。但CSS不足以触发(和反转)点击转换。我希望能够做到以下几点: a) 单击某个项目(并通过CSS类切换等方式触发大小更改) b) 计算其初始大小和新大小之间的差异,并使用转换触发转换 c) 在更改其大小时再次单击它 d) 从单击时的位置反转过渡 我的问题是d)步骤

我目前正在探索将所有CSS转换减少为
转换
不透明度
(因为GPU加速)的可能性。它涉及直接使用Javascript操作样式。虽然触发这样的转变并不困难,但我发现自己无法逆转。通常,当您停止悬停时,CSS中定义的转换(例如悬停)会自动反转。但CSS不足以触发(和反转)点击转换。我希望能够做到以下几点:

a) 单击某个项目(并通过CSS类切换等方式触发大小更改)
b) 计算其初始大小和新大小之间的差异,并使用
转换触发
转换

c) 在更改其大小时再次单击它
d) 从单击时的位置反转过渡

我的问题是d)步骤。由于某种原因,图元突然将其大小更改为既不是旧尺寸也不是新尺寸,而是完全不同的尺寸。我举了一个我在这里尝试做的例子:

单击一个正方形,然后在它放大时再次单击它


有没有可靠的方法来正确地完成我想做的事情?有好的替代方案吗?

我相信这就是你想要的。另外,在我看来,您似乎还不完全理解
requestAnimationFrame
。它取代了一种技术,该技术涉及递归调用
setInterval
,每隔几毫秒更改一个元素的CSS属性(请参阅更多)。因此,我建议先阅读更多关于
requestAnimationFrame
的内容

我想指出的是,下面的动画可以更容易地使用CSS转换。此外,MDN提到两者的性能或多或少都相似(read)。不过,这里有一个简单的工作示例,可以说明您想要什么:

let clicked=false;
let square=document.querySelector(“.small sq”);
让我们展开
让我收回
square.style.transformOrigin='左上'
square.style.transform='scale(1)'
square.addEventListener('click',e=>{
let timeStart=new Date()
让currentScale=parseFloat(square.style.transform.slice(6,-1))
如果(!单击){
取消动画帧(收回ID)
expandID=requestAnimationFrame(()=>重复(timeStart、currentScale、单击))
}
否则{
取消动画帧(expandID)
retractID=requestAnimationFrame(()=>重复(timeStart、currentScale、单击))
}
点击=!点击
})
功能重复(timeStart、currentScale、status){
让时间差=新日期()-timeStart
如果(状态){
让scaleValue=currentScale+(1*时差/5000)>2?2:currentScale+(1*时差/5000)
square.style.transform=`scale(${scaleValue})`
expandID=requestAnimationFrame(()=>repeat(timeStart,scaleValue,status))
如果(比例值>=2)
取消动画帧(expandID)
}
否则{
设scaleValue=currentScale-(1*时差/5000)<1?1:currentScale-(1*时差/5000)
square.style.transform=`scale(${scaleValue})`
retractID=requestAnimationFrame(()=>repeat(timeStart,scaleValue,status))

如果(scaleValue我已经找到了一个有效的解决方案(它导入了
rematrix
库,使变换矩阵的计算更容易)。这个解决方案和Richard的简单解决方案都能够以60fps的速度进行动画-我想区别在于每种方法可以处理的案例数量


感谢您提供详细的回答。我了解性能,我认为您的第二个示例可以在很多情况下使用。但在某些情况下,这还不够(为DOM位置更改设置动画,例如列表混乱或共享元素转换)。