如何在不使用背景位置的情况下为线性渐变设置动画?

编程入门 行业动态 更新时间:2024-10-09 19:21:07
本文介绍了如何在不使用背景位置的情况下为线性渐变设置动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试创建内容加载器,但是背景动画出现性能问题.当屏幕上只有几个元素时,它很平滑,但是当存根元素数增加到20-30时,它会急剧降低fps.现在,我知道动画背景位置属性是个坏主意,最好对此使用转换.但是我该怎么办呢?我想保持无缝动画.渐变应相对于屏幕而不是容器.

I'm trying to create content loader but got a performance problem with background animation. It's smooth when there are only a few elements on the screen but dramatically drops fps while increasing stub elements count to 20-30. Now I know that animating background-position property is a bad idea and it is better to use transforms for this. but how can I do this? I'd like to keep seamless animation. Gradient should be relative to screen, not to container.

这是一些代码:

const cardsRoot = document.getElementById('cards') const addButton = document.getElementById('add') const card = document.getElementsByClassName('card')[0] let cardsCount = 1 addButton.addEventListener('click', () => { cardsRoot.innerHTML = '' cardsCount++ for (let i = 0; i < cardsCount; i++) { let cardClone = card.cloneNode(true) cardsRoot.appendChild(cardClone) } })

body { padding: 40px; } .card { display: flex; margin-top: 20px; } .stub { width: 300px; height: 12px; margin: 8px; border-radius: 8px; background: linear-gradient(to right, rgba(0, 0, 0, 0.04), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.04) 20%) fixed; animation: stub 1.3s linear infinite; margin-bottom: 8px; } .circle { width: 40px; height: 40px; margin-right: 12px; border-radius: 20px; } @keyframes stub { 0% { background-position: 0vw; } 100% { background-position: 100vw; } }

<button id="add"> ADD CARD </button> <div id="cards"> <div class="card"> <div> <div class="stub circle"></div> </div> <div> <div class="stub"></div> <div class="stub"></div> <div class="stub"></div> </div> </div> </div>

和演示: jsfiddle/3da4uzm2/57/

推荐答案

您可以在应用翻译的地方使用伪元素替换动画.诀窍是考虑使用固定元素替换 background-attachment:fixed ,然后使该元素的尺寸比屏幕大两倍,并从左向右平移.

You can replace the animation using pseudo element where you apply translation. The trick is to consider fixed element to replace background-attachment:fixed, then you make the element twice bigger as the screen and you translate it from left to right.

const cardsRoot = document.getElementById('cards') const addButton = document.getElementById('add') const card = document.getElementsByClassName('card')[0] let cardsCount = 1 addButton.addEventListener('click', () => { cardsRoot.innerHTML = '' cardsCount++ for (let i = 0; i < cardsCount; i++) { let cardClone = card.cloneNode(true) cardsRoot.appendChild(cardClone) } })

body { padding: 40px; } .card { display: inline-flex; margin-top: 20px; } .stub { width: 150px; height: 12px; margin: 8px; border-radius: 8px; margin-bottom: 8px; position:relative; z-index:0; /*overflow:hidden; this is no more working, using mask instead */ -webkit-mask:linear-gradient(#fff 0 0); /* OR clip-path:inset(0) */ } .stub:before { content:""; position:fixed; z-index:-1; top:0; right:0; width:200vw; bottom:0; background: linear-gradient(rgba(0, 0, 0, 0.04),rgba(0, 0, 0, 0.04)) left/50% 100%, linear-gradient(to right, rgba(0, 0, 0, 0.04), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.04) 20%) right/50% 100%; background-repeat:no-repeat; animation: stub 1.3s linear infinite; pointer-events:none; } .circle { width: 40px; height: 40px; margin-right: 12px; border-radius: 20px; } @keyframes stub { 0% { transform:translate(0); } 100% { transform:translate(50%); } }

<button id="add"> ADD CARD </button> <div id="cards"> <div class="card"> <div> <div class="stub circle"></div> </div> <div> <div class="stub"></div> <div class="stub"></div> <div class="stub"></div> </div> </div> <div class="card"> <div> <div class="stub circle"></div> </div> <div> <div class="stub"></div> <div class="stub"></div> <div class="stub"></div> </div> </div> </div>

为了更好地理解这里发生的事情,是一个简化版本,其中只有一个元素,我也更改了渐变颜色.

To better understand what is happening here is a simplified version with only one element where I also changed the gradient colors.

body:before { content:""; position:fixed; /*relative to the screen*/ z-index:-1; top:0; right:0; width:200vw; /*2x100vw*/ bottom:0; background: /*will cover the left area while sliding*/ linear-gradient(red,red) left/50% 100%, /*the red should be green*/ /*the main gradient*/ linear-gradient(to right, green, blue 10%, green 20%) right/50% 100%; background-repeat:no-repeat; animation: stub 3s linear infinite; } @keyframes stub { 0% { transform:translate(0); } 100% { transform:translate(50%); } /*50% will be 200vw/2 = 100vw*/ }

有关了解背景值背后的技巧的说明:将百分比值与线性梯度的背景位置一起使用

Related to understand the trick behind the background values: Using percentage values with background-position on a linear-gradient

更多推荐

如何在不使用背景位置的情况下为线性渐变设置动画?

本文发布于:2023-10-29 00:33:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1538210.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线性   情况下   背景   位置   动画

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!