svg和vml自己写的公用类

目标:了解vml和svg的兼容性写法
实现方式:代码和说明lizhi.js
由于时间仓促,类库写的很草率,纯粹一时性起玩乐之作,不过基本思路和兼容方式基本就是这样的,可能一些细节没太在意。
如果你真的想做一个svg和vml兼容类库可以参考代码思路,自己创作。如果有什么问题可以联系我,很乐意帮你解决。
/*
* 玩乐之作,思路经供参考。
* lizhi.0.1.js 
* 作者:荔枝小站fanlizhi
*/
/*
*判断属性是否属于对象
*是返回true 不是返回 false
*/
function isEmptyObject(obj){ 
	for(var name in obj){
		return false;
	}
	return true;
}
/*
*基础全局对象F
*id canvas的外部div
*/
function F (id) {
	return new F.prototype.init(id);
}
/*
* F.prototype 初始方法和属性
* F.prototype.init 返回 div dom 和 canvas 画板
* version 版本
* _NS svg xml命名空间
* _ISSVG 是否SVG
* _CNAME vml与元素关联的className
*/ 
F.fn = F.prototype = {
	init : function(id){
		this.c = document.getElementById(id);
		this.r = this.initC();
		return this;
	},
	version : '0.1',
	_NS : 'http://www.w3.org/2000/svg',
	_ISSVG : true,
	_CNAME : 'fan'
}
/*
* F.prototype.initC
* 返回画板
*/
F.fn.initC = function(){
	if(document.createElementNS){
		var r = document.createElementNS(this._NS,'svg');
		r.setAttribute('vesion','1.1');
		r.setAttribute('xmlns',this._NS);
		r.setAttribute('style','width:100%;height:100%;');
	}else{
		var head = document.getElementsByTagName("head")[0];
		var style = document.createElement("style");
		var r = document.createElement("div");
		this._ISSVG = false;
		document.namespaces.add("v", "urn:schemas-microsoft-com:vml");//添加命名空间
		var cssStr = '.fan {behavior:url(#default#VML);} v\:*{behavior:url(#default#VML);}';	//添加元素和vml的关系
		style.type = 'text/css';		
		style.styleSheet.cssText = cssStr;
		head.appendChild(style);//添加到head里面
		r.setAttribute('style','position:absolute;width:100%;height:100%;');
	}
	this.c.appendChild(r);
	return r;
}
/*
* F.prototype.Line 
* 返回line的element对象
*/
F.fn.Line = function(x1,y1,x2,y2){
	return new E.prototype.initLine(this,x1,y1,x2,y2);
}
/*
* F.prototype.Path 
* 返回Path的element对象
*/
F.fn.Path = function(path){
	return new E.prototype.initPath(this,path);
}
/*
* F.prototype.Rect 
* 返回Rect的element对象
*/
F.fn.Rect = function(x,y,width,height,corner){
	return new E.fn.initRect(this,x,y,width,height,corner);
}
/*
* F.prototype.ellipse 
* 返回Ellipse的element对象
*/
F.fn.Ellipse = function(cx,cy,rx,ry){
	return new E.fn.initEllipse(this,cx,cy,rx,ry);
}
/*
* 将 F.prototype 属性,方法添加到 F.prototype.init.prototype 上
* 将 将F的全局方法属性给画布
*/
F.fn.init.prototype = F.fn;
/*
* ELement 对象
*/
function E(){}
/*
* E.prototype 放属于element的参数
* _VML, SVG 中的attr为统一样式名
*/

E.fn = E.prototype = {
	_VML : {'attr':{'stroke-width':'strokeweight','stroke':'strokecolor','opacity':'opacity','dashstyle':'dashstyle','joinstyle':'joinstyle','fill':'fillcolor','src':'src'}},
	_SVG : {'attr':{'stroke-width':'stroke-width','stroke':'stroke','opacity':'fill-opacity','dashstyle':'stroke-dasharray','joinstyle':'stroke-linecap','fill':'fill','src':'href'}}
}
E.fn.svgFormatDashstyle = function (val) {
	var strokew = this.dom.getAttribute('stroke-width');
	
	switch (val) {
		case 'Dash':
		return strokew*4+','+strokew*5;
		break;
		case 'Dot':
		return strokew*1+','+strokew*4;
		break;
		default:
		return 'none';
	}
}
/*
* 初始化样式属性
*/
E.fn.initAttr = function(el,attrs){
	var attrs = attrs || {};
	if(!this.F._ISSVG){
		var stroke = document.createElement("stroke");
		stroke.className = this.F._CNAME;
		el.appendChild(stroke);
		var fill = document.createElement("fill");
		fill.className = this.F._CNAME;
		el.appendChild(fill);
		fill.setAttribute('opacity','0');
	}else{
		el.setAttribute('stroke','#000');//默认
		el.setAttribute('fill','none');//默认 兼容vml
	}
	if(el.nodeName === 'path'){
		el.setAttribute('stroke','#000');//默认
		el.setAttribute('fill','none');//默认 兼容vml
	}
	return el;
}
/*
* 调用path的时候初始化vml shape
*/
E.fn.initPath_VML = function(F){
	var dom = document.createElement("shape");
	dom.style.position = 'absolute';
    dom.style.width = '1px';
    dom.style.height= '1px';
	dom.setAttribute('coordsize','1,1');
	dom.className = F._CNAME;
	return dom;
}

