无限单个 div 动画
Posted
技术标签:
【中文标题】无限单个 div 动画【英文标题】:Infinite individual div animation 【发布时间】:2020-10-07 01:07:47 【问题描述】:我想为我的缩略图 div 的移动行为设置动画。我希望每个单独的 div 以不同的方式移动。网格本身也可以在两个方向上无限滚动。目前我有以下问题:
div 全部移到页面左侧 动画有时会停止 有时网格在第一次初始滚动时会闪烁您可以在这支笔中看到结果: https://codepen.io/Dennisade/pen/OJymaKZ
这就是我设置 css 的方式:
CSS:
.grid-image
text-align: center;
width: 50%;
margin-bottom: 18%;
pointer-events: none;
will-change: transform;
transition: 20s linear
JS
//MOVING ANIMATION
setInterval(function()
$('.grid-image').each(function(index)
var yAxis= index * Math.floor(Math.random()-2);
var xAxis= index * Math.floor(Math.random()-1);
$('.grid-image').css('transform', 'matrix(1, 0, 0, 1, ' + yAxis + ',' + xAxis + ')');
);
, 50);
//ENDLESS SCROLL
var origDocHeight = document.body.offsetHeight;
var clone = $(".wrapper").contents().clone();
clone.appendTo(".wrapper");
clone.prependTo(".wrapper");
$(document).scroll(function()
var scrollWindowPos = $(document).scrollTop();
if(scrollWindowPos >= origDocHeight )
$(document).scrollTop(0);
if(scrollWindowPos <= 0 )
$(document).scrollTop(origDocHeight);
);
【问题讨论】:
【参考方案1】:这里似乎有两个独立的部分。首先,div 没有正确移动,然后它们完全停止移动。其次,滚动无法正常工作。
先看div的运动:
我不熟悉 jquery,但您的问题之一似乎是这一行
$('.grid-image').css('transform', 'matrix(1, 0, 0, 1, ' + yAxis + ',' + xAxis + ')');
不会更新当前元素的转换设置,但会更改 grid-image 类的所有元素的 CSS。为确保每个 div 获得其新矩阵,您可以将上面的行更改为
this.style.transform='matrix(1, 0, 0, 1, ' + yAxis + ',' + xAxis + ')';//incidentally did you want the x and y this way round?
另一个问题是除第一个 div 之外的所有 div 仍将在其变换矩阵中以相同的 xAxis 和 yAxis 结束。这是因为 Math.floor(Math.random()) 等价于 Math.floor(Math.random()*1) 给出一个从 0(包括)到 1(不包括)的随机整数,所以它总是 0。根据您希望这些值有多大,您可以使用更高的整数。例如,Math.floor(Math.random()*10) 给出一个从 0 到 9 的随机整数。
我不知道你是否有意这样做,但第一个 div 永远不会改变它的变换,因为它的索引是 0,所以这些行总是设置 xAxis 和 yAxis = 0
var yAxis= index * Math.floor(Math.random()-2);
var xAxis= index * Math.floor(Math.random()-1);
例如,将 1 添加到索引将确保第一个 div 获得新值。
现在更仔细地查看坐标轴的计算,CSS 变换矩阵将其最后两个参数解释为 translateX 和 translateY。这些是相对于元素的当前位置的。在原始值中,这些值始终为负数,因此所有元素逐渐向左移动并(随着增量较小而不太明显)向上移动。
使用您的 Codepen,我的笔记本电脑变得非常热,风扇变得疯狂 - 每秒 20 次对这么多元素进行矩阵变换需要进行大量计算。我试图通过注意到您没有缩放或倾斜元素来缓解这种情况,因此可以使用平移变换而不是矩阵变换。
如果我们将 setInterval 调用替换为
setInterval(function()
$('.grid-image').each(function(index)
var yAxis= (index+1) * Math.floor(Math.random()*1000) * (Math.random() < 0.5 ? -1 : 1);
var xAxis= (index+1) * Math.floor(Math.random()*1000) * (Math.random() < 0.5 ? -1 : 1);
this.style.transform='translate('+xAxis+'px,'+yAxis+'px)';
);
, 50);
我们得到所有 div 的随机运动。当然,运动量取决于时间间隔和 x 和 y 增量的计算,我这里有 *1000 以获得一些容易看到的运动。如果您希望元素在屏幕上移动更多,它需要更多。我在计算中保留了索引,但我不确定这是否是您想要的 - 向下移动的元素比顶部的移动更多,然后当您滚动时,您会再次发现较慢的元素(所以整体效果是一种模式的暗示,而不是完全的随机性)。 使用此代码我还没有看到动画停止 - 并且已经运行了很多分钟。笔记本电脑变热了,但不是那么热。我想可能存在一个问题,即功能较弱的处理器是否可以在时间间隔内完成所有矩阵变换。如果这被证明是一个问题,那么迁移到 setTimeout 会有所帮助,任何鼓励使用 GPU 的 CSS 更改也会有所帮助。
希望这对您的前两点有所帮助。
现在来看看滚动。这段代码
var clone = $(".wrapper").contents().clone();
clone.appendTo(".wrapper");
clone.prependTo(".wrapper");
仅将内容 div 的一份副本放入 .wrapper div。我认为这是因为它被附加,然后被附加,这意味着它不再被附加,即它不能同时出现在两个地方。用此代码替换它会提供 3 个内容 div 副本,我猜您知道这足以满足您的代码将用于显示的大小
var clone = $(".wrapper").contents().clone();
var clone2 = $(".wrapper").contents().clone();
clone.appendTo(".wrapper");
clone2.prependTo(".wrapper");
现在可以向后滚动,但向前滚动有问题。在这段代码中
$(document).scroll(function()
var scrollWindowPos = $(document).scrollTop();
if(scrollWindowPos >= origDocHeight )
$(document).scrollTop(0);
if(scrollWindowPos <= 0 )
$(document).scrollTop(origDocHeight);
);
其中 scrollWindowPos >= origDocHeight 它滚动到 0,这意味着下次 scrollWindowPos
$(document).scroll(function()
var scrollWindowPos = $(document).scrollTop();
if(scrollWindowPos >= origDocHeight )
$(document).scrollTop(1); /* used to be 0 - using 1 is a bit hacky but it does the job */
else if(scrollWindowPos <= 0 )
$(document).scrollTop(origDocHeight);
);
它并不完美。通过抓住滚动条并将其向下移动来滚动会产生“闪烁”,但通过选择滚动条的向下箭头进行滚动可以平滑滚动,不会出现闪烁(Windows 10、Edge 和 Chrome)。目前我想不出如何进一步调查。
为了获得滚动条,我不得不在 Codepen 的 CSS 中删除 body 上的 display:none,所以我可能误解了你想要滚动的内容。
这是完整的 JS 代码,其中包含上述所有更改
//MOVING ANIMATION
setInterval(function()
$('.grid-image').each(function(index)
var yAxis= (index+1) * Math.floor(Math.random()*1000) * (Math.random() < 0.5 ? -1 : 1);
var xAxis= (index+1) * Math.floor(Math.random()*1000) * (Math.random() < 0.5 ? -1 : 1);
this.style.transform='translate('+xAxis+'px,'+yAxis+'px)';
);
, 50);
//ENDLESS SCROLL
var origDocHeight = document.body.offsetHeight;
var clone1 = $(".wrapper").contents().clone();
var clone = $(".wrapper").contents().clone();
clone.appendTo(".wrapper");
clone1.prependTo(".wrapper");
$(document).scroll(function()
var scrollWindowPos = $(document).scrollTop();
if(scrollWindowPos >= origDocHeight )
$(document).scrollTop(1);
else if(scrollWindowPos <=0 )
$(document).scrollTop(origDocHeight);
);
【讨论】:
以上是关于无限单个 div 动画的主要内容,如果未能解决你的问题,请参考以下文章