前端动效中svg的使用
分享1:路径颜色循环动画
这里我们创建了3组动效,矩形,圆,自定义路径。 我们定义4种颜色,通过控制路径动画的俩常用属性stroke-dasharray和stroke-dashoffset来实现,初始化好虚线配置,动态调整虚线偏移完成一段颜色的动画
然后创建剩余颜色的图形,叠加到上面,调整偏移,完成初始的显示
接下来就是帧循环,随着时间来调整每段的偏移完成动画了。
需要注意的是:可以看到的是圆的首尾有很好的连续,矩形的没有连续,原因是矩形的我给每段虚线设置了固定长度,没有正好平铺满矩形周长,圆形的处理成了每段虚线是周长的1/8,这样,4组颜色能正好2次铺满周长
主要代码:
// 创建svg的元素
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
// 段的颜色
var colors = [
"#ff0000",
"#00ff00",
"#0000ff",
"#ff00ff",
];
// 圆半径
var cir_radwid = 200;
// 圆周长
var cir_pm = 2 * Math.PI * cir_radwid;
// colors共4段颜色,准备2次铺满
var cir_line = cir_pm / (colors.length * 2);
var cir_offset = cir_line * (colors.length - 1);
// 圆所有路径的存储
var circlearr = [];
// 添加圆
for (var i = 0; i < colors.length; i++) {
// 每种颜色一个圆
var one_circle = makeSVG("circle", {
"cx": 250,
"cy": 250,
"r": cir_radwid,
"fill": "none",
"stroke-width": 10,
"stroke": colors[i],
//重要
"stroke-dasharray": cir_line + " " + cir_offset,
//重要
"stroke-dashoffset": i * cir_offset,
//连接点的处理
"stroke-linecap": "round",//butt,square,round
"id": "circle" + i
})
circlearr.push(one_circle);
}
// 上帧时间,用来计算时间
var lastframe = Date.now();
// 运动的速度
var rect1_offset = 0;
// requestAnimationFrame的id
var updateid = 1;
// 帧循环
var loop = () => {
var ntime = Date.now();
// 帧间隔
var passtime = ntime - lastframe;
if (passtime > 30) {
passtime = 30;
}
// 偏移增量
rect1_offset += passtime * 100 / 1000;
for (var i2 = 0; i2 < circlearr.length; i2++) {
var i2circle = circlearr[i2];
// 更新偏移实现动画
i2circle.setAttribute("stroke-dashoffset", (rect1_offset + i2 * cir_offset));
}
updateid = requestAnimationFrame(loop);
}
loop();
分享2:常见的滚动显示的动画
这个demo包含了3个效果,一个是路径线的动效,一个是图片的遮罩显示,一个是文字的按照路径移动显示。
路径线的动效
先分段绘制所有的线,分组添加到svg中
// 宽度
var svg_wid = document.body.clientWidth;
// 高度
var svg_hei = 3500;
// 0->500的路径,第一段的所有路径
var p1 = makeSVG("path", {
"d": "M" + svg_wid / 2 + " 0," +
"V" + 500,
});
// 500->1000的路径,第一段的所有路径
var p2 = makeSVG("path", {
"d": "M" + svg_wid / 2 + " " + 500
+ ",h" + svg_wid / 3
+ ",V" + 1000
+ ",h" + (-svg_wid / 3)
});
var p2_1 = makeSVG("path", {
"d": "M" + svg_wid / 2 + " " + 500
+ ",h" + (-svg_wid / 3)
+ ",V" + 1000
+ ",h" + (svg_wid / 3)
});
.
.
.
//滚动监听,调整每个path的stroke-dashoffset
路径绘制好后,添加滚动监听,根据滚动位置,来调整路径的虚线偏移完成路径动画
图片的遮罩
添加图片和遮罩,动态调整遮罩位置,完成图片的遮罩动画
// 设置一个遮罩
var mask = makeSVG("mask", {
"id": "mask1"
});
// 遮罩的区域
var rect = makeSVG("rect", {
"x": svg_wid / 6,
"y": 0,
"width": svg_wid / 3 * 2,
"height": 500,
"fill": "#ffffff",
"id":"mask_rect1",
});
mask.appendChild(rect);
// 添加一个图片
var p2_img = makeSVG("image", {
"href": "../bannerimg.png",
"x": svg_wid / 6,
"y": 500,
"height": 500,
"width": svg_wid / 3 * 2,
"mask": "url(#mask1)"
})
//滚动监听,调整mask中rect的y
文字的路径移动
使用svg文字的textPath标签设置显示路径,动态调整startOffset属性完成文字动画
// 文字的显示路径
var onecurve = makeSVG("path",{
"id":"curvepath",
"d":"M"+(100)+" "+1260+","
+"Q"+(svg_wid/2)+" 2000, "+(svg_wid-300)+" 1450"
})
// 文本
var p4_txt = makeSVG("text",{
"x":svg_wid/2,
"y":1650,
"text-anchor":"middle",
"font-size":88,
"stroke-width":2
});
// 路径文本
var p4_txtpath = makeSVG("textPath",{
"href":"#curvepath",
"startOffset":"100%"
})
p4_txtpath.innerHTML = "点个赞再走";
p4_txt.appendChild(p4_txtpath);
//滚动监听,调整p4_txtpath的startOffset
代码在:gitee.com/zjz1995/svg… test7和8中