【JavaScript】SVGTool: SVG常用方法庫

前言


HTML5經歷了幾年的沉淪之後引來一輪的潮流。在圖形可視化方面,SVG同canvas相比在交互性方面有更大的優勢。

市面上成熟的JavaScript框架已有很多,其中多有對SVG的封裝。

本篇兼顧易用性和可讀性,更適合初學者入門,用於瞭解SVG的基本原理和超輕量級的庫引用(以便後期自主拓展)。


之前封裝過一個iOS平臺下的canvas繪圖(《【iOS】UIWebView的HTML5擴展之canvas篇 》)

本篇則純粹的從H5的角度對SVG常用方法進行簡單封裝。


完整源代碼下載地址(持續更新):https://github.com/duzixi/SVGTool


源代碼


核心代碼:

SVGTool.js

//
// SVGTool.js
// 
// (C) 2015 duzixi.com
// 
// 2015.10.03 Created by 杜子兮
// 
// 封裝了常用的SVG方法。
// 包括:基本形狀、濾鏡、漸變填充等

/* 通用 */

// 命名空間
var XMLNS = "http://www.w3.org/2000/svg";

function svgRootNode(id, width, height) {
	var svgNode = document.createElementNS(XMLNS, "svg");
	svgNode.id = id;
	svgNode.setAttribute("xmlns", XMLNS);
	svgNode.setAttribute("version", "1.1");
	svgNode.setAttribute("width", width);
	svgNode.setAttribute("height", height);
	return svgNode;
}

/* 基本形狀 */

// •矩形 <rect>
function svgRectNode(id, x, y, rx, ry, w, h, fillColor, strokeWidth, strokeColor){
	var svgNode = document.createElementNS(XMLNS, "rect");
	
	svgNode.id = id;
	
	svgNode.setAttribute("x", x);
	svgNode.setAttribute("y", y);
	svgNode.setAttribute("rx", rx);
	svgNode.setAttribute("ry", ry);
	svgNode.setAttribute("width", w);
	svgNode.setAttribute("height", h);

	svgNode.style.fill = fillColor;
	svgNode.style.stroke = strokeColor;
	svgNode.style.strokeWidth = strokeWidth;

	return svgNode;
}

// •圓形 <circle>
//	示例:<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
function svgCircleNode(id, cx, cy, r, fillColor, strokeWidth, strokeColor){
	var svgNode = document.createElementNS(XMLNS, "circle");
	
	svgNode.id = id;
	
	svgNode.setAttribute("cx", cx);
	svgNode.setAttribute("cy", cy);
	svgNode.setAttribute("r", r);

	svgNode.style.fill = fillColor;
	svgNode.style.stroke = strokeColor;
	svgNode.style.strokeWidth = strokeWidth;

	return svgNode;
}

// •橢圓 <ellipse>
//  示例:<ellipse cx="300" cy="150" rx="200" ry="80" style="fill:rgb(200,100,50); stroke:rgb(0,0,100);stroke-width:2"/>
function svgEllipseNode(id, cx, cy, rx, ry, fillColor, strokeWidth, strokeColor) {
	var svgNode = document.createElementNS(XMLNS, "ellipse");
	
	svgNode.id = id;
	
	svgNode.setAttribute("cx", cx);
	svgNode.setAttribute("cy", cy);
	svgNode.setAttribute("rx", rx);
	svgNode.setAttribute("rx", rx);

	svgNode.style.fill = fillColor;
	svgNode.style.stroke = strokeColor;
	svgNode.style.strokeWidth = strokeWidth;

	return svgNode;
}

// •線 <line>
// 示例:<line x1="0" y1="0" x2="300" y2="300" style="stroke:rgb(99,99,99);stroke-width:2"/>
function svgLineNode(id, x1, y1, x2, y2, strokeWidth, strokeColor){
	var svgNode = document.createElementNS(XMLNS, "line");
	
	svgNode.id = id;
	
	svgNode.setAttribute("x1", x1);
	svgNode.setAttribute("y1", y1);
	svgNode.setAttribute("x2", x2);
	svgNode.setAttribute("y2", y2);

	svgNode.style.stroke = strokeColor;
	svgNode.style.strokeWidth = strokeWidth;

	return svgNode;

}

// •多邊形 <polygon>
// 示例:<polygon points="220,100 300,210 170,250" style="fill:#cccccc; stroke:#000000;stroke-width:1"/>
function svgPolygonNode(id, points, fillColor, strokeWidth, strokeColor){
	var svgNode = document.createElementNS(XMLNS, "polygon");
	
	svgNode.id = id;
	
	svgNode.setAttribute("points", points);

	svgNode.style.fill = fillColor;
	svgNode.style.stroke = strokeColor;
	svgNode.style.strokeWidth = strokeWidth;

	return svgNode;
}

