SVG 与 Canvas

Posted 知其黑、受其白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SVG 与 Canvas相关的知识,希望对你有一定的参考价值。

阅读目录

00、前端图形

前端实现图形的几种方式:

01、<svg> 矢量图形

<svg> 可缩放矢量图形(Scalable Vector Graphics,SVG),是一种基于 XML 描述的二维的矢量图形。

相比于位图,体积更小,可无线缩放而不失真。


<svg> 内部支持多种图形算法,基础的如线,圆形 line、矩形 rect、文本 text,复杂的有折线 polyline、多边形 polygon、路径数据 path 等。

iconfont-阿里巴巴矢量图标库上有非常丰富的矢量图形。

❗ 小提示:注意服务器添加对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>

动画

SVG 的动画是基于其 transform 属性,通过JS来实现。
transform 变化的主要参数:

translate 移动:transform="translate(x, y)"
scale 缩放:transform="scale(x, y)",可只写一个,等比例缩放。
rotate 旋转:transform="rotate(deg)",deg 为角度
transform-origin 元素中心点,transform-origin="x y"
skew 倾斜:transform="skewX(x) skewY(y)",x、y方向倾斜( /skjuː/歪斜)

<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>

02、<canvas> 基础

<canvas> 只是一块平平无奇的画布而已,提供了一点点API,由JS进行绘制各种图形。
2D 的 canvas 绘制和 挺像,都是一些线、矩形、圆、path 路径数据。

  • 双标签,必须包含闭合标签。
  • 坐标系以左上角为中心点,和 SVG 一样。


<canvas id="canvas" width="400" height="400"></canvas>
<script>
	ctx = document.getElementById('canvas').getContext('2d');
	// ctx.alpha = false;
	ctx.fillStyle = 'rgba(250,0,0,0.6)';
	ctx.fillRect(10, 10, 40, 40);
	ctx.fillRect(30, 30, 40, 40);
	ctx.strokeStyle = 'red';
	ctx.lineWidth = 3;
	ctx.strokeRect(90, 10, 150, 50);
	ctx.fillStyle = 'rgba(0,0,250,0.5)';
	ctx.font = '20px 微软雅黑';
	ctx.fillText("文本Text", 120, 40)
	//path
	ctx.beginPath();
	ctx.moveTo(90, 80);
	ctx.lineTo(90, 200);
	ctx.lineTo(190, 200);
	ctx.closePath();
	ctx.arc(120, 120, 50, 0, 360);
	ctx.fill();
</script>

动画

动画就是不停的重绘:

setInterval(function, delay):适合不需要交互的场景。

setTimeout(function, delay):通过键盘或者鼠标事件来捕捉用户的交互,再用 setTimeout 执行相应的动作。

requestAnimationFrame(callback):这个方法更加平缓并更加有效率,当系统准备好了重绘条件的时候,才调用绘制动画帧。

<canvas id="canvas" width="400" height="400"></canvas>
<script>
	ctx = document.getElementById('canvas').getContext('2d');
	//动画旋转
	let eangle = 0;
	function drawEllipse() 
			ctx.clearRect(255, 150, 140, 140);
			ctx.beginPath();
			ctx.fillStyle = 'rgba(0,250,0,0.3)';
			eangle = eangle > 360 ? 0 : eangle + 1;
			ctx.ellipse(320, 230, 60, 30, eangle * Math.PI / 180, 0, 2 * Math.PI);
			ctx.stroke();
			ctx.fill();
			ctx.beginPath();
			ctx.ellipse(320, 230, 30, 60, eangle * Math.PI / 180, 0, 2 * Math.PI);
			ctx.fillStyle = 'rgba(0,0,250,0.3)';
			ctx.stroke();
			ctx.fill();
	
	setInterval(drawEllipse, 20);
	//水平移动
	let lx = 40;
	let ltr = true;
	function drawRect() 
			if (lx > 300) ltr = false;
			if (lx < 40) ltr = true;
			// ctx.clearRect(lx, 220, 40, 40);
			ctx.fillStyle = 'rgb(255,255,255,0.4)';
			ctx.fillRect(20, 290, 340, 60);
			lx = ltr ? lx + 2 : lx - 2;
			ctx.fillStyle = 'rgb(110,22,250)';
			ctx.fillRect(lx, 300, 40, 40);
			ctx.strokeRect(lx, 300, 40, 40);
			requestAnimationFrame(drawRect);
	
	requestAnimationFrame(drawRect);
</script>

03、WebGL

WebGL 作为一种WEB 3D绘图技术,依托于 <canvas> 元素。

WebGL是运行在GPU上的,可面向底层显卡编程,可以调用底层的接口,实现硬件加速,在2D图形绘制上性能会优于Canvas2D。

原生的WebGL比较难学,可考虑使用使用第三方的 WebGL库,如 Three.js、Cesium.js(3D地图)、Babylon.js

以上是关于SVG 与 Canvas的主要内容,如果未能解决你的问题,请参考以下文章

SVG 与 HTML5 的 canvas 各有啥优点,哪个更有前途

canvas与svg的区别有什么?canvas和svg的区别比较

canvas绘制形状

Canvas 和 SVG 有什么区别?

CANVAS画布与SVG的区别

HTML5——Canvas 与 SVG 区别