一、简介
Raphael JS是一个用于在网页中绘制矢量图形的Javascript库。它使用SVG W3C推荐标准和VML作为创建图形的基础,几乎所有的浏览器都支持。Raphael绘制出的内容是真实的DOM节点,不仅可以通过动态修改它的大小、颜色等操作来创建你想要的内容,而且可以为你创建的内容赋予点击,悬停,动画等操作。
二、安装
1、script标签:
2、AMD加载方式:
define([ 'path/to/raphael' ], function( Raphael ) {
console.log( Raphael )
});
3、npm安装:
npm i raphael -S
三、使用:
1、创建画布
Raphael有两种创建画布的方式:第一种是在浏览器窗口上创建画布,第二种是在元素上创建画布(建议使用第二种)。
第一种:在浏览器窗口上创建画布
var paper = Raphael(x, y, width, height); // x坐标 y坐标 宽度 高度
这样的画布是定位在浏览器窗口的,所以画布的位置绝对定位,所以它会和其他的HTML元素发生重叠。
第二种:在一个元素中创建画布
var paper = Raphael(element, width, height); // 元素节点本身或ID 宽度 高度
要在一个元素上创建画布,需要传入元素本身或元素ID
// 以元素本身作为参数
var paper = Raphael(document.getElementById('paper'), 500, 500);
// 以元素ID作为参数
var paper = Raphael('paper', 500, 500);
2、绘制基础图形
Raphael可绘制的基础图形有圆形、矩形、椭圆:
paper.circle(x, y, r); // x坐标 y坐标 半径
paper.rect(x, y, width, height, r); // x坐标 y坐标 宽度 高度 圆角半径(可选)
paper.ellipse(x, y, rx, ry); // x坐标 y坐标 水平半径 垂直半径
3、给图形设置属性
使用attr方法给图形设置属性,attr方法可以接受一个或两个参数:
paper.circle(200, 25, 20).attr({
'fill': 'blue',
'stroke': 'red',
'stroke-width': 1
})
paper.rect(235, 5, 70, 40).attr('fill', 'yellow')
paper.ellipse(345, 25, 25, 15).attr('stroke-width', 4)
读取图形属性:
let circleAttr = circle.attr(['fill', 'stroke'])
let rectAttr = rect.attr('fill')
4、绘制复杂图形
除了圆形、矩形、椭圆。在使用中我们往往还需要绘制一些例如三角形、心形等图形。这时就要使用path方法来绘制图形了。path方法只有一个参数(SVG格式的路径字符串paper.path([pathString])),路径字符串由一个或多个命令组成。每个命令以一个字母开始,随后是逗号(',')分隔的参数。例如:
'M10,20 L30,40'
我们看到两个命令:'M'与参数(10, 20)和'L'与参数(30, 40),大写字母的意思是命令是绝对的,小写是相对的。
这里是可用命令的简表,详细内容请参照:SVG路径字符串格式 。
let paper = Raphael('complexShapes', 800, 100)
paper.path('M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z')
.attr({ 'fill': 'red', 'stroke-width': 0 }) // 心形图案1
paper.path('M100,30 L110,30 L110,20 L130,20 L130,30 L140,30 L140,20 L160,20 L160,30 L170,30 L170,50 L160,50 L160,60 L150,60 L150,70 L140,70 L140,80 L130,80 L130,70 L120,70 L120,60 L110,60 L110,50 L100,50 Z')
.attr('fill', 'green') // 心形图案2
paper.path('M190,40 L215,15 L240,40 L265,15 L290,40 L240,90 Z').attr('fill', 'purple') // 心形图案3
paper.path('M305,20 l0,70 Z').attr('stroke-width', 2) // 垂直直线
paper.path('M315,55 l80,0 Z').attr('stroke-width', 2) // 水平直线
paper.path('M415,35 l40,40, l40,-40').attr('stroke-width', 2) // 折线
paper.path('M515,75 l40,-40, l40,40 Z').attr('stroke-width', 2) // 三角形
paper.path('M620,50 L720,50') // 绘一条直线
.attr({
'stroke': 'lime',
'stroke-width': 3,
'arrow-end': 'classic-wide-midium' // 加箭头属性
})
给线条加箭头
路径的末尾显示箭头。字符串格式是[- [- ]]。
可能的类型:classic、block、open、oval、diamond、none
宽:wide、narrow、midium,长:long 、short、midium。
5、绘制其他图形
(1)绘制文字
text方法是用来绘制文本的,如果你需要换行,使用“\n”。有三个参数,paper.text(x, y, text);。x坐标、y坐标、文本字符串。
可以给text设置属性attr。如:font-size、text-anchor、font-family、fill属性。其中text-anchor属性有三个值:start、middle、end,分别表示实作坐标开始、为中心还是结尾,默认为middle。
paper.text(10, 50, '绘制出来的文字').attr({
'font-size': 20,
'font-family': 'STXingkai',
'text-anchor': 'start'
}) // 绘制文字
(2)引入图片
Raphael可以使用paper.image()方法引入图片。该方法有五个参数:src、x、y、width、height(源图像的URI、x坐标、y坐标、宽度、高度)。
paper.image(’./abc.png‘, 600, 20, 600, 600);
6、绘制渐变图形
Raphael支持线性和梯度渐变去填充图形:
线性渐变语法:
径向渐变语法:
r[(
// 线性渐变
paper.rect(5, 5, 100, 80)
.attr('fill', '0-red-blue')
.attr('fill', '45-red-yellow')
// 径向渐变
paper.circle(170, 50, 40)
.attr('fill', 'rblack-white-black')
.attr('fill', 'rblack-white:60-black') // 以半径的60%处为第二阶段的渐变分割点
// 偏离圆心的渐变
paper.circle(280, 50, 40).attr('fill', 'r(0.1,0.5)#fff-#000') // r(0.5,o.5)是正圆心
paper.circle(390, 50, 40).attr('fill', 'r(0.5,0.1)#fff-#000')
paper.circle(510, 50, 40).attr('fill', 'r(0.9,0.5)#fff-#000')
paper.circle(630, 50, 40).attr('fill', 'r(0.5,0.9)#fff-#000')
7、添加事件
Raphael一般具有以下事件:
click、dblclick、drag、hide、hover、mousedown、mouseout、mouseup、mouseover等以及对应的解除事件,只要在前面加上“un”就可以了(unclick、undblclick)。
(1) hover、click
let circle = paper.circle(25, 25, 20).attr({ 'fill': 'purple', 'cursor': 'pointer' })
.hover(
() => circle.attr('fill', 'blue'), // f_in
() => circle.attr('fill', 'purple') // f_out
)
let ellipse = paper.ellipse(90, 25, 25, 15).attr({ 'fill': 'pink', 'cursor': 'pointer' })
.click(() => {
let fillColor = ellipse.attr('fill') === 'pink' ? 'green' : 'pink'
ellipse.attr('fill', fillColor)
})
(2)drag
let rect = paper.rect(140, 5, 70, 40).attr({ 'fill': 'yellow', 'cursor': 'pointer' })
let rectX, rectY
rect.drag(
(dx, dy) => { // onmove
let x = rect.attr('x')
let y = rect.attr('y')
dx = (x + dx) > 730 ? (730 - x) : ((x + dx) < 0 ? (0 - x) : dx)
dy = (y + dy) > 60 ? (60 - y) : ((y + dy) < 0 ? (0 - y) : dy)
rectX = x + dx
rectY = y + dy
rect.transform('t' + dx + ',' + dy) // 平移
},
() => rect.attr('fill', 'blue'), // onstart
() => { // onend
rect.transform('')
rect.attr({ 'x': rectX, 'y': rectY })
rect.attr('fill', 'yellow')
}
)
rect.dblclick(() => rect.undrag()) // 解除拖拽事件的绑定
8、变换和动画
(1)变换
为元素增加变换,这是独立于其他属性的变换,即变换不改变矩形的x或y。变换字符串跟路径字符串的语法类似:
't100,120 r30,100,100 s1.5,1.2,100,100 r45 s1.5'
每个字母是一个命令,有四个命令:t是平移,r是旋转,s是缩放,m是矩阵,对应的大写字母是绝对的变换。
上面的例子可以读作“平移100,120;围绕100,100旋转30°;围绕100,100缩放1.5,1.2倍;围绕中心旋转45°;相对中心缩放1.5倍”。
// 变换
let transformFlag = false
let rect = paper.rect(5, 5, 50, 50).attr({ 'fill': 'yellow', 'cursor': 'pointer' })
.click(() => {
rect.transform(transformFlag ? '' : 't100,120 r30,100,100 s1.5,1.2,100,100 r45 s1.5')
transformFlag = !transformFlag
})
(2)动画
语法:Element.animate({ 动画属性的键值对 }, 动画时间, 缓动类型, 回调函数);
缓动类型其实就是动画过渡公式,是哪种类型的。主要有以下这些类型:
“linear” (线性)
“<”或“easeIn”或“ease-in” (由慢到快)
“>”或“easeOut”或“ease-out”(又快到慢)
“<>”或“easeInOut”或“ease-in-out”(由慢到快再到慢)
“backIn”或“back-in”(开始时回弹)
“backOut”或“back-out”(结束时回弹)
“elastic”(橡皮筋)
“bounce”(弹跳)
// 动画1
let circle1 = paper.circle(110, 25, 20).attr({ 'fill': 'red', 'cursor': 'pointer' })
.click(() => {
circle1.animate({
'cx': 110,
'cy': 120,
'transform': 's1.5'
}, 1000, 'bounce')
})
// 动画2
let circle2 = paper.circle(200, 25, 15).attr({ 'fill': 'purple', 'fill-opacity': 0.5, 'cursor': 'pointer' }) // fill-opacity透明度
.hover(() => {
circle2.animate({
'20%': {
cx: 300,
easing: '<>'
},
'40%': {
cy: 125,
easing: '<>'
},
'60%': {
cx: 200,
easing: '<>'
},
'80%': {
cy: 25,
easing: '<>'
}
}, 2000)
})
参考:
https://zhuanlan.zhihu.com/p/...
https://www.jianshu.com/p/570...
https://code.tutsplus.com/tut...