Javascript 如何使用offset path CSS属性将SVG路径从其原始位置偏移
我有一堆SVG路径,它们是文本字母。在scroll上,我想从它们的原始位置开始沿Javascript 如何使用offset path CSS属性将SVG路径从其原始位置偏移,javascript,css,svg,intersection-observer,Javascript,Css,Svg,Intersection Observer,我有一堆SVG路径,它们是文本字母。在scroll上,我想从它们的原始位置开始沿偏移路径设置它们的动画。因此,我将0x和0y起始位置指定给偏移路径属性,然后将随机化行指定给偏移路径,我希望沿着该路径设置SVG字母的动画,如下所示: path.setAttribute("style", "offset-path: path('M" + 0 +" " + 0 + " L " + generateRandomAnimati
偏移路径设置它们的动画。因此,我将0x
和0y
起始位置指定给偏移路径
属性,然后将随机化行
指定给偏移路径
,我希望沿着该路径设置SVG字母的动画,如下所示:
path.setAttribute("style", "offset-path: path('M" + 0 +" " + 0 + " L " + generateRandomAnimationPathLine() + " " + generateRandomAnimationPathLine() + "')");
path.style.offsetDistance = element.intersectionRatio * 100 + "%";
但是,一旦我使用随机L
属性给出了所有SVG路径offset path
,它们就已经遍布了屏幕,并且offset distance
设置为0%
。为什么呢?如果偏移距离设置为0,它们不应该留在原点吗?为什么offset path:path()中的L
即使M
设置为0,也会将SVG从原点移动
您可以检查每个SVG字母并勾选偏移距离,以查看它们是否已超出原点。如何从SVG路径的原始位置开始设置其动画?我试图实现这样一种效果,当你滚动时,它会慢慢地破坏“你好,世界”,当你向上滚动时,它会回到原来的形式
用图片来解释我想要达到的目标。当SVG在屏幕上时,将offset path
设置为randomLines/L
,通过将offset distance
相对于滚动的距离从0%
更改为100%
来设置SVG字母的动画,如下所示:
path.setAttribute("style", "offset-path: path('M" + 0 +" " + 0 + " L " + generateRandomAnimationPathLine() + " " + generateRandomAnimationPathLine() + "')");
path.style.offsetDistance = element.intersectionRatio * 100 + "%";
实例:
代码:
JS:
let thresholdArray=[]
对于(设i=10;i<100;i+=1){
thresholdArray.push(i/100);
}
让选项={
root:null,
rootMargin:“20px”,
阈值:阈值数组
};
设pathGenerated=false;
让回调=(条目,观察者)=>{
entries.forEach(元素=>{
element.target.querySelectorAll(“路径”).forEach(路径=>{
if(元素isIntersecting){
如果(!pathGenerated){
setAttribute(“样式”,“偏移路径:路径('M“+0+”“+0+”L“+GeneraterDomainAnimationPathline()+”“+GeneraterDomainAnimationPathline()+”));
}
path.style.offsetDistance=element.intersectionRatio*100+“%”;
}否则{
pathGenerated=false;
path.style.removeProperty(“偏移路径”);
}
});
});
pathGenerated=true;
}
让GeneratorDomainAnimationPathline=(元素)=>{
返回Math.floor(Math.random()*Math.floor(100));
}
让observer=新的IntersectionObserver(回调,选项);
document.querySelectorAll('section').forEach(section=>{
console.log(部分)
观察员:观察(第节);
});
有两种误解。第一个问题涉及偏移路径
的工作方式。如果定义了沿其移动字母的路径,则可以使用移动坐标系执行此操作:
- 坐标系的原点将移动到路径上由偏移距离
指示的点
- 如果未为特性“偏移旋转”(offset rotate)设置任何其他设置,则会旋转坐标系,以使x轴沿着与当前使用点处路径的切线指向
- 然后,在移动和旋转的坐标系中绘制字母
与上面的图形所暗示的相反,字母不会随着距离的增加而远离其原始位置,每个字母始终与其未移动坐标系的原点有一段距离,该坐标系沿偏移路径旋转和移动。(由于每个路径都有一个单独的偏移路径,这意味着每个字母都有一个单独的坐标系。)
在某种意义上,对于直线,旋转是在距离很小之前应用的,这就是为什么字母会到处都是
你一出发
path {
offset-rotate: 0deg;
}
坐标系的旋转被抑制,在偏移距离为0时,字母显示在其原始位置。对于更远的距离,它们仍然向不同的方向移动,但不旋转
如果希望根据距离增加字母的旋转,则必须在脚本中计算。但请记住,旋转中心不是移动的字母位置,而是原始坐标系的原点!其结果是,一个线性函数随着交叉点的下降而逐渐旋转字母,再加上距离的增加,将产生沿螺旋线的移动。(将距离和旋转的组合视为极坐标。)
第二个误解在于IntersectionObserver返回的intersectionRatio
值。0%的交点表示对象在参考范围外,100%表示对象在参考范围内。因此,如果要在截面可见的情况下“有序”放置字母,则必须计算与交点成反比的偏移距离:
let callback = (entries, observer) => {
entries.forEach(element => {
element.target.querySelectorAll("path").forEach(path => {
if (element.isIntersecting) {
if (!pathGenerated) {
const x1 = 0;
const y1 = 0;
const x2 = generateRandomAnimationPathLine();
const y2 = generateRandomAnimationPathLine();
path.style.offsetPath = `path('M ${x1} ${y1} L ${x2} ${y2}')`;
}
path.style.offsetDistance = (1 - element.intersectionRatio) * 100 + "%";
} else {
pathGenerated = false;
path.style.removeProperty("offset-path");
}
});
});
pathGenerated = true;
}
我不得不说,我发现使用偏移路径
实现您想要达到的目标是次优的。对运动路径CSS模块的几个属性的支持是不完整的,正如我们所发现的,旋转与路径的关系是违反直觉的。SVG本身有