用javascript画一个Atom官网的SVG图标
关键属性和元素
- svg
viewBox: 属性的值是一个包含4个参数的列表min-x,min-y,widthandheight, 以空格或者逗号分隔开, 在用户空间中指定一个矩形区域映射到给定的元素。
定义一个显示区域、比例(svg缩放应该保持纵横比),对外(父级以上设置width,height)值=值,对内和子元素的是 值:值 的比例关系。svg设置的宽高都会相应的根据比例(值:值)显示子元素大小和位置。
- circle
stroke-width: 圆环宽度,边框会有一半宽度算在宽高里(和半径重合)。宽度=半径 * 2 + 圆环宽度;如下图填充的圆和半透明圆环块:
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="44" stroke-width="12" stroke-dasharray="10" fill="#ffffff00" stroke="#ffffff33"></circle>
<circle cx="50" cy="50" r="44" fill="#ffffff33"></circle>
</svg>
- circle
stroke-dasharray: 它是一个length和percentage数列,数与数之间用逗号或者空白隔开,指定短划线和缺口的长度。如果提供了奇数个值,则这个值的数列重复一次,从而变成偶数个值。这个值对应的是每一段的宽度和空白宽度。 <animateTransform>: 关键元素,可以控制svg动画,repeatCount设置为“indefinite”的时候无限循环。支持transform的很多属性。(但是貌似很坑的旋转中心需要用css transform-origin: center处理)
然后就是一顿画圆,画不同颜色和不同半径的圆就OK
- 创建命名空间下的节点。
由于document.createElement创建的是html下的普通元素,所以,我们创建svg图标还需要用到 document.createElementNS
let element = document.createElementNS(namespaceURI, qualifiedName[, options]);
有效的namespaceURI
- HTML - 参阅
http://www.w3.org/1999/xhtml - SVG - 参阅
http://www.w3.org/2000/svg - XBL - 参阅
http://www.mozilla.org/xbl - XUL - 参阅
http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul
其他都好说,直接上源码:
function mount(selector, circles) {
const svgNS = "http://www.w3.org/2000/svg"
const content = document.querySelector(selector)
const svg = document.createElementNS(svgNS, "svg")
svg.setAttribute("viewBox", "0 0 100 100")
content.innerHTML = ""
const group = document.createElementNS(svgNS, "g")
group.style.transformOrigin = "center"
const animationTransform = document.createElementNS(svgNS, "animateTransform")
animationTransform.setAttribute("attributeName", "transform");
animationTransform.setAttribute("attributeType", "XML")
animationTransform.setAttribute("type", "rotate")
animationTransform.setAttribute("to", "360")
animationTransform.setAttribute("repeatCount", "indefinite")
circles.forEach(circle => {
const _group = group.cloneNode(true)
const _animationTransform = animationTransform.cloneNode(true)
const child = document.createElementNS(svgNS, 'circle')
child.setAttribute("cx", "50")
child.setAttribute("cy", "50")
child.setAttribute("r", circle.r)
child.setAttribute("fill", "#ffffff00")
child.setAttribute("stroke-width", circle.width)
child.setAttribute("stroke-dasharray", (circle.dashArray || [10, 25]).join(","))
child.setAttribute("stroke", circle.color)
_animationTransform.setAttribute("from", circle.offset || "0")
if (circle.speed) _animationTransform.setAttribute("dur", circle.speed + "s")
_group.appendChild(child)
_group.appendChild(_animationTransform)
svg.appendChild(_group)
})
content.appendChild(svg)
}
可以上CodePen 体验和获取代码。一毛一样打在评论区。
参考资料
走进HTML5-让你从不懂到精通SVG(大量实例操作) - 掘金 (juejin.cn)
SVG入门—如何手写SVG - 掘金 (juejin.cn)
SVG:理解stroke-dasharray和stroke-dashoffset属性 - 掘金 (juejin.cn)
(知乎文章同步发布)