前端绘图用的最多的就是svg和canvas,现在有许多基于这两种技术的图形框架,比如基于svg的D3 和基于canvas的echarts 。今天要讲的是基于svg的Raphael Javascript ,它是一个 Javascript的矢量库。
首先你要在HTML中引入RaphaelJS
<script type="text/javascript" src="raphael.min.js"></script>
image.png
然后你就可以在js中使用这个包了
我是先建了一个名为master.js的文件,在这个文件中写js,注意两个文件的放置顺序,由于要在master.js中使用RaphaelJS,所以raphael.js的引用要放在前面
创建画布
1.以坐标点定义画布位置
var paper = Raphael(20, 30, 650, 400); 分别为横坐标,纵坐标,宽度,高度
2.以节点定义画布位置
var width = 600;var height = 200;var paper = Raphael("mySvg",width,height); //定义svg绘图节点,及宽度,高度
封装绘图函数
1.画矩形
function drawRect(x,y,w,h,radius){ var rect = paper.rect(x,y,w,h); //若绘圆角矩形加上圆角参数(横坐标,纵坐标,宽,高,圆角) rect.attr({ "fill": "red", //填充颜色 "stroke": "lime", //边框颜色 "stroke-width": 2 // 边框宽度 });}
2.画圆
function drawCircle(x,y,r){ var cir = paper.circle(x,y,r); //(圆心横坐标,圆心纵坐标,半径) cir.attr({ "fill": "blue", "stroke": "lime", "stroke-width": 2 })}
3.画椭圆
function drawEllipse(x,y,rx,ry){ //水平半径和垂直半径其实就是椭圆的rx和ry var ellipse = paper.ellipse(x,y,rx,ry); ellipse.attr({ "fill": "yellow", "stroke": "lime", "stroke-width": 2 })}
4.画上五边形
function drawDownFive(x,y,w,h){ // 传起点坐标,宽和高 // 若要使边框完整,从起始坐标到起始坐标,仅填充的话不需在后面加起始坐标或加闭合路径 // var DownFive = paper.path('M'+x+','+y+'H'+(w+x)+'V'+(h+y)+'L'+(w/2+x)+','+(h+h/2+y) // +'L'+x+','+(y+h)+'L'+x+','+y); // var DownFive = paper.path('M'+x+','+y+'H'+(w+x)+'V'+(h+y)+'L'+(w/2+x)+','+(h+h/2+y) // +'L'+x+','+(y+h)+'Z'); var DownFive = paper.path('m'+x+','+y+'h'+w+'v'+h+'l'+(-w/2)+','+(h/2)+'l'+(-w/2)+','+(-h/2)+'Z');//相对坐标 DownFive.attr({ "fill": 'orangered', "stroke": 'lime', "stroke-width": 2 }); }
5.添加文字
function drawText(x,y,txt){ // 横坐标+纵坐标+文本 var tip = paper.text(x,y,txt); tip.attr({ "font-size": 16, //字体大小 "fill": 'brown', //字体颜色 "text-anchor":"middle", // 字体对齐样式 }); } drawText(200,140,"椭圆弧的使用");
Raphael元素的变换
// T 平移
// S 缩放 Sx,y 横向缩放x倍,纵向缩放y倍
// R 按角度旋转
// M 变换矩阵
// 每个字母是一个命令 t是平移,r是旋转,s是缩放,m是矩阵
// 也有另类的“绝对”平移、旋转和缩放:T、R和S。他们不会考虑到以前的变换
var rect1 = paper.rect(20,300,100,50); rect1.attr({ "transform": 'r90T100,0s0.5' });
Raphael图形的动画效果
// 语法如下:Element.animate({动画属性的键值对},动画时间,缓动类型,回调函数);
// 缓动类型其实就是动画过渡公式,是哪种类型的。主要有以下这些类型:
// “linear”(线性)
// “<”或“easeIn”或“ease-in” (由慢到快)
// “>”或“easeOut”或“ease-out”(又快到慢)
// “<>”或“easeInOut”或“ease-in-out”(由慢到快再到慢)
// “backIn”或“back-in”(开始时回弹)
// “backOut”或“back-out”(结束时回弹)
// “elastic”(橡皮筋)
// “bounce”(弹跳)
rect1.animate({transform: "r90t100,0s1.5"}, 1000,"bounce",function(){console.log("finish");});
事件绑定
var rect2 = paper.rect(60,300,100,50,10);rect2.attr('fill', 'blue');rect2.mouseover(function() { //绑定鼠标悬浮事件,其他事件类似 rect2.attr({ "transform": 'T0,50s2', "fill": '#000' });});rect2.mouseout(function() { rect2.attr({ "fill": 'blue', "transform": 'T0,0s1' });});
clone() 复制一个
var rect3 = rect2.clone().attr({ "x": 400, "y": 400});
画布的方法
// 画布的方法
// paper.clear(); // paper.clear()方法清空画布
// 加载图片 paper.image()
// 参数 说明
// src 图片的路径,对经常写前台的童鞋们来说这个小菜一碟
// X 图片摆放位置的x坐标
// Y 图片摆放位置的y坐标
// width 图片的宽度
// height 图片的高度
// 例:paper.image("images/testimage.png",10,10,200,150);将在画布的(10,10)位置摆放一个宽200,长150的图片。
// paper.setSize()用来重新设置画布的大小。你以在发现画布大小不合适时调整画布的大小
// 而不是需要从头建立画布然后重复原来的工作。方法有2个参数:宽和高
paper.setSize(1000,1000);// 我们将画布的大小修改为宽100px,1000px。
// paper.set()方法是个很重要的方法。它帮助我们对Raphael元素进行分组然后进行批量管理
var rect4 = paper.rect(300,600,100,50,10); var circle1 = paper.circle(400,680,50); var set = paper.set(); set.push(circle1,rect4); // set.clear(); // set.exclude(circle1); // set.attr('fill', 'green'); // 我们想要清空set,可不要用remove()而是用clear(),remove()会把所有set里面的元素remove掉。 // clear()只是清除set里的内容,并不会对里面的内容本身有影响 // set.exclude(rect);还记得我前面的代码里面将rect添加进入raphaelSet里面吗? // 现在你可以试一试在在执行raphaelSet.attr()之前使用raphaelSet.exclude(rect); // 试一试。效果和我们想象的一样,第一个矩形没有被填充红色,因为它被从set里面剔除出来了。 // set.forEach()就是去循环我们创建的set对象,然后通过遍历对set内的元素进行操作。 // 这个功能是差不多算是set里面最重要的方法了,我们使用set大部分业务都需要这个循环了 set.forEach(function(ele){ ele.attr({"fill":"red"});});
// set.pop(); 清除最后一个添加进去的元素
// set.splice()方法 它有3个参数index,count,element set.splice(1,2,rect),
// 我从set里面index为1的位置开始往后删除2个元素,然后把rect添加进来。所以slice可以同时删除和添加元素
透明度
// 元素透明度键名opacity,取值范围为0(完全不透明)到1(完全透明),也可以分别设置stroke-opacity和fill-opacity
var circle2 = paper.circle(600,680,50); circle2.attr({ "fill": 'blue', "stroke": 'lime', "stroke-width":5, "fill-opacity":0.5 }); // Raphael支持通过clip-rect属性来进行元素的矩形切割,它允许我们将图形切割出一部分下来 circle2.attr('clip-rect', '545,625,50,50');
Raphael支持线性和梯度渐变去填充图形,要达到这个效果,而不是直接用一个颜色的字符串去设置fill属性。
我们需要指定了下面这种字符串的格式去做到线性渐变:
<angle>-<color>[-<color>[:<offset>]]-<color>
下面的语法就是达到径向渐变的效果:
r[(<fx>,<fy>)]<color>[-<color>[:<offset>]]-<color>
1.线性渐变 <angle>-<color1>-<color2>
var rect5 = paper.rect(760,600,100,80); rect5.attr('fill', '0-red-blue'); rect5.attr('fill', '45-red-yellow');
2.径向渐变 r<color>-<color>
var circle3 = paper.circle(940,650,50); circle3.attr('fill', 'rblack-white-black'); circle3.attr('fill', 'rblack-white:80-black'); //以半径的80%处为第二阶段的渐变分割点
3.偏离圆心的渐变
var circle4 = paper.circle(70,900,50); var circle5 = paper.circle(200,900,50); var circle6 = paper.circle(330,900,50); var circle7 = paper.circle(460,900,50); var circle8 = paper.circle(590,900,50); circle4.attr('fill', 'r(0.1,0.5)#fff-#000'); //r(0.5,o.5)是正圆心 circle5.attr('fill', 'r(0.5,0.1)#fff-#000'); circle6.attr('fill', 'r(0.9,0.5)#fff-#000'); circle7.attr('fill', 'r(0.5,0.9)#fff-#000'); circle8.attr('fill', 'r(0.5,0.5)#c8c8c8-#000');
给线条加箭头
路径的末尾显示箭头。字符串格式是<type>[-<width>[-<length>]]。
可能的类型:classic、block、open、oval、diamond、none
宽:wide、narrow、midium,长:long 、short、midium。
var arrow = paper.path("M20,960L120,960").attr('stroke', 'lime'); //绘一条直线 arrow.attr({ "arrow-end":'classic-wide-midium', //加箭头属性 "stroke-width":3 });
线条虚化
stroke-dasharray string [“”, “-”, “.”, “-.”, “-..”, “.”, “- ”, “--”, “- .”, “--.”, “--..”]
var dottedLine = paper.path("M200,960,L300,960"); dottedLine.attr({ "stroke": 'blue', //先给个颜色 "stroke-dasharray": '-.' });
线段端点处理
stroke-linecap string [“butt”, “square”, “round”]
var lineCap = paper.path("M320,960L420,960"); lineCap.attr({ "stroke": 'red', "stroke-linecap": 'butt', "stroke-width": 10 });
stroke-linejoin 属性指明路径的转角处使用的形状或者绘制的基础形状。
stroke-linejoin string [“bevel”, “round”, “miter”]
var linejoin = paper.path("M440,960L500,960L500,1000"); linejoin.attr({ "stroke": 'orangered', "stroke-linejoin": 'bevel', "stroke-width": 5 });