【问题标题】:Manipulate css animated position of element with JS用JS操作元素的css动画位置
【发布时间】:2021-11-11 05:01:49
【问题描述】:

我正在尝试更改一个元素的位置,该元素在 x 轴上通过 css 动画移动。目标是通过单击鼠标水平移动元素。之后动画当然应该继续定期运行。

重要:只是原生 js。

有什么提示吗?

基本示例

    <style>
    .dummyAnimation{width:100%;position:relative;height:100px;}
    .bump{width:100px;height:100px;background:blue;animation:dummySequence 30s linear infinite;position:absolute;}
    .bump:hover{animation-play-state:paused;}
    @keyframes dummySequence{
        0%{left:0;}
        100%{left:calc(100% - 100px)}
    }
</style>

<div class="dummyAnimation">
    <div class="bump"></div>
</div>

【问题讨论】:

    标签: javascript css animation css-transitions


    【解决方案1】:

    在尝试了一堆东西之后,我想出了这个“hacky”的东西,在mousedown 上删除动画,在mouseup 上添加鼠标位置作为偏移边距,再次添加动画。

    let cube =  document.querySelector('.bump')
    
    document.addEventListener('mousedown', (e)=>{
        cube.classList.remove('animation')
    })
    
    document.addEventListener('mouseup', (e)=>{
        cube.style = `margin-left: ${e.x - 50}px;`
        cube.classList.add('animation')
    })
        .dummyAnimation{width:200px;position:relative;height:100px;}
        .bump{width:100px;height:100px;background:blue;position:absolute;}
        .bump:hover{animation-play-state:paused;}
        .animation{animation:dummySequence 30s linear infinite;}
        @keyframes dummySequence{
            0%{left:0;}
            100%{left:100%}
        }
    <div class="dummyAnimation">
        <div class="bump animation"></div>
    </div>

    理想情况下,您希望获取鼠标位置并修改keyframes 规则left,因此动画从您单击的位置重新开始,但据我所知,没有简单的方法可以修改它。我想你可以在 js 中保留样式的副本,用修改后的值或类似的东西替换整个 &lt;style&gt; 标签,但这似乎比这更“hackier”。

    编辑 - 这使得动画从鼠标点击的点恢复到 100%,您可以添加检查以查看鼠标的位置是否超过容器宽度,因此立方体没有在它之外获得位置,或者将事件附加到容器本身。

    window.addEventListener('load', ()=>{
    
        let cube =  document.querySelector('.bump')
        let styleTag = document.getElementsByTagName('style')[0]
        let initialStyle = styleTag.textContent
        
        let initialKeyFrame = " .animation{animation:dummySequence 3s linear infinite;display:block} @keyframes dummySequence{ 0%{left:0;}100%{left:calc(100% - 100px)}}"
        styleTag.textContent = styleTag.textContent += initialKeyFrame
        
        document.addEventListener('mousedown', (e)=>{
        cube.classList.remove('animation')
        })
    
        document.addEventListener('mouseup', (e)=>{
        initialKeyFrame = ` .animation{animation:dummySequence 3s linear infinite; display:block} @keyframes dummySequence{ 0%{left:${e.x-50}px;}100%{left:calc(100% - 100px)}}`
        styleTag.textContent = initialStyle
        styleTag.textContent = styleTag.textContent += initialKeyFrame
        cube.classList.add('animation')
        
        })
    
    })
        .dummyAnimation{width:400px;position:relative;height:100px;background:gray}
        .bump{width:100px;height:100px;background:blue;position:absolute;display:none}
        .bump:hover{animation-play-state:paused;}
    <div class="dummyAnimation">
        <div class="bump animation"></div>
    </div>

    编辑 2 - 现在动画从头开始重新开始,但我不得不删除 .bump:hover{animation-play-state:paused;},因为它会影响超时。

    window.addEventListener('load', ()=>{
    
        let cube =  document.querySelector('.bump')
        let styleTag = document.getElementsByTagName('style')[0]
        let initialStyle = styleTag.textContent
        
        let initialKeyFrame = " .animation{animation:dummySequence 3s linear infinite;display:block} @keyframes dummySequence{ 0%{left:0;}100%{left:calc(100% - 100px)}}"
        styleTag.textContent = styleTag.textContent += initialKeyFrame
        
        document.addEventListener('mousedown', (e)=>{
        cube.classList.remove('animation')
        })
    
        document.addEventListener('mouseup', (e)=>{
        initialKeyFrame = ` .animation{animation:dummySequence 3s linear infinite; display:block} @keyframes dummySequence{ 0%{left:${e.x-50}px;}100%{left:calc(100% - 100px)}}`
        styleTag.textContent = initialStyle
        styleTag.textContent = styleTag.textContent += initialKeyFrame
        cube.classList.add('animation')
        setTimeout(()=>{
            cube.classList.remove('animation')
            initialKeyFrame = ` .animation{animation:dummySequence 3s linear infinite; display:block} @keyframes dummySequence{ 0%{left:0;}100%{left:calc(100% - 100px)}}`
            styleTag.textContent = initialStyle
            styleTag.textContent = styleTag.textContent += initialKeyFrame
            cube.classList.add('animation')
        }, 3000)
        })
    
    })
       .dummyAnimation{width:400px;position:relative;height:100px;background:gray}
        .bump{width:100px;height:100px;background:blue;position:absolute;display:none}
    /*     .bump:hover{animation-play-state:paused;} */
    <div class="dummyAnimation">
        <div class="bump animation"></div>
    </div>

    【讨论】:

    • 感谢您的回答。类似的事情也是我的第一个方法。但是,通过这种方式,整个区域会发生变化,动画本身会继续,但位置不再正确。例如,如果我在动画期间将框向右拖动,它会继续将拖动的长度向右移动到边缘上方。当然,我希望动画在右边缘结束,而不是超出它。
    • @Viewer 我添加了另一种方法,这会更接近您正在寻找的结果吗?
    • 真的很接近 THX。但是如果你拖动元素并且这个“动画循环”结束了,它就会从被拖动的地方开始。如果能从 left:0 重新开始就好了。
    • @Viewer 现在怎么样? :)
    • @Viewer 啊,这会在多次点击时中断..,它需要去抖动什么的
    猜你喜欢
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    相关资源
    最近更新 更多