滚动后在对象的旧位置触发的 mojs 动画
mojs animation firing at object's old location after scrolling
https://codepen.io/mprquinn/pen/OmOMrR/
credit: Mike Quinn
以下代码在鼠标悬停在 link 上时触发动画。据我了解代码,x 和 y 坐标应该在每次调用函数时更新位置,因为 getBoundingClientRect() 应该在文档滚动时更新坐标...
如果您将鼠标悬停在 link 上而不滚动页面,您会看到动画按预期围绕 link,但如果滚动文档,则动画会在 link。我注意到在控制台中滚动文档并调用 getBoundingClientRect() 时 X 和 Y 没有更新...
const links = document.querySelectorAll('a');
links.forEach(link => link.addEventListener('mouseenter', shootLines));
function shootLines(e) {
const itemDim = this.getBoundingClientRect(),
itemSize = {
x: itemDim.right - itemDim.left,
y: itemDim.bottom - itemDim.top,
},
shapes = ['line'],
colors = ['#2FB5F3',
'#FF0A47',
'#FF0AC2',
'#47FF0A'];
const chosenC = Math.floor(Math.random() * colors.length),
chosenS = Math.floor(Math.random() * shapes.length);
// create shape
const burst = new mojs.Burst({
left: itemDim.left + (itemSize.x/2),
top: itemDim.top + (itemSize.y/2),
radiusX: itemSize.x,
radiusY: itemSize.y,
count: 8,
children: {
shape: shapes[chosenS],
radius: 10,
scale: {0.8: 1},
fill: 'none',
points: 7,
stroke: colors[chosenC],
strokeDasharray: '100%',
strokeDashoffset: { '-100%' : '100%' },
duration: 450,
delay: 100,
easing: 'quad.out',
isShowEnd: false,
}
});
burst.play();
}
.container {
margin-top: 20%;
height: 110vh;
}
<div class="container"><a href="javascript:void(0);">test</a></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mo-js/0.288.2/mo.min.js"></script>
您只需为每个 link 元素定义一次突发。我修改了代码以迭代 links 并在 link 上定义突发。在函数的最后,我添加了一个事件侦听器来播放突发事件。
您遇到的问题是您使用的是 getBoundingClientRect,它给出了元素的视口坐标。默认情况下,突发在文档主体元素(文档坐标)之外运行。 link 元素的文档坐标在您滚动时永远不会改变,但视口坐标会改变。参考 here 以获得简单的解释。
这大部分与您的代码完全相同,只是添加了事件侦听器以在最后播放突发事件。我相信这也会更有效,因为它不会在每次鼠标进入元素时都创建一个新的 burst 实例。您 link 使用的代码笔效率非常低,因为它会在每次悬停 link 时在文档中创建新的突发元素,也会导致内存泄漏。
const links = document.querySelectorAll('a');
links.forEach(link => {
const itemDim = link.getBoundingClientRect(),
itemSize = {
x: itemDim.right - itemDim.left,
y: itemDim.bottom - itemDim.top,
},
shapes = ['line'],
colors = ['#2FB5F3',
'#FF0A47',
'#FF0AC2',
'#47FF0A'];
const chosenC = Math.floor(Math.random() * colors.length),
chosenS = Math.floor(Math.random() * shapes.length);
// create shape
const burst = new mojs.Burst({
left: itemDim.left + (itemSize.x/2),
top: itemDim.top + (itemSize.y/2),
radiusX: itemSize.x,
radiusY: itemSize.y,
count: 8,
children: {
shape: shapes[chosenS],
radius: 10,
scale: {0.8: 1},
fill: 'none',
points: 7,
stroke: colors[chosenC],
strokeDasharray: '100%',
strokeDashoffset: { '-100%' : '100%' },
duration: 450,
delay: 100,
easing: 'quad.out',
isShowEnd: false,
}
});
// Add the mouseenter listener to play the burst.
link.addEventListener('mouseenter', function () { burst.play(); });
});
.container {
margin-top: 20%;
height: 110vh;
}
<div class="container"><a href="javascript:void(0);">test</a></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mo-js/0.288.2/mo.min.js"></script>
https://codepen.io/mprquinn/pen/OmOMrR/
credit: Mike Quinn
以下代码在鼠标悬停在 link 上时触发动画。据我了解代码,x 和 y 坐标应该在每次调用函数时更新位置,因为 getBoundingClientRect() 应该在文档滚动时更新坐标...
如果您将鼠标悬停在 link 上而不滚动页面,您会看到动画按预期围绕 link,但如果滚动文档,则动画会在 link。我注意到在控制台中滚动文档并调用 getBoundingClientRect() 时 X 和 Y 没有更新...
const links = document.querySelectorAll('a');
links.forEach(link => link.addEventListener('mouseenter', shootLines));
function shootLines(e) {
const itemDim = this.getBoundingClientRect(),
itemSize = {
x: itemDim.right - itemDim.left,
y: itemDim.bottom - itemDim.top,
},
shapes = ['line'],
colors = ['#2FB5F3',
'#FF0A47',
'#FF0AC2',
'#47FF0A'];
const chosenC = Math.floor(Math.random() * colors.length),
chosenS = Math.floor(Math.random() * shapes.length);
// create shape
const burst = new mojs.Burst({
left: itemDim.left + (itemSize.x/2),
top: itemDim.top + (itemSize.y/2),
radiusX: itemSize.x,
radiusY: itemSize.y,
count: 8,
children: {
shape: shapes[chosenS],
radius: 10,
scale: {0.8: 1},
fill: 'none',
points: 7,
stroke: colors[chosenC],
strokeDasharray: '100%',
strokeDashoffset: { '-100%' : '100%' },
duration: 450,
delay: 100,
easing: 'quad.out',
isShowEnd: false,
}
});
burst.play();
}
.container {
margin-top: 20%;
height: 110vh;
}
<div class="container"><a href="javascript:void(0);">test</a></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mo-js/0.288.2/mo.min.js"></script>
您只需为每个 link 元素定义一次突发。我修改了代码以迭代 links 并在 link 上定义突发。在函数的最后,我添加了一个事件侦听器来播放突发事件。
您遇到的问题是您使用的是 getBoundingClientRect,它给出了元素的视口坐标。默认情况下,突发在文档主体元素(文档坐标)之外运行。 link 元素的文档坐标在您滚动时永远不会改变,但视口坐标会改变。参考 here 以获得简单的解释。
这大部分与您的代码完全相同,只是添加了事件侦听器以在最后播放突发事件。我相信这也会更有效,因为它不会在每次鼠标进入元素时都创建一个新的 burst 实例。您 link 使用的代码笔效率非常低,因为它会在每次悬停 link 时在文档中创建新的突发元素,也会导致内存泄漏。
const links = document.querySelectorAll('a');
links.forEach(link => {
const itemDim = link.getBoundingClientRect(),
itemSize = {
x: itemDim.right - itemDim.left,
y: itemDim.bottom - itemDim.top,
},
shapes = ['line'],
colors = ['#2FB5F3',
'#FF0A47',
'#FF0AC2',
'#47FF0A'];
const chosenC = Math.floor(Math.random() * colors.length),
chosenS = Math.floor(Math.random() * shapes.length);
// create shape
const burst = new mojs.Burst({
left: itemDim.left + (itemSize.x/2),
top: itemDim.top + (itemSize.y/2),
radiusX: itemSize.x,
radiusY: itemSize.y,
count: 8,
children: {
shape: shapes[chosenS],
radius: 10,
scale: {0.8: 1},
fill: 'none',
points: 7,
stroke: colors[chosenC],
strokeDasharray: '100%',
strokeDashoffset: { '-100%' : '100%' },
duration: 450,
delay: 100,
easing: 'quad.out',
isShowEnd: false,
}
});
// Add the mouseenter listener to play the burst.
link.addEventListener('mouseenter', function () { burst.play(); });
});
.container {
margin-top: 20%;
height: 110vh;
}
<div class="container"><a href="javascript:void(0);">test</a></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mo-js/0.288.2/mo.min.js"></script>