自动选择SVG和VML的WEB页面
来源:互联网 发布:孤岛惊魂3视频优化 编辑:程序博客网 时间:2024/05/22 10:54
自动选择SVG和VML的WEB页面
问题
在WEB上使用二维图形编程的人员现在面临者一个两难的选择,是使用SVG,还是VML?二者的功能相似,可以满足大多数WEB二维图形应用的需求,但目前的情况是:VML只能在IE中使用,SVG被firefox,opera等浏览器的最新版本支持,并且是W3C制定的开放标准,但目前IE不内置支持SVG,只能通过ADOBE的SVG插件显示。
对于有特定用户的应用,可能选择哪一种技术都可以,软件提供方可以要求用户安装和配置所需的环境。但对于面向INTERNET用户的应用,例如网上地图等,这个问题就比较明显了。IE无疑是最广泛使用的浏览器,而且大多数用户在不了解网站内容的情况下,不会选择下载并安装一个4M多的SVG插件。而在技术上,SVG无疑前景更光明,而且被其它浏览器支持,可以被非WINDOWS平台用户使用。
思路
能否通过用户浏览器的类型,自动在SVG和VML之间切换,以在浏览器上显示同样(或基本相似)的图形?(下面提到的SVG都是SVG1.1标准)
解决方法
1, 根据用户浏览器情况,设置显示标志
//设置使用SVG显示标志,缺省为使用
var useSVG = true;
//如果为IE则使用VML
if (navigator.appName == "Microsoft Internet Explorer")
useSVG = false;
//如果为其它浏览器,则使用SVG,这里用Opera
if (navigator.userAgent.search("Opera")>=0)
useSVG = true;
2, 在HTML初始化时,加载SVG或VML对象
if(useSVG)
{
var elem = document.createElement("embed");
elem.id = "svgCanvas";
elem.width = 500;
elem.height = 500;
elem.name = "svgCanvas";
elem.src = "canvas.svg";
elem.wmode = "transparent";
elem.type = "image/svg+xml";
document.body.insertBefore(elem,null);
}
else
{
var elem = document.createElement("v:group");
elem.id = "vmlCanvas";
elem.style.width = 500 + "px";
elem.style.height = 500 + "px";
elem.coordsize = "200,200";
document.body.insertBefore(elem,null);
}
之后,我们就可以分别在SVG或VML画布上进行操作了。当然最好是定义一个与显示无关的图形对象。
3, 图形对象,此处为一个简单的圆
function Bubble(id, cx, cy, r, stroke, fill)
{
this.id = id;
this.cx = cx;
this.cy = cy;
this.r = r;
this.stroke = stroke;
this.fill = fill;
this.draw = draw;
this.move = move;
}
其显示和移动实现为:
function draw()
{
if(useSVG)
{
//alert("svg");
var svgDocument = GetSvgDocument();
if(svgDocument == null)
return;
var elem = svgDocument.createElementNS(svgns, "circle" );
elem.setAttributeNS(null, "id", this.id);
elem.setAttributeNS(null, "cx", this.cx);
elem.setAttributeNS(null, "cy", this.cy);
elem.setAttributeNS(null, "r", this.r);
elem.setAttributeNS(null,"stroke",this.stroke);
elem.setAttributeNS(null,"fill",this.fill);
var svgCanvas = GetSvgCanvas();
if(svgCanvas == null)
return;
svgCanvas.appendChild(elem);
}
else
{
//alert("vml");
var elem = document.createElement("v:oval");
with (elem.style)
{
position="absolute";
top=this.cy - this.r;
left=this.cx - this.r;
width=parseInt(this.r*2);
height=parseInt(this.r*2);
}
elem.coordorigin = "0,0";
elem.strokecolor=this.stroke;
elem.FillColor = this.fill;
vmlCanvas.insertBefore(elem,null);
}
}
function move(x, y)
{
this.cx = x;
this.cy = y;
}
4, 使用
var bubble1 = new Bubble("b1", 100, 100, 30, "purple", "green");
bubble1.draw();
var bubble2 = new Bubble("b2", 30, 20, 20, "red", "yellow");
bubble2.draw();
VML显示:
SVG显示
5,注意事项:
l 通过上面的图可以看出,尽管比较相似,但还是有所不同,例如圆的边线由于使用的是缺省属性,SVG和VML使用的笔画粗细是不同。因此要显示完全相同的图形要付出很大的工作量。
l 尽管SVG和VML在大多数情况下可以互相替换,但还是有一些对方不支持的特性和属性。例如SVG中的动画(animate)等,这些要在VML-SVG混合时尽量避免使用,实在不行就只能使用脚本模拟实现了。
l SVG为独立的嵌入对象,因此要使用embedded列表取得,而VML可以直接使用HTML的文档对象。在SVG动态嵌入时,要判断加载情况,在加载完成后才可以操作。
在SVG中加载事件中通知HTML
function OnLoadEvent(evt)
{
window.parent.svgLoadFlag = true;
}
在HTML初始化时,等待SVG加载完成标志
if(useSVG)
{
//Wait svg load event
if ( svgLoadFlag == false )
{
setTimeout("renderObjects()",100);
return;
}
}
l 如果使用交互事件,例如鼠标操作等,SVG和VML的事件对象结构是不同的,传递方式也不相同,应分别处理,不过一般在得到事件对象的属性,例如坐标位置,产生事件对象ID后,就可以使用相同的处理函数了。例如:
//SVG的事件处理
function svgClick(evt)
{
var choiceId = evt.target.getAttributeNS(null,"id");
selectChoice(choiceId);
}
//VML事件处理
function vmlClick()
{
var choiceId = event.srcElement.name;
selectChoice(choiceId);
}
因此在VML/SVG混合编程时,采用MODEL-VIEW-CONTROL方式是比较好的一种模式。
附:SVG和VML元素对应表(不全)
名称
SVG
VML
描述
矩形
rect
rect
圆角矩形
roundrect
SVG中通过rect属性实现
直线
line
line
圆
circle
oval
椭圆
ellipse
oval
折线
polyline
polyline
多边形
polygon
shape
曲线
arc
SVG中可以使用circle或path实现
路径
path
path
文本
text
textbox
文本段
tpan
路径文本
textPath
textPath
标题
title
描述
desc
组
group
group
预定义图形
defs
vmlframe
滤镜
filter
线性渐变
linearGradient
圆形渐变
radialGradient
图案
pattern
箭头
marker
在stroke的属性StartArrow和EndArrow实现
剪裁
clippath
遮盖
mask
链接
a
重用
use
vmlframe
图形
symbol
shape
光栅图像
image
image
完整代码
HTML
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<title>VML-SVG-DEMO</title>
<STYLE>...
v:* {...}{ BEHAVIOR: url(#default#VML) }
</STYLE>
<script src="objects.js" language="JavaScript" type="text/javascript"></script>
<script src="initial.js" language="JavaScript" type="text/javascript"></script>
</head>
<body onload="init()"></body>
</html>
<head>
<title>VML-SVG-DEMO</title>
<STYLE>...
v:* {...}{ BEHAVIOR: url(#default#VML) }
</STYLE>
<script src="objects.js" language="JavaScript" type="text/javascript"></script>
<script src="initial.js" language="JavaScript" type="text/javascript"></script>
</head>
<body onload="init()"></body>
</html>
SVG
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200" onload="OnLoadEvent(evt)">
<g id="Canvas"></g>
<script type="text/ecmascript">...
<![CDATA[
function OnLoadEvent(evt)
...{
window.parent.svgLoadFlag = true;
}
]]>
</script>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200" onload="OnLoadEvent(evt)">
<g id="Canvas"></g>
<script type="text/ecmascript">...
<![CDATA[
function OnLoadEvent(evt)
...{
window.parent.svgLoadFlag = true;
}
]]>
</script>
</svg>
初始化脚本
//useSVG = true; //you can also change this by hand
function renderObjects()
...{
if(useSVG)
...{
//Wait svg load event
if ( svgLoadFlag == false )
...{
setTimeout("renderObjects()",100);
return;
}
}
//alert(svgLoadFlag);
var bubble1 = new Bubble("b1", 100, 100, 30, "purple", "green");
bubble1.draw();
var bubble2 = new Bubble("b2", 30, 20, 20, "red", "yellow");
bubble2.draw();
}
function init()
...{
// Write svg embed object or vml group into html body
//
//<embed width='500' height='500' name='svgCanvas' src='canvas.svg' wmode='transparent' type='image/svg+xml' />
//<v:group id='vmlCanvas' style='WIDTH:500px;HEIGHT:500px;' coordsize = '200,200'/>;
if(useSVG)
...{
var elem = document.createElement("embed");
elem.id = "svgCanvas";
elem.width = 500;
elem.height = 500;
elem.name = "svgCanvas";
elem.src = "canvas.svg";
elem.wmode = "transparent";
elem.type = "image/svg+xml";
document.body.insertBefore(elem,null);
}
else
...{
var elem = document.createElement("v:group");
elem.id = "vmlCanvas";
elem.style.width = 500 + "px";
elem.style.height = 500 + "px";
elem.coordsize = "200,200";
document.body.insertBefore(elem,null);
}
//Create graphic object and draw
renderObjects();
}
function renderObjects()
...{
if(useSVG)
...{
//Wait svg load event
if ( svgLoadFlag == false )
...{
setTimeout("renderObjects()",100);
return;
}
}
//alert(svgLoadFlag);
var bubble1 = new Bubble("b1", 100, 100, 30, "purple", "green");
bubble1.draw();
var bubble2 = new Bubble("b2", 30, 20, 20, "red", "yellow");
bubble2.draw();
}
function init()
...{
// Write svg embed object or vml group into html body
//
//<embed width='500' height='500' name='svgCanvas' src='canvas.svg' wmode='transparent' type='image/svg+xml' />
//<v:group id='vmlCanvas' style='WIDTH:500px;HEIGHT:500px;' coordsize = '200,200'/>;
if(useSVG)
...{
var elem = document.createElement("embed");
elem.id = "svgCanvas";
elem.width = 500;
elem.height = 500;
elem.name = "svgCanvas";
elem.src = "canvas.svg";
elem.wmode = "transparent";
elem.type = "image/svg+xml";
document.body.insertBefore(elem,null);
}
else
...{
var elem = document.createElement("v:group");
elem.id = "vmlCanvas";
elem.style.width = 500 + "px";
elem.style.height = 500 + "px";
elem.coordsize = "200,200";
document.body.insertBefore(elem,null);
}
//Create graphic object and draw
renderObjects();
}
对象脚本
var useSVG = true;
var svgLoadFlag = false;
if (navigator.appName == "Microsoft Internet Explorer")
useSVG = false;
if (navigator.userAgent.search("Opera")>=0)
useSVG = true;
//alert(useSVG);
var svgns = "http://www.w3.org/2000/svg";
var xlinkNS = "http://www.w3.org/1999/xlink";
function GetSvgDocument()
...{
return(document.embeds[0].getSVGDocument());
}
function GetSvgCanvas()
...{
return(document.embeds[0].getSVGDocument().getElementById("Canvas"));
}
///
/// Bubble class
///
function Bubble(id, cx, cy, r, stroke, fill)
...{
this.id = id;
this.cx = cx;
this.cy = cy;
this.r = r;
this.stroke = stroke;
this.fill = fill;
this.draw = draw;
this.move = move;
}
function draw()
...{
if(useSVG)
...{
//alert("svg");
var svgDocument = GetSvgDocument();
if(svgDocument == null)
return;
var elem = svgDocument.createElementNS(svgns, "circle" );
elem.setAttributeNS(null, "id", this.id);
elem.setAttributeNS(null, "cx", this.cx);
elem.setAttributeNS(null, "cy", this.cy);
elem.setAttributeNS(null, "r", this.r);
elem.setAttributeNS(null,"stroke",this.stroke);
elem.setAttributeNS(null,"fill",this.fill);
var svgCanvas = GetSvgCanvas();
if(svgCanvas == null)
return;
svgCanvas.appendChild(elem);
}
else
...{
//alert("vml");
var elem = document.createElement("v:oval");
with (elem.style)
...{
position="absolute";
top=this.cy - this.r;
left=this.cx - this.r;
width=parseInt(this.r*2);
height=parseInt(this.r*2);
}
elem.coordorigin = "0,0";
elem.strokecolor=this.stroke;
elem.FillColor = this.fill;
vmlCanvas.insertBefore(elem,null);
}
}
function move(x, y)
...{
this.cx = x;
this.cy = y;
}
///
/// Bubble class finish
///
- 自动选择SVG和VML的WEB页面
- 自动选择SVG和VML的WEB页面
- 自动选择SVG和VML的WEB页面
- Web图形开发,选择SVG还是VML
- Javascript 对SVG和 VML的封装
- [HTML5-SVG,VML,CANVAS]Web开发中的矢量绘图(vml,svg)处理和应用
- SVG和VML
- Vml和Svg教程
- GML、SVG和VML介绍
- <canvas> 标记和 SVG 以及 VML 之间的差异
- svg和vml自己写的公用类
- GML、SVG、VML的比较
- GML、SVG、VML的比较
- GML、SVG、VML的比较
- GML、SVG、VML的比较
- GML、SVG、VML的比较
- GML、SVG、VML的比较
- GML、SVG、VML的比较
- UML读书笔记(1)
- 中科院信息安全国家重点实验室博士考试专业课试题
- 如何用javascript获得TextArea中的光标位置
- Alexa排名猛升21,956位(www.mobi123.cn,手机网址之家)
- JBoss Eclipse IDE
- 自动选择SVG和VML的WEB页面
- 网页javascript精华代码集
- 半年的目标
- WEB开发中的JAVA字符编码
- eclipse3.2.1+lomboz3.2安装与配置
- 如何取得 Sqldatasource 中的数据集合
- 用javamail发送邮件
- 关于智能卡(2)
- 在VS.NET 2005中体验clickonce技术