我有一个jQuery函数更改了background-position
上三个元素的mousemove
属性,这似乎导致了一些性能问题。
应该注意的是,这些元素的背景图像是SVG。
示例代码:
$(window).on('mousemove', function(event) {
window.requestAnimationFrame(function() {
$banner.find('.pattern').each(function(key) {
var modifier = 20 * (key + 1);
$(this).css({
'background-position': (event.pageX / modifier)+'px '+(event.pageY / modifier)+'px'
});
});
});
});
请在此处查看我的工作代码:https://codepen.io/thelevicole/project/full/DarVMY/
我正在使用window.requestAnimationFrame()
,并且每个元素上都有will-change: background-position;
css属性。
你可能会说,这种影响是滞后的。在更大的窗户尺寸上似乎会变得更糟。
我很确定这个问题是由于使用SVG代替PNG而导致的。我使用SVG的原因是因为高像素密度屏幕。
如果有人能够提供一些有关我如何在不使用非常棒的PNG的情况下改进FPS的见解。感谢。
答案 0 :(得分:1)
成功。我的解决方案是一系列建议。
我现在正在更改每个元素的transform属性,但在执行此操作时遇到了另一个问题。我在这些相同的元素上有一个变换关键帧动画,并且忽略了JS应用的样式。
为了解决这个问题,我嵌套了关键帧动画元素,并使用JS来转换父元素。
我已应用@CristianTraìna的建议将window.requestAnimationFrame()
移到mousemove
您可以在我的原始链接上看到更新:https://codepen.io/thelevicole/project/full/DarVMY/
可悲的是,CodePen不允许对项目进行版本控制。
最终工作代码
(function($) {
'use strict';
var $banner = $('section.interactive');
if ($banner.length) {
var $patterns = $banner.find('.pattern');
var x = 0,
y = 0;
// Bind animation to cursor
$(window).on('mousemove', function(event) {
x = event.pageX;
y = event.pageY;
});
/**
* Tell the browser that we wish to perform an animation
* @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
*/
window.requestAnimationFrame(function animation() {
// Loop each pattern layer
$patterns.each(function(key) {
// Modify the x,y coords per element to give "depth"
var modifier = 20 * (key + 1);
// Move background position
$(this).css({
'transform': 'translate('+(x / modifier)+'px, '+(y / modifier)+'px)'
});
});
window.requestAnimationFrame(animation);
});
}
})(jQuery);
section.interactive {
position: relative;
height: 100vh;
background-image: linear-gradient(45deg, #6ac8ea 0%, #5de2c1 100%);
}
section.interactive .layers {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.15) 0%, transparent 40%, transparent 60%, rgba(0, 0, 0, 0.1) 100%);
}
section.interactive .layers .pattern {
position: absolute;
top: -10px;
left: -10px;
bottom: -10px;
right: -10px;
background-position: top left;
will-change: background-position;
background-size: 1000px 1000px;
}
section.interactive .layers .pattern .inner {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
section.interactive .layers .pattern.pattern-1 .inner {
background-image: url("http://www.inrialpes.fr/sed/people/boissieux/VEAD/out_Stars.svg");
filter: blur(2px);
opacity: 0.3;
z-index: 1;
animation: Floating 10s infinite;
animation-delay: 2s;
background-size: 800px 800px;
}
section.interactive .layers .pattern.pattern-2 .inner {
background-image: url("http://www.inrialpes.fr/sed/people/boissieux/VEAD/out_Stars.svg");
filter: blur(1px);
opacity: 0.4;
z-index: 2;
animation: Floating 10s infinite;
animation-delay: 1s;
background-size: 900px 900px;
}
section.interactive .layers .pattern.pattern-3 .inner {
background-image: url("http://www.inrialpes.fr/sed/people/boissieux/VEAD/out_Stars.svg");
opacity: 0.4;
z-index: 3;
animation: Floating 10s infinite;
background-size: 1000px 1000px;
}
@keyframes Floating {
0% {
transform: translate(-10px, 10px);
}
50% {
transform: translate(10px, -10px);
}
100% {
transform: translate(-10px, 10px);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Animation performance</title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
<link rel="stylesheet" href="styles.processed.css">
</head>
<body>
<section class="interactive">
<div class="layers">
<div class="pattern pattern-3">
<div class="inner"></div>
</div>
<div class="pattern pattern-2">
<div class="inner"></div>
</div>
<div class="pattern pattern-1">
<div class="inner"></div>
</div>
</div>
</section>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</body>
</html>
答案 1 :(得分:0)
当您调用 on 方法时,您正在创建一个将侦听事件的异步函数,当此事件被触发时,您将创建另一个将侦听事件的异步函数。
然后,你正在做的是听一个事件( mousemove )并在第一个被触发时设置另一个事件( requestAnimationFrame ),但是如果mousemove是在短时间内激发两次,requestAnimationFrame仍然没有第一次执行其回调?
解决问题的更简洁方法是:
var x = 0;
var y = 0;
$patterns = $banner.find('.pattern');
$(window).on('mousemove', function(event) {
x = event.pageX;
y = event.pageY;
});
window.requestAnimationFrame(function moveBackground() {
$patterns.each(function(key) {
var modifier = 20 * (key + 1);
$(this).css({
'background-position': (x / modifier)+'px '+(y / modifier)+'px'
});
});
window.requestAnimationFrame(moveBackground);
});
你可以看到我的工作项目(没有JQuery)clicking here