/*
* 调用path的时候初始化SVG path
*/
E.fn.initPath_SVG = function(F){
	var dom = document.createElementNS(F._NS,"path");
	return dom;
}
/*
* E.prototype.initLine 初始化 line对象
*/
E.fn.initLine = function(F,x1,y1,x2,y2){
	if (F._ISSVG) {
		var dom = document.createElementNS(F._NS,"line");
		dom.setAttribute('x1',x1);
		dom.setAttribute('y1',y1);
		dom.setAttribute('x2',x2);
		dom.setAttribute('y2',y2);
		dom.setAttribute('stroke','#000');
	}else{
		var dom = this.initPath_VML(F);
		var path = 'M'+x1+' '+y1+'L'+x2+' '+y2+'e';
		dom.path = path;
	}
	this.F = F;
	this.dom = dom;
	dom = this.initAttr(dom);
	F.r.appendChild(dom);
	return this;
}

/*
* E.prototype.initPath 初始化 path对象
*/
E.fn.initPath = function(F,path){
	path = path.toUpperCase();
	if(F._ISSVG){
		var dom = E.fn.initPath_SVG(F);
		dom.setAttribute('d',path);
	}else{		
		var dom = E.fn.initPath_VML(F);
		var path = path.replace('Z','X');
		dom.path = path;
	}	
	this.F = F;
	this.dom = dom;
	dom = this.initAttr(dom);
	F.r.appendChild(dom);
	return this;
}

/*
* E.prototype.initRect 初始化 rect对象
* points:{x,y,width,height}
*/
E.fn.initRect = function(F,x,y,width,height,corner){
	var IScorner = false;
	if(corner != 0 && typeof corner ==='number'){
		var shortL = width > height ? height : width;
		if(corner >= shortL>>1){
			corner = shortL>>1;
		}
		IScorner = true;
	}
	if(F._ISSVG){
		var corner = corner || 0;
		var dom = document.createElementNS(F._NS,"rect");
		dom.setAttribute('x',x);
		dom.setAttribute('y',y);
		dom.setAttribute('width',width);
		dom.setAttribute('height',height);
		if (IScorner) {
			dom.setAttribute('rx',corner);
			dom.setAttribute('ry',corner);
		}
	}else{		
		var dom = this.initPath_VML(F);
		var path ='';
		if(x && y && typeof x === 'number' && typeof y === 'number' && width && height && typeof width === 'number' && typeof height === 'number'){
			var xl = x + width,yl = y + height;
			if(IScorner){
				var x1 = x+corner,y1 = y+corner,x4 = xl-corner,y4 = yl-corner;
				path += 'M'+x1+' '+y+'L'+x4+' '+y+'qx'+xl+' '+y1+'L'+xl+' '+y4+'qy'+x4+' '+yl+'L'+x1+' '+yl+'qx'+x+' '+y4+'L'+x+' '+y1+'qy'+x1+' '+y+' z';
			}else{
				path += 'M'+x+' '+y+' ';
				path += 'L'+ xl +' '+ y;
				path += 'L'+ xl +' '+ yl;
				path += 'L'+ x +' '+ yl +'xe';
			}
		}
		dom.path = path;
	}
	this.F = F;
	this.dom = dom;
	dom = this.initAttr(dom);
	F.r.appendChild(dom);
	return this;
}

/*
* E.prototype.initRect 初始化 rect对象
* points:{x,y,width,height}
*/
E.fn.initEllipse = function(F,cx,cy,rx,ry){
	if(F._ISSVG){
		var dom = document.createElementNS(F._NS,"ellipse");
		dom.setAttribute('cx',cx);
		dom.setAttribute('cy',cy);
		dom.setAttribute('rx',rx);
		dom.setAttribute('ry',ry);		
	}else{		
		var dom = this.initPath_VML(F);
		var path ='ae'+cx+' '+cy+' '+rx+' '+ry+' 0 23592960X';		
		dom.path = path;
	}	
	this.F = F;
	this.dom = dom;
	dom = this.initAttr(dom);
	F.r.appendChild(dom);
	return this;
}

E.fn.initLine.prototype = E.fn;

E.fn.initPath.prototype = E.fn;

E.fn.initRect.prototype = E.fn;

E.fn.initEllipse.prototype = E.fn;
我这还有一 调用的例子,可以通过下面的方式测试一下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="lizhi.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function(){
	var paper = F("dv");
	var line = paper.Line(5,50,100,50);
	var path = paper.Path('M5 100 C5 150 200 200 100 250');
	var rect = paper.Rect(300,300,100,100,20);
	var ellipse = paper.Ellipse(300,100,20,50);
	var path1 = paper.Path('M100 100L200 100Z');

}
</script>
</head>
<body>
<div id="dv" style="width:800px;height:500px; background:#ceafec"></div>
</body>
</html>
下面是在我电脑上跑的样子:


新的博客迁移至: l-zhi.com
虽然代码不多300来行,但是我也花了不少时间研究svg 和vml。 转载请写明出处,你的支持才是我分享的动力。
如果时间精力允许的话我可能会加入img和text,以及样式的更改方法,当然还得希望公司别再老加班了 大哭

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值