00、前端图形
前端代码实现图形的几种方式:CSS、SVG、Canvas(主要是JavaScript编码)
CSS也是可以画图的,需要借助于高宽、边框border
、clip-path
裁剪、渐变色背景等属性来模拟实现各种图形,当然只能实现一些简单的图形。
border:用四条边框样式属性的各种组合变换,实现一些简单的图形。网上也有画一些稍微复杂的图形,如哆啦A梦,但代码量稍多,可读性不好,并不推荐。
<div class="gcss">
<p class="border">border</p>
<p class="rborder">圆角按钮</p>
<p class="radio"></p>radio
<p class="triangle1"></p>三角形
<p class="triangle2"></p>三角形
</div>
<style>
.gcss p {
display: inline-block;
text-align: center; vertical-align: middle;
}
.border {
border: 30px solid;
border-color: aqua tan violet peru;
border-radius: 20px;
}
.rborder {
background-color: #b1ccf3;
width: 100px; height: 40px; line-height: 40px;
border-radius: 20px;
}
.radio {
width: 40px; height: 40px;
border-radius: 50%;
border: 10px solid;
}
.triangle1 {
border: 50px solid #0001;
border-left-color: red;
}
.triangle2 {
border-left: 50px solid #0001;
border-right: 50px solid #0001;
border-bottom: 50px solid red;
}
</style>
01、< svg>矢量图形
< svg>可缩放矢量图形(Scalable Vector Graphics,SVG),是一种基于 XML(数学)描述的二维的矢量图形,内容可以直接插入网页,成为DOM的一部分,然后用 JavaScript 和 CSS 进行操作。SVG 内容也可以写在一个独立文件中,然后用CSS(background-url)、<img>
、<object>
、<embed>
、<iframe>
来引用。
大多数现代浏览器都支持SVG 图形,越来越多的项目在使用SVG图形,简单的像图标,复杂的一些图表Chart也有不少是基于SVG实现的。相比于位图,体积更小,可无线缩放而不失真。
比较 | 矢量图形 | 位图 |
---|---|---|
存储的数据 | 存储元素、算法数据 | 存储像素数据 |
存储大小 | 小 | 大 |
缩放效果 | 无线缩放,不失真 | 固定大小,放大会失真 |
可维护性 | 很容易修改 | 修改麻烦 |
扩展性 | 支持CSS、JS | 不支持 |
文件格式 | .svg ,直接嵌入数据到页面 |
.bmp /.png /.jpg /.gif ,< img>可嵌入svg文件 |
支持的元素 | <svg> 、<img> 、<iframe> 、<object> |
<img> 、<iframe> |
兼容性 | IE9开始支持 | 较好 |
渲染性能 | 复杂的SVG会占用很多时间 | 稳定 |
网络传输性能 | 和页面数据一起,体积小,速度快 | 需单独请求图片资源 |
缓存 | 随网页内容一起,不可单独缓存 | 图片可单独缓存 |
1.1、< svg>元素
<svg>
内部支持多种图形算法,基础的如线line
、圆形<circle>
、矩形rect
、文本text
,复杂的有折线polyline
、多边形polygon
、路径数据path
等。这些图形都以子元素的形式组合,因此也就都支持CSS、JS的操作了。iconfont-阿里巴巴矢量图标库上有非常丰富的< svg>矢量图形。
元素/属性 | 描述 | 值/示例 |
---|---|---|
< svg > |
矢量图形元素 | |
viewBox | SVG 画布显示区域,这里 1 单位等同于 1 屏幕单位,SVG里的坐标、尺寸都是基于此画布区域 | viewBox="0 0 300 200" |
width、height | 宽度、高度 | width="300" height="200" |
xmlns | xml标签的命名空间,为了区分html、svg,可以省略 | |
< line> | 线段 | |
x1、y1 | 起点x、y坐标 | <line x1="0" y1="100" /> |
x2、y2 | 终点x、y坐标 | x2="300" y2="100" |
< rect> | 矩形:<rect x="5" y="50" height="100" width="290"/> |
|
x、y | 起点坐标 | |
width、height | 矩形的宽、高 | |
rx、ry | x、y方向的圆角半径。r=radius 半径 | rx="50" ry="50" |
<circle/ellipse> | 圆和椭圆:<circle cx="150" cy="100" r="80"/> |
|
cx、cy | 圆心的x、y坐标 | |
r | 圆的半径长度 | |
rx、ry | 椭圆的x、y半径 | |
<polyline/polygon> | 折线、多边形,两者数据结构相似,多边形是自动首尾连接封闭成一个区域(Polygon /ˈpɒlɪɡən/ 多边形) | |
points | x、y坐标的集合,多个坐标逗号, 分割 |
points="0 0, 20 40, 70 80/> |
< path> | 路径,很常用、很强大的图形绘制,数据在属性d 中 |
|
< d> | 路径数据,< path> 最重要的属性,由多组命令+ 坐标点组成 |
d="M 50 5 H250 V195 H50 Z" |
M x y | 移动画笔到坐标点x、y | M50 5 |
L x y | 划线到坐标x、y | L 250 0 |
H x | 绘制水平线,到坐标x;小写h 的坐标为相对位置 |
H 250 |
V y | 绘制垂直线,到坐标y;小写v 的坐标为相对位置 |
V195 |
Z | 闭合路径(closepath),放到最后用于闭合路径 | |
C* | 绘制曲线,包括贝塞尔曲线、圆弧。 | |
<text> | 文本标签,支持CSS样式中的文本样式 | |
x、y | 文本开始位置 | |
font-size | 字体大小 | |
< textPath> | 文字绘制的路径,这个就比较有趣了 | <textPath xlink:href="#path1"> |
公共属性 | 部分属性可以用CSS设置,支持hover伪类 | |
stroke | 笔画颜色(stroke /stroʊk/ 笔画) ,包括线段、形状线条。 | stroke="red" |
stroke-width | 画笔线宽 | stroke-width="10" |
fill | 填充颜色,填充一个区域(矩形、圆形等) | fill="#0001" |
❗小提示:注意服务器添加对svg的支持,及gzip压缩。
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<circle cx="150" cy="100" r="80" fill="green" />
<circle cx="150" cy="100" r="70" fill="#fff" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="orange">SVG</text>
<line x1="0" y1="100" x2="300" y2="100" stroke="white" stroke-width="8"/>
</svg>
<svg class="icon" height="200" viewBox="0 0 300 200" version="1.1">
<rect x="5" y="50" rx="50" ry="50" height="100" width="290" fill="white" stroke="blue" stroke-width="10"/>
<path d="M 50 5 H250 V195 H50 Z" stroke="red" stroke-width="10" fill="#00000001" />
<text x="145" y="125" font-size="60" text-anchor="middle" fill="#fab">Path</text>
</svg>
<style>
svg:hover{
background-color: aliceblue;
stroke: red;
stroke-width: 1px;
fill: red;
}
</style>
1.2、动画
SVG 本身就是一个HTML元素,因此动画可以用CSS的动画来实现(参考 CSS动画),SVG中也有专门用于实现动画的<animate>
子元素。这里示例采用JavaScript+transform
变换实现旋转效果。
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<circle cx="150" cy="100" r="80" fill="green" />
<circle cx="150" cy="100" r="70" fill="#fff" />
<text class="svgc" x="150" y="125" font-size="60" text-anchor="middle" fill="orange" >SVG</text>
<line class="svgc" x1="0" y1="100" x2="300" y2="100" stroke="white" stroke-width="8" />
</svg>
<script>
let svgcs = document.querySelectorAll(".svgc");
//设置中心点
svgcs.forEach(element => {
element.setAttribute("transform-origin", '150 100');
});
let deg = 0;
setInterval(() => {
deg = deg > 360 ? 0 : deg+4;
svgcs.forEach(element => {
element.setAttribute("transform", `rotate(${deg})`);
});
}, 100);
</script>
<!-- 用CSS动画实现的版本 -->
<style>
.svgc {
transform-origin: 150px 100px;
animation: svgc-routate 2s linear 1s infinite;
}
@keyframes svgc-routate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>