SVG 基础知识
SVG基本图形和属性
图形
- 矩形
- 圆形
- 椭圆
- 线
- 折线
- 多边形
rect.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="20" rx="20" ry="20" width="250" height="250"
style="fill:blue;stroke:pink;stroke-width:5;
fill-opacity:0.1;stroke-opacity:0.9"/>
</svg>
polyline.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<polyline points="0,0 0,20 20,20 20,40 40,40 40,60"
style="fill:white;stroke:red;stroke-width:2"/>
</svg>
polygon.svg
<11770820@qq.com
<tech_support@chinapay.com>, “huang.haisong@chinapay.com“ <huang.haisong@chinapay.com>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<polygon points="220,100 300,210 170,250"
style="fill:#cccccc;
stroke:#000000;stroke-width:1"/>
</svg>
基本属性
- fill
- stroke
- stroke-width
- transform
基本操作
API
- 创建图形
createElementNs(ns,tagName)
var text = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var NS = 'http://www.w3.org/2000/svg';
var tspan = document.createElementNS(NS,'tspan');
- 添加图形
element.appendChild(childElement)
- 设置/获取属性
element.setAttribute(name, value ) / elememt.getAttribute(name)
- 设置 xlink:href 属性 textPath.setAttributeNS(“http://www.w3.org/1999/xlink",'xlink:href',path)
HTML
<html>
<head></head>
<body>
<img src="sample.svg"> >
<embed src="sample.svg"></embed> > 外部引用式
<iframe src="sample.svg"></iframe> >
<object data="sample.svg"></object> >
<svg data-src="img/buble.svg"/>
</body>
</html>
容器
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/a
<a>, <defs>, <g>, <marker>,
<mask>, <missing-glyph>, <pattern>,
<svg>, <switch>, <symbol>
Descriptive elements
看medata案例就可以,
SVG 滤镜
Gaussian_blur.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="Gaussian_Blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" />
</filter>
</defs>
<ellipse cx="200" cy="150" rx="70" ry="40"
style="fill:#ff0000;stroke:#000000;
stroke-width:2;filter:url(#Gaussian_Blur)"/>
</svg>
注解:
- filter 定义滤镜
filter:url
引用滤镜- stdDeviation 模糊程度
- in=”SourceGraphic” 定义整个创建效果
滤镜效果有
- feBlend
- feColorMatrix
- feComponentTransfer
- feComposite
- feConvolveMatrix
- feDiffuseLighting
- feDisplacementMap
- feFlood
- feGaussianBlur
- feImage
- feMerge
- feMorphology
- feOffset
- feSpecularLighting
- feTile
- feTurbulence
- feDistantLight
- fePointLight
- feSpotLight
SVG 滤镜效果可以叠加使用
multi-filter.svg
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feGaussianBlur -->
<svg width="120" height="120"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="dropShadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
<feOffset dx="2" dy="4" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<circle cx="60" cy="60" r="50" fill="green"
filter="url(#dropShadow)" />
</svg>
SVG中的坐标系统
2.1 世界,视野和视窗的概念
- 世界是⽆无穷⼤大的,SVG画布可以是无穷大的
- 视野是观察世界的⼀一个矩形区域,可以有viewbox定义视野区域
- 视窗是浏览器开辟的一个区域, width, height - 控制视窗
- preserveAspectRatio 控制视野和视窗之间关系
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"
viewBox="0 0 400 300" preserveAspectRatio="xMidYMid meet">
</svg>
动态效果请参照:viewbox.html
2.2 图形分组
标签来创建分组 - 子元素可以继承组属性
- transform 属性定义坐标变换
- 可以嵌套使用
<svg xmlns="http://www.w3.org/2000/svg" >
<g stroke="green" fill="none" transform(0,50)>
<rect x="100" y="50" width="100" height="50"></rect>
<rect x="140" y="100" width="20" height="120"></rect>
</g>
</svg>
注解:
- g设置的stroke,fill属性, 两个rect都能继承
- transform能整体改变
内坐标
2.3 坐标系统概述
如上图:svg使用的是笛卡尔坐标系统
2.4 四个坐标系
- 用户坐标系(User Coordinate): -> 世界的坐标系
- 自身坐标系(Current Coordinate) -> 每个图形元素或分组独立与生俱来
- 前驱坐标系(Previous Coordinate) -> 父容器的坐标系
- 参考坐标系(Reference Coordinate) -> 使用其它坐标系来考究自身的情况时使用
2.5 坐标变换
查看ransform.html
- 嵌套
, 子 会继承父g坐标属性
颜色渐变和笔刷
颜色
HSL
渐变
线性渐变
linearGradient.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);
stop-opacity:1"/>
<stop offset="100%" style="stop-color:rgb(255,0,0);
stop-opacity:1"/>
</linearGradient>
</defs>
<ellipse cx="200" cy="190" rx="85" ry="55"
style="fill:url(#orange_red)"/>
</svg>
- gradientUnits=”userSpaceOnUse(用的是世界坐标系不是图形当前的坐标系)/objectBoundingBox(默认值)”
x1="0%" y1="0%
图形最上段,x2="100%" y2="0%
图形最下段
放射性渐变
radialGradient.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="grey_blue" cx="50%" cy="50%" r="50%"
fx="50%" fy="50%">
<stop offset="0%" style="stop-color:rgb(200,200,200);
stop-opacity:0"/>
<stop offset="100%" style="stop-color:rgb(0,0,255);
stop-opacity:1"/>
</radialGradient>
</defs>
<ellipse cx="230" cy="200" rx="110" ry="100"
style="fill:url(#grey_blue)"/>
</svg>
注解:
- cx、cy 和 r 属性定义外圈
- fx 和 fy 定义内圈,颜色渐变中心点,能产生聚光灯的效果
笔刷 pattern
pattern.svg
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="p1" x="0" y="0" width="50" height="50" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="5" fill="red"></circle>
<polygon points="30 10 60 50 0 50" fill="green"></polygon>
</pattern>
<pattern id="p2" x="0" y="0" width="50" height="50">
<circle cx="10" cy="10" r="5" fill="red"></circle>
<polygon points="30 10 60 50 0 50" fill="green"></polygon>
</pattern>
</defs>
<rect x="100" y="100" width="800" height="600" fill="url(#p1)" stroke="blue"></rect>
<rect x="100" y="100" width="800" height="600" fill="url(#p2)" stroke="blue"></rect>
</svg>
- objectBoundingBox : (默认)为容器百分比
- userSpaceOnUse : width 和 height 以世界坐标系为准,为宽度、高度
- patternUnits/patternUnitsContent
Path 高级
概述
path.svg 黑色山角型
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M250 150 L150 350 L350 350 Z" /> </svg>
Path-命令汇总
- M = moveto
- L = lineto
- H = horizontal lineto
- V = vertical lineto
- C (x1,y1,x2,y2,x,y)+ = curveto 从当前位置绘制三次⻉贝塞尔曲线到指定位置
- S = smooth curveto 从当前位置光滑绘制三次⻉贝塞尔曲线到指定位置
- Q = quadratic Belzier curve 绘制⼆二次⻉贝塞尔曲线
- T = smooth quadratic Belzier curveto 光滑绘制⼆二次⻉贝塞尔曲线
- A (rx,ry,xr,laf,sf,x,y) = elliptical Arc
- Z = closepath
A (rx,ry,xr,laf,sf,x,y) - 绘制弧线
- xr - (xAxis-rotation) 弧线所在椭圆的长轴角度
- laf - (large-arc-flag) 是否选择大弧长
- sf - (sweep-flag) 是否选择逆的那一段
时针方向
弧
基本规律
- 大写为绝对位置命令,小写为相对位置命令
参考资料
SVG 文本
.svg
<svg viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg">
<style>
.small { font: italic 13px sans-serif; }
.heavy { font: bold 30px sans-serif; }
/* Note that the color of the text is set with the *
* fill property, the color property is for HTML only */
.Rrrrr { font: italic 40px serif; fill: red; }
</style>
<text x="20" y="35" class="small">My</text>
<text x="40" y="35" class="heavy">cat</text>
<text x="55" y="55" class="small">is</text>
<text x="65" y="55" class="Rrrrr">Grumpy!</text>
</svg>
textPath.svg
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<!-- to hide the path, it is usually wrapped in a <defs> element -->
<!-- <defs> -->
<path id="MyPath" fill="none" stroke="red"
d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50" />
<!-- </defs> -->
<text>
<textPath href="#MyPath">
Quick brown fox jumps over the lazy dog.
</textPath>
</text>
</svg>
- x/dx/startOffset 都能使文字在path描绘的路径向前移动
- text-anchor=”middle”, 一段文字初始化锚点在一段文字中间
JS脚本控制
- setAttributeNS()设置xlink:href 属性
textPath.setAttributeNS("http://www.w3.org/1999/xlink",'xlink:href',path)
实战案例查看 path.html 或者是 附录-经典案例-正玄字体
tspan.svg
<svg xmlns="http://www.w3.org/2000/svg" >
<defs>
<pattern id="grid" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<path stroke="#f0f0f0" fill="none" d="M0,0H20V20"></path>
</pattern>
</defs>
<rect width="1200" height="1000" fill="url(#grid)"></rect>
<text id="sintext" x="100" y="100" style="font-size: 50px; font-family: 'Arial'; ">
<tspan fill="red" dy="-20 20">AB</tspan>
<tspan stroke="green" fill="none" stroke-width="2" dy="-40 40">CDE</tspan>
<!--简单叠加的效果-->
<tspan fill="blue" dy="20 20 20 20 20 20">FGHIJKLM</tspan>
</text>
<path d="M100,0V200M0,100H200" stroke="red" />
</svg>
垂直居中问题
代码如下
Example.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<select id="ta">
<option value="start">start</option>
<option value="end">end</option>
<option value="middle">center</option>
</select>
<select id="select"></select>
<svg>
<path stroke="green" d="M 0 100.5 500 100.5 M 140 0 v 200"/>
<text id="text" x="140" y="100" fill="red" font-size="50">慕课网</text>
<rect id="rect" stroke="blue" fill="none"></rect>
</svg>
</body>
</html>
Example.js
var values = "auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge | text-top | text-bottom".split(' | ');
values.forEach(function(value) {
var opt = document.createElement('option');
opt.value = opt.textContent = value;
select.appendChild(opt);
});
select.addEventListener('input', function() {
text.setAttribute('dominant-baseline', select.value);
var box = text.getBBox();
rect.setAttribute('x', box.x);
rect.setAttribute('y', box.y);
rect.setAttribute('width', box.width);
rect.setAttribute('height', box.height);
});
ta.addEventListener('input', function() {
text.setAttribute('text-anchor', ta.value);
});
案例2:自定义top,center,bottom对齐方式
https://jsbin.com/vezegib/edit?html,js,console
图形引用、裁切和蒙版
<use>
xlink:href = "#id"
<clipPath>
clip-path = "url(#clip-id)"
<mask>
mask="url(#mask-id)"
starsky
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>星空</title>
</head>
<style>
html, body {
margin: 0;
height: 100%;
width: 100%;
padding: 0;
background: #001122;
line-height: 0;
font-size: 0;
}
</style>
<body>
<svg width="100%" height="100%"
viewBox="-400 -300 800 600"
preserveAspectRatio="xMidYMid slice">
<defs>
<polygon id="star" points="0 -10 2 -2 10 0 2 2 0 10 -2 2 -10 0 -2 -2" fill="white"></polygon>
</defs>
<g id="real" >
<g id="start-group"/>
<g id="moon-group">
<mask id="moon-mask">
<circle r="70" cx="-250" cy="-120" fill="white"></circle>
<circle r="70" cx="-220" cy="-200" fill="black"></circle>
</mask>
<circle r="70" cx="-250" cy="-120" fill="white" mask="url(#moon-mask)"></circle>
</g>
<g id="light-tower " transform="translate(250,0)">
<defs>
<linearGradient id="tower" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#999"></stop>
<stop offset="1" stop-color="#333"></stop>
</linearGradient>
<radialGradient id="light" cx="0.5" cy="0.5" r="0.5">
<stop offset="0" stop-color="rgba(255,255,255,.8"></stop>
<stop offset="1" stop-color="rgba(255,255,255,0"></stop>
</radialGradient>
<clipPath id="light-clip">
<polygon points="0 0 -400 -15 -400 15">
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0"
to="360"
dur="10s"
repeatCount="indefinite"/>
</polygon>
<circle cx="0" cy="0" r="2"/>
</clipPath>
</defs>
<polygon points="0 0 5 50 -5 50" fill="url(#tower)"></polygon>
<ellipse rx="300" ry="100" cx="0" cy="0" fill="url(#light)" clip-path="url(#light-clip)"></ellipse>
</g>
</g>
<g id="reflect" transform="translate(0,50)" mask="url(#fading)">
<defs>
<linearGradient id="fade" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="rgba(255,255,255,.3)"/>
<stop offset="0.5" stop-color="rgba(255,255,255,0)"/>
</linearGradient>
<mask id="fading">
<rect x="-400" y="0" width="800" height="300" fill="url(#fade)"></rect>
</mask>
</defs>
<!--use 是不能使用mask的-->
<use xlink:href="#real" transform="scale(1,-1) translate(0,-50)" ></use>
</g>
<line x1="-400" y1="50" x2="400" y2="50" stroke="white"/>
</svg>
</body>
<script>
var NS = 'http://www.w3.org/2000/svg'
var XLINK_NS = 'http://www.w3.org/1999/xlink';
var page = document.querySelector('svg');
function use(origin) {
var _use = document.createElementNS(NS, 'use');
_use.setAttributeNS(XLINK_NS, 'xlink:href', '#' + origin.id);
return _use;
}
function random(min, max) {
return min + (max - min) * Math.random();
}
renderStar();
function renderStar() {
var starRef = document.getElementById('star');
var starGroup = document.getElementById('start-group');
var starCount = 500;
var star;
while (starCount--) {
star = use(starRef);
star.setAttribute('opacity', random(0.1, 0.4));
star.setAttribute('transform', 'translate(' + random(-400, 400) + ',' + random(-300, 50) + ')' +
'scale(' + random(0.1, 0.8) + ')'
);
starGroup.appendChild(star);
}
}
</script>
</html>
SVG动画
参考资料
动画标签概述
animate.svg
<?xml version="1.0"?>
<svg width="120" height="120" viewBox="0 0 120 120" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="100" height="100">
<animate attributeType="XML" attributeName="x" from="-100" to="120"
dur="10s" repeatCount="indefinite"/>
</rect>
</svg>
motion.xml
<?xml version="1.0"?>
<svg width="120" height="120" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Draw the outline of the motion path in grey, along
with 2 small circles at key points -->
<path d="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110"
stroke="lightgrey" stroke-width="2"
fill="none" id="theMotionPath"/>
<circle cx="10" cy="110" r="3" fill="lightgrey" />
<circle cx="110" cy="10" r="3" fill="lightgrey" />
<!-- Red circle which will be moved along the motion path. -->
<circle cx="" cy="" r="5" fill="red">
<!-- Define the motion path animation -->
<animateMotion dur="6s" repeatCount="indefinite">
<mpath xlink:href="#theMotionPath"/>
</animateMotion>
</circle>
</svg>
<mpath xlink:href="#theMotionPath"/>
引用上面的路径定义
path 可以在animation内部
sample2.html
<!DOCTYPE html>
<html lang="en">
<style>
html,body, svg{
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
<head>
<meta charset="UTF-8">
<title>SVG 动画</title>
</head>
<body>
<svg viewBox="-400 -400 800 800" xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="-25" y="-25" height="50" width="50" fill="rgba(0,255,255,0.6)">
<animateMotion
path="M 0 0L 100 100A 200 200 0 1 0 0 -100"
dur="3s"
repeatCount="indefinite"
rotate="auto">
<!--<mpath xlink:href="#motion-path"/>-->
</animateMotion>
</rect>
<path id="motion-path" d="M 0 0L 100 100A 200 200 0 1 0 0 -100" stroke="gray" fill="none"/>
</svg>
</body>
</html>
transform.svg
<svg width="120" height="120" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<polygon points="60,30 90,90 30,90">
<animateTransform attributeName="transform"
attributeType="XML"
type="rotate"
from="0 60 70"
to="360 60 70"
dur="10s"
repeatCount="indefinite"/>
</polygon>
</svg>
参数设置
实战案例
动画顺序
<svg viewBox="-400 -400 800 800" xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="-25" y="-25" height="80" width="80" fill="rgba(0,255,255,0.6)">
<animate id="first"
attributeName="x"
attributeType="XML"
from="100"
to="500"
dur="1s"
fill="freeze"
begin="0;second.end"
/>
<animate id="second"
attributeName="x"
attributeType="XML"
from="500"
to="100"
dur="1s"
fill="freeze"
begin="first.end"
/>
<animate id="third"
attributeName="fill"
attributeType="XML"
from="red"
to="yellow"
dur="6s"
fill="freeze"
/>
SVG 工具
svgo
SVG 优化工具,删减多余的内容,减少SVG大小
网页工具svgomg
SVG动画编辑工具
附录
安卓相关文章
- An Introduction to Icon Animation Techniques 非常详尽的介绍并附有代码例子讲解 【重点】
- Animation: Jump-through【待研究】【重点】
官方文档
学习资料
经典案例
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/metadata -->
<svg width="400" viewBox="0 0 400 300"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<metadata>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:connect="http://www.w3.org/1999/08/29-svg-connections-in-RDF#">
<rdf:Description about="#CableA">
<connect:ends rdf:resource="#socket1"/>
<connect:ends rdf:resource="#ComputerA"/>
</rdf:Description>
<rdf:Description about="#CableB">
<connect:ends rdf:resource="#socket2"/>
<connect:ends rdf:resource="#ComputerB"/>
</rdf:Description>
<rdf:Description about="#CableN">
<connect:ends rdf:resource="#socket5"/>
<connect:ends>Everything</connect:ends>
</rdf:Description>
<rdf:Description about="#Hub">
<connect:ends rdf:resource="#socket1"/>
<connect:ends rdf:resource="#socket2"/>
<connect:ends rdf:resource="#socket3"/>
<connect:ends rdf:resource="#socket4"/>
<connect:ends rdf:resource="#socket5"/>
</rdf:Description>
</rdf:RDF>
</metadata>
<title>Network</title>
<desc>An example of a computer network based on a hub.</desc>
<style>
svg {
/* Default styles to be inherited */
fill: white;
stroke: black;
}
text { fill: black; stroke: none; }
path { fill: none; }
</style>
<!-- Define symbols used in the SVG -->
<defs>
<!-- hubPlug symbol. Used by hub symbol -->
<symbol id="hubPlug">
<desc>A 10BaseT/100baseTX socket</desc>
<path d="M0,10 h5 v-9 h12 v9 h5 v16 h-22 z"/>
</symbol>
<!-- hub symbol -->
<symbol id="hub">
<desc>A typical 10BaseT/100BaseTX network hub</desc>
<text x="0" y="15">Hub</text>
<g transform="translate(0 20)">
<rect width="253" height="84"/>
<rect width="229" height="44" x="12" y="10"/>
<circle fill="red" cx="227" cy="71" r="7" />
<!-- five groups each using the defined socket -->
<g id="sock1et" transform="translate(25 20)">
<title>Socket 1</title>
<use xlink:href="#hubPlug"/>
</g>
<g id="socket2" transform="translate(70 20)">
<title>Socket 2</title>
<use xlink:href="#hubPlug"/>
</g>
<g id="socket3" transform="translate(115 20)">
<title>Socket 3</title>
<use xlink:href="#hubPlug"/>
</g>
<g id="socket4" transform="translate(160 20)">
<title>Socket 4</title>
<use xlink:href="#hubPlug"/>
</g>
<g id="socket5" transform="translate(205 20)">
<title>Socket 5</title>
<use xlink:href="#hubPlug"/>
</g>
</g>
</symbol>
<!-- computer symbol -->
<symbol id="computer">
<desc>A common desktop PC</desc>
<g id="monitorStand" transform="translate(40 121)">
<title>Monitor stand</title>
<desc>One of those cool swivelling monitor stands that sit under the monitor</desc>
<path d="m0,0 S 10 10 40 12"/>
<path d="m80,0 S 70 10 40 12"/>
<path d="m0,20 L 10 10 S 40 12 70 10 L 80 20z"/>
</g>
<g id="monitor">
<title>Monitor</title>
<desc>A very fancy monitor</desc>
<rect width="160" height="120"/>
<rect fill="lightgrey" width="138" height="95" x="11" y="12"/>
</g>
<g id="processor" transform="translate(0 142)">
<title>The computer</title>
<desc>A desktop computer - broad flat box style</desc>
<rect width="160" height="60"/>
<g id="discDrive" transform="translate(70 8)">
<title>disc drive</title>
<desc>A built-in disc drive</desc>
<rect width="58" height="3" x="12" y="8"/>
<rect width="8" height="2" x="12" y="15"/>
</g>
<circle cx="135" cy="40" r="5"/>
</g>
</symbol>
</defs>
<text x="0" y="15">Network</text>
<!-- Use the hub symbol. -->
<g id="Hub" transform="translate(80 45)">
<title>Hub</title>
<use xlink:href="#hub" transform="scale(0.75)"/>
</g>
<!-- Use the computer symbol. -->
<g id="ComputerA" transform="translate(20 170)">
<title>Computer A</title>
<use xlink:href="#computer" transform="scale(0.5)"/>
</g>
<!-- Use the same computer symbol. -->
<g id="ComputerB" transform="translate(300 170)">
<title>Computer B</title>
<use xlink:href="#computer" transform="scale(0.5)"/>
</g>
<!-- Draw Cable A. -->
<g id="CableA" transform="translate(107 88)">
<title>Cable A</title>
<desc>10BaseT twisted pair cable</desc>
<path d="M0,0c100,140 50,140 -8,160"/>
</g>
<!-- Draw Cable B. -->
<g id="CableB" transform="translate(142 88)">
<title>Cable B</title>
<desc>10BaseT twisted pair cable</desc>
<path d="M0,0c100,180 110,160 159,160"/>
</g>
<!-- Draw Cable N. -->
<g id="CableN" transform="translate(242 88)">
<title>Cable N</title>
<desc>10BaseT twisted pair cable</desc>
<path d="M0,0c0,-70 20,-50 60,-50"/>
</g>
</svg>
正玄字体
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>正玄字体</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="100%" height="100%">
<defs>
<pattern id="grid" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<path stroke="#f0f0f0" fill="none" d="M0,0H20V20"></path>
</pattern>
</defs>
<rect width="4200" height="2000" fill="url(#grid)"></rect>
<text id="sintext" x="100" y="160" style="font-size: 14px; font-family: 'Arial'; ">ABCDEFGHIJKLMNOPQRSTUVWXYZ</text>
<path d="M100,0V200M0,100H200" stroke="red" transform="translate(0,60)"/>
<text id="sintext2" x="100" y="360" style="font-size: 14px; font-family: 'Arial'; "></text>
</svg>
<style>
body {
width: 100vm;
height: 100vm;
}
svg {
overflow: visible;
}
</style>
<script>
var n = 26;
var x = [];
var y = null;
var i = n;
var s = 100;
var w = 0.02;
var t = 0;
var text = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var NS = 'http://www.w3.org/2000/svg';
while (i--) {
x.push(10);
var tspan = document.createElementNS(NS,'tspan');
tspan.textContent = text[n -i -1];
sintext2.appendChild(tspan);
var h = Math.round(360 / 26 * i);
tspan.setAttribute('fill','hsl(' + h + ',100%,80%')
}
function arrange(t) {
y = [];
var ly = 0, cy;
for (i = 0; i < n; i++) {
cy = -s * Math.sin(w * i * 20 + t);
y.push(cy - ly);
ly = cy;
}
console.table(y);
}
function render() {
sintext.setAttribute('dx', x.join(' '));
sintext.setAttribute('dy', y.join(' '));
sintext2.setAttribute('dx', x.join(' '));
sintext2.setAttribute('dy', y.join(' '));
}
function frame() {
t += 0.02;
arrange(t);
render();
requestAnimationFrame(frame)
}
frame()
</script>
</body>
</html>