// •折線 <polyline>
// 示例:<polyline points="0,0 0,20 20,20 20,40 40,40 40,60" style="fill:white;stroke:red;stroke-width:2"/>
function svgPolylineNode(id, points, fillColor, strokeWidth, strokeColor){
	var svgNode = document.createElementNS(XMLNS, "polyline");
	
	svgNode.id = id;
	
	svgNode.setAttribute("points", points);

	svgNode.style.fill = fillColor;
	svgNode.style.stroke = strokeColor;
	svgNode.style.strokeWidth = strokeWidth;

	return svgNode;

}

// •路徑 <path>
/*
下面的命令可用於路徑數據:
•M = moveto
•L = lineto
•H = horizontal lineto
•V = vertical lineto
•C = curveto
•S = smooth curveto
•Q = quadratic Belzier curve
•T = smooth quadratic Belzier curveto
•A = elliptical Arc
•Z = closepath
*/

// 示例:
/* 螺旋
<path d="M153 334
C153 334 151 334 151 334 C151 339 153 344 156 344 C164 344 171 339 171 334 C171 322 164 314 156 314 C142 314 131 322 131 334
C131 350 142 364 156 364 C175 364 191 350 191 334 C191 311 175 294 156 294 C131 294 111 311 111 334 C111 361 131 384 156 384
C186 384 211 361 211 334 C211 300 186 274 156 274"
style="fill:white;stroke:red;stroke-width:2"/>
*/
function svgPathNode(id, d, strokeWidth, strokeColor) {
	var svgNode = document.createElementNS(XMLNS, "path");
	
	svgNode.id = id;
	
	svgNode.setAttribute("d", d);

	svgNode.style.stroke = strokeColor;
	svgNode.style.strokeWidth = strokeWidth;

	return svgNode;
}

/* 濾鏡 */
// 說明:濾鏡是CSS的一種樣式,兩者配合使用,效果最佳。

/* 在 SVG 中,可用的濾鏡有:
•feBlend
•feColorMatrix
•feComponentTransfer
•feComposite
•feConvolveMatrix
•feDiffuseLighting
•feDisplacementMap
•feFlood
•feGaussianBlur
•feImage
•feMerge
•feMorphology
•feOffset
•feSpecularLighting
•feTile
•feTurbulence
•feDistantLight
•fePointLight
•feSpotLight
*/

// 高斯模糊
// 示例:
// SVG:
//	   <defs><filter id="Gaussian_Blur"><feGaussianBlur in="SourceGraphic" stdDeviation="10" /></filter></defs>
// CSS:
//	   filter:url(#Gaussian_Blur);
function filterGuassianBlur(id, r) {
	var filter = '<defs><filter id="' + id + '">';
	filter += '<feGaussianBlur in="SourceGraphic" stdDeviation="' + r + '" /></filter></defs>';
	return filter;

}

// 添加文字

/* 漸變填充 */
// 說明:漸變填充是一種自定義的特殊顏色,可以直接作爲參數傳入上面的函數中使用,也可在CSS中指定使用。

// 線性漸變
// 示例:
// 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>
// CSS:
	// fill:url(#orange_red)
function fillLinearGradient(id, x1, y1, x2, y2, offsets, colors) {
	var fill = '<defs>';
	fill += '<linearGradient id="' + id + '" x1="' + x1 + '" y1="' + y1 + '" x2="' + x2 + '" y2="' + y2 + '">';

	for(var i = 0; i < offsets.length; i++){
		fill += ' <stop offset="'+offsets[i]+'%" style="stop-color:'+colors[i]+'"/>';
	}

	fill += '</linearGradient>';
	fill += '</defs>';
	return fill;
}

調用方法:

SVGToolDemo.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=unicode" />
<script src="SVGTool.js"></script>
<script>

function clickMe() {
	alert("!");
}

function touchMe() {
	this.style.fill = "yellow";
}

function init()
{
	// 創建根節點
	var svgRoot = svgRootNode("svg01", "100%", "100%");
	root.appendChild(svgRoot);

	// 創建SVG形狀
	var c1 = svgCircleNode("c02", 200, 100, 50, "rgba(5,100,10,0.4)", 0, "yellow");
	svgRoot.appendChild(c1);

	// 添加事件
	c1.onclick = clickMe;
	c1.onmouseover = touchMe;
	
}

</script>

</head>

<body onload = "init();">
<div id="root"></div>

</body>
</html>

後語

SVG節點創建方式是要格外注意的地方,必須用有命名空間的方式。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章