本文大部分內(nèi)容來(lái)自文章結(jié)尾參考資料中的內(nèi)容,只是做了部分刪減整理贩幻。
創(chuàng)建畫(huà)布
在瀏覽器窗口中初始化畫(huà)布
語(yǔ)法:
//Raphael function中4個(gè)參數(shù)分別是x坐標(biāo)段直、y坐標(biāo)鸯檬、寬度喧务、高度枉圃。
var raphaelObj = Raphael(x,y,width,height);
// 因?yàn)檫@個(gè)是在瀏覽器視口里面來(lái)創(chuàng)建的孽亲,所以畫(huà)布的位置是絕對(duì)定位。因此栖茉,它會(huì)在所有html元素下面重疊吕漂。
在元素中創(chuàng)建Raphael對(duì)象(推薦)
要在一個(gè)元素中初始化一個(gè)Raphael對(duì)象惶凝,我們必須把這個(gè)元素的ID或者這個(gè)元素本身加入到坐標(biāo)系(x,y)中苍鲜。
// 初始化一個(gè)寬320高320的畫(huà)布
let paper = Raphael(document.getElementById("chart-wrap"), 320, 320)
一 畫(huà)布的方法
1 繪制圓形circle(x, y, r)
var cir = paper.circle(x,y,r);
參數(shù)含義:
x: 圓心X軸坐標(biāo)
y: 圓心Y軸坐標(biāo)
r: 圓的半徑
2 矩形rect()
我們可以使用rect()方法來(lái)創(chuàng)建一個(gè)矩形坡贺。這個(gè)方法一共有4個(gè)必須參數(shù)和一個(gè)可選參數(shù)箱舞。5個(gè)參數(shù)含義分別是:
x坐標(biāo)晴股、y坐標(biāo)电湘、矩形寬度寂呛、矩形高度贷痪、圓角半徑(可選)。其中最后一個(gè)參數(shù)圓角半徑默認(rèn)為0肉津,為可選參數(shù)妹沙。
var rect = paper.rect(x熟吏,y距糖,width, height, border-radius(可選));
3 橢圓ellipse()
橢圓的方法是ellipse(),有4個(gè)必要參數(shù)玄窝。分別是x坐標(biāo)、y坐標(biāo)肾筐、水平半徑哆料、垂直半徑缸剪。水平半徑和垂直半徑其實(shí)就是橢圓的寬和高除以2吗铐。
var ellipse = paper.ellipse(x, y, rx, ry)
回顧我們中學(xué)數(shù)學(xué)中的知識(shí):
![](http://latex.codecogs.com/png.latex?\frac{x^2 }{a2}+\frac{y2 }{b^2}\leqslant 1)
其中a, b分別給橢圓的長(zhǎng)短半徑
4 復(fù)雜圖形path()
path()方法杏节。它只有一個(gè)參數(shù)唬渗,我們稱它為:
pathString(一串字母和數(shù)字的組合)
在這之前,我們先想象一下自己畫(huà)復(fù)雜圖形的場(chǎng)景奋渔。其實(shí)你拿一支筆在紙上畫(huà)畫(huà)的話镊逝,就好像你從一個(gè)起點(diǎn)開(kāi)始,不斷的連線到構(gòu)成你的圖畫(huà)嫉鲸。其實(shí)這里的機(jī)制就是如此撑蒜,通過(guò)線的連接來(lái)構(gòu)成復(fù)雜圖形,連線可以使直線也可以是曲線玄渗。
var path = paper.path([pathString])
路徑字符串由一個(gè)或多個(gè)命令組成座菠。每個(gè)命令以一個(gè)字母開(kāi)始,隨后是逗號(hào)(“,”)分隔的參數(shù)
但是命令有大小寫(xiě)的區(qū)別藤树,其效果也不同浴滴。大寫(xiě)表示絕對(duì),小寫(xiě)為相對(duì)岁钓。比如(M20,20)表示從(0,0)位置來(lái)計(jì)算的升略,而(m20,20)則是相對(duì)畫(huà)筆的位置(dom位置)來(lái)計(jì)算。
常用的幾個(gè)命令:
命令 | 名稱 | 參數(shù) |
---|---|---|
M | 移動(dòng)到(move To) | (x, y)+ |
Z | 閉合路徑(closepath) | (none) |
L | 直線(lineTo) | (x, y)+ |
H | 水平直線 | x+ |
V | 垂直直線 | y+ |
C | 曲線(curveTo) | (x1, y1,x2, y2, x, y )+ |
S | 平滑曲線 | (x2, y2, x, y)+ |
Q | 二次貝塞爾曲線 | (x1, y1, x, y)+ |
T | 平滑二次貝塞爾曲線 | (x, y)+ |
A | 橢圓弧 | (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ |
var paper = Raphael(document.getElementById("chart-wrap"), 700, 600);
//1屡限、直線使用path命令L
paper.path("M20,20L100,20z").attr({
"fill": "#5DDEF4",
"stroke": "#2A6570",
"stroke-width": 2
});
//2品嚣、三角形使用Path命令L
paper.path("M130,30 L200,30 L160,90 z").attr({
"fill": "#5DDEF4",
"stroke": "#2A6570",
"stroke-width": 2
});
//3、T形使用Path命令H,V
paper.path("M 40,40 H 90 V 60 H 70 V 110 H 60 V 60 H 40 z").attr({
"fill": "#5DDEF4",
"stroke": "#2A6570",
"stroke-width": 2
});
//4钧大、2次貝塞爾曲線形翰撑,使用path命令Q
paper.path("M240,40L300,40L300,100");
paper.path("M240,40Q300,40 300,100").attr('stroke', 'red');
//5、2次貝塞爾曲線形拓型,使用path命令Q和T(第一個(gè)是正常繪制额嘿,第二個(gè)光滑連接)
paper.path('M10,250 L90,130 L160,160 L250,190 L250,70');
paper.path('M10,250 Q90,130 160,160 T250,70').attr('stroke', 'red');
//6检盼、繪制3次貝賽爾曲線靴庆,使用命令C,平滑畫(huà)線使用命令S
paper.path('M320,120 L350,180 L450,260 L480,140');
這里重點(diǎn)解釋下最后一個(gè)path繪制橢圓弧掠哥,這里小伙伴可能有一個(gè)疑問(wèn)压固,這個(gè)橢圓弧和上面講的ellipse() 方法有什么區(qū)別球拦,這個(gè)好理解,ellipse()方法只是這其中的一種特例, 總之坎炼,path繪制橢圓弧包含ellipse() 方法的功能愧膀。
橢圓弧的參數(shù)詳解如下:
參數(shù)含義:
rx:橫軸的長(zhǎng)度;
ry:縱軸的長(zhǎng)度谣光;
x-axis-rotation:橢圓的橫軸與x軸的角度檩淋;
large-arc-flag:區(qū)分弧度的大小(0表示小角度弧度萄金,1表示大角度弧度)蟀悦;
sweep-flag:繪制弧度圍繞橢圓中心的方向(0表示逆時(shí)針?lè)较颍?表示順時(shí)針?lè)较颍?
x y:橢圓曲線終點(diǎn)坐標(biāo);
詳細(xì)可查看http://lblovesnow-163-com.iteye.com/blog/1485388
6 text()
text()氧敢,是用來(lái)顯示文字內(nèi)容的方法日戈。語(yǔ)法其實(shí)很簡(jiǎn)單,就是x,y坐標(biāo)和文字內(nèi)容孙乖。
// 語(yǔ)法
let text = paper.text(x, y, "Raphael JS Text");
// 例子
let text = paper.text(300, 300, 'Raphael設(shè)置文本').attr({
'fill': '#17A9C6',
'font-size': '20px',
'text-anchor': 'start',
'font-family': 'century gothic'
})
text-anchor屬性表明文字與坐標(biāo)的關(guān)系浙炼,是從這個(gè)坐標(biāo)開(kāi)始、為中心還是為結(jié)尾唯袄。屬性值可以設(shè)置 "start", "middle" or "end" 默認(rèn)"middle"弯屈。
7 Raphael元素的變換
Raphael其實(shí)提供了好幾個(gè)方法供大家調(diào)用來(lái)變換元素,但是其中幾個(gè)的方法都是不推薦的越妈。唯一推薦的元素變換方法是transform()方法季俩。transform方法的參數(shù)與上篇最后的path命令串很相似,只不過(guò)這是transform命令串梅掠。它有4個(gè)命令:
參數(shù) | 說(shuō)明 |
---|---|
T | 移動(dòng) |
S | 縮放 |
R | 按角度變換 |
M | 變換矩陣 |
比如:"t100,100r30,100,100s2,2,100,100r45s1.5"
也有另類的“絕對(duì)”平移酌住、旋轉(zhuǎn)和縮放:T、R和S阎抒。他們不會(huì)考慮到以前的變換酪我。例如:...T100,0總會(huì)橫向移動(dòng)元素100px,而...t100,0會(huì)移動(dòng)垂直移動(dòng)如果之前有r90且叁,則發(fā)生了垂直移動(dòng)都哭,這個(gè)后面會(huì)有強(qiáng)調(diào)。上面的例子可以讀作“平移100,100逞带;圍繞100,100旋轉(zhuǎn)30°欺矫;圍繞100,100縮放兩倍;圍繞中心旋轉(zhuǎn)45°展氓;相對(duì)中心縮放1.5倍“穆趴。正如你可以看到旋轉(zhuǎn)和縮放命令的原點(diǎn)坐標(biāo)為可選參數(shù),默認(rèn)的是該元素的中心點(diǎn)遇汞。
有一點(diǎn)需要注意未妹,transform方法并不改變?cè)乇旧淼娜魏螤顟B(tài)簿废!無(wú)論你平移多少,transform執(zhí)行后你獲得坐標(biāo)信息仍舊創(chuàng)建元素時(shí)的坐標(biāo)络它,但是transform的參數(shù)在變化族檬。也就是transform的內(nèi)容是你可以獲得的。無(wú)論你執(zhí)行多少次transform化戳,它保存著現(xiàn)在狀態(tài)和創(chuàng)建狀態(tài)之間的轉(zhuǎn)換內(nèi)容单料,其實(shí)transform就是元素本身的一個(gè)屬性,而不是去改變?cè)氐钠渌鼘傩浴?/p>
let rect1 = paper.rect(100, 20, 80, 40).attr({
'stroke': 'rgb(92, 215, 120)'
})
let rect2 = paper.rect(100, 70, 80, 40, 20).attr({
'stroke': 'rgb(255, 130, 121)'
})
let rect3 = paper.rect(100, 20, 80, 40).attr({
'stroke': 'rgb(92, 215, 120)'// border color of the rectangle
}).transform('r90t100, 0')
let rect4 = paper.rect(100, 70, 80, 40, 20).attr({
'stroke': 'rgb(255, 130, 121)'// border color of the rectangle
}).transform('r90T100, 0')
絕對(duì)迂烁,就是無(wú)論其它什么變換我都不管不顧只會(huì)去執(zhí)行我后面緊跟的參數(shù)看尼,所以T執(zhí)行的是不管你前面轉(zhuǎn)了90度還是沒(méi)轉(zhuǎn),我都x軸平移100px盟步。而相對(duì),則是我轉(zhuǎn)了90度躏结,我的頭部(假設(shè)元素都有一個(gè)頭部)本來(lái)朝右變成了朝下却盘,x軸平移100px,好吧我向著x平移100px媳拴,但是實(shí)際是去y軸平移了100px黄橘,因?yàn)槲冶緛?lái)指向x軸的頭部變成了y軸方向。
但是不論是不是發(fā)生了變換屈溉,并不改變?cè)氐谋旧砥渌鼘傩浴?/p>
8 Raphael圖形的動(dòng)畫(huà)效果
Raphael的圖形動(dòng)畫(huà)效果可以達(dá)到非常平滑的程度塞关,并且任何屬性都可以,不論是顏色子巾、透明度帆赢、寬度、高度還是其它細(xì)節(jié)线梗。
四個(gè)參數(shù):
動(dòng)畫(huà)屬性鍵值對(duì)椰于, 動(dòng)畫(huà)時(shí)間, 緩動(dòng)類型仪搔,回調(diào)函數(shù)
語(yǔ)法:
Element.animate({動(dòng)畫(huà)屬性的鍵值對(duì)}, 動(dòng)畫(huà)時(shí)間,緩動(dòng)類型,回調(diào)函數(shù));
Raphael元素的常用事件
let rect3 = paper.rect(100, 20, 80, 40).attr({
'stroke': 'rgb(92, 215, 120)'// border color of the rectangle
}).transform('r90t100, 0')
let rect4 = paper.rect(100, 70, 80, 40, 20).attr({
'stroke': 'rgb(255, 130, 121)'// border color of the rectangle
}).transform('r90T100, 0')
// 元素事件綁定
rect3.click(function(){
alert('點(diǎn)擊事件');
});
rect4.mouseover(function(){
alert('mouseover事件');
});
常用事件如下瘾婿, 具體查看官方文檔
事件名 | 說(shuō)明 |
---|---|
click | 單擊事件 |
dbclick | 雙擊事件 |
mousedown | 鼠標(biāo)按下 |
mouseup | 鼠標(biāo)釋放 |
mousemove | 鼠標(biāo)移動(dòng) |
mouseover | 鼠標(biāo)進(jìn)入元素時(shí)觸發(fā),這里需要說(shuō)明烤咧,mouseover()和上面mousemove()的區(qū)別偏陪,你從外面移動(dòng)到一個(gè)Raphael元素時(shí),兩個(gè)方法都可以觸發(fā)事件煮嫌。但是如果你把事件執(zhí)行完成笛谦,繼續(xù)移動(dòng)鼠標(biāo)(假設(shè)此時(shí)鼠標(biāo)光標(biāo)還在元素中),mouseover()將不再繼續(xù)執(zhí)行事件立膛,而mousemove() 會(huì)持續(xù)觸發(fā)事件揪罕。 |
mouseout | mouseout()方法觸發(fā)為鼠標(biāo)移出一個(gè)Raphael元素時(shí)梯码,它只有在移出時(shí)觸發(fā),進(jìn)入不觸發(fā)好啰。 |
10 Raphael中常用的方法
clone()
clone()方法是克隆一個(gè)Raphael時(shí)調(diào)用的轩娶。有個(gè)小伙伴可能會(huì)問(wèn),那我直接var newrect=rect;難道不行嗎框往?實(shí)際上是不行的鳄抒,因?yàn)閚ewrect實(shí)際只是一個(gè)指向老rect的"快捷方式",它并不會(huì)創(chuàng)建一個(gè)新的Dom椰弊。
//下面這個(gè)是我們想要的效果的代碼:
let newrect=rect.clone().attr({"x":50,"y":50});
//而不是這個(gè):
let newrect=rect.attr({"x":50,"y":50});
data()
data()方法是個(gè)不可思議的方法许溅。你可以根據(jù)自己需要為Raphael元素賦予你想賦予的含義,并且在需要時(shí)取回來(lái):
newrect.data({
"name": "heihei",
"age":2
});
newrect.click(function(){
alert(newrect.data("age"));
});
我們可以隨意賦予元素它要裝載的內(nèi)容秉版,在需要的時(shí)候拿回來(lái)贤重。這個(gè)功能非常靈活,你可以隨意設(shè)計(jì)關(guān)鍵詞清焕,當(dāng)你需要為用戶展現(xiàn)鼠標(biāo)移過(guò)展現(xiàn)內(nèi)容時(shí)就可以用這個(gè)并蝗。當(dāng)然有了這個(gè)為元素添加data的方法就肯定有移出的方法。
removeData ()
與上面的為元素添加內(nèi)容相反秸妥,removeData()方法是移出已經(jīng)添加了的內(nèi)容:
newrect.removeData("age");
getBBox()
getBBox()方法獲得一個(gè)Raphael元素的邊界框(我把它成為包圍盒)滚停。其實(shí)應(yīng)該就是能包圍元素的最小矩形。getBBox()有個(gè)參數(shù)isWithoutTransform粥惧,值是true或者false键畴。參數(shù)含義是獲得的邊界框是在執(zhí)行transform也就是變換之前的元素還是變換后的。默認(rèn)是false突雪,意思是轉(zhuǎn)換后的起惕,也就是你不設(shè)置里面參數(shù)為true,它獲得的包圍盒就是轉(zhuǎn)換之后的.
** getPointAtLength()**
getPointAtLength()方法在給定的path對(duì)象和指定的長(zhǎng)度挂签,返回那個(gè)位置點(diǎn)的坐標(biāo)
path.getPointAtLength(length)
toFront() 疤祭、toBack() 、hide() 饵婆、show() 勺馆、remove()
這里我們有5個(gè)方法一起講解。這5個(gè)方法都沒(méi)有參數(shù)侨核,也就是 元素.方法()草穆,就行了. 類似于jquery中元素的操作
toFront()到前面來(lái),toBack()與toFront()相反搓译,到后面去悲柱;hide()和show()相反,分別是隱藏和顯示些己;remove()刪除豌鸡。
畫(huà)布的另外幾種常用的方法
paper.clear()
paper.clear()方法清空畫(huà)布嘿般,還記得上面元素方法里面有個(gè)remove()方法吧。那個(gè)是單個(gè)去除一個(gè)元素涯冠,這里是畫(huà)布來(lái)調(diào)用清除所有元素的方法炉奴。
paper.image()
這里說(shuō)明一下,RaphaelJS確實(shí)是個(gè)非常優(yōu)秀的前臺(tái)圖形繪制工具蛇更,但是不要以為它可以替代圖片瞻赶。其它普通圖片和Raphael是互補(bǔ)的,而不是可以替代的關(guān)系派任。所以Raphael提供了引用圖片的方法砸逊,就是paper.image()。它有5個(gè)參數(shù)
paper.image(src, x, y, width, height)
** paper.setSize()**
paper.setSize()用來(lái)重新設(shè)置畫(huà)布的大小掌逛。你可以在發(fā)現(xiàn)畫(huà)布大小不合適時(shí)調(diào)整畫(huà)布的大小而不是需要從頭建立畫(huà)布然后重復(fù)原來(lái)的工作师逸。方法有2個(gè)參數(shù):寬和高
paper.setSize(600,800);
paper.set()
paper.set()方法是個(gè)很重要的方法。它幫助我們對(duì)Raphael元素進(jìn)行分組然后進(jìn)行批量管理颤诀。也就是我們放進(jìn)一個(gè)set里面的Raphael元素如果用set來(lái)執(zhí)行一些動(dòng)作字旭,那么這些操作是所有在set里面的元素一起起作用的。但是set本身并不創(chuàng)建和復(fù)制崖叫、克隆Raphael元素,也就是你刪除一個(gè)set拍柒,不會(huì)刪除set里面的Raphael元素心傀,但是你可以用set來(lái)幫助管理set內(nèi)的元素。我們貼個(gè)代碼看看:
var paper = Raphael("my-canvas", 650, 400);
var rect = paper.rect(20, 20, 60, 40).attr({
"stroke": "red", // border color of the rectangle
});
var rect1 = paper.rect(20, 70, 60, 40, 20).attr({
"stroke": "yellow", // border color of the rectangle
});
var cir = paper.circle(150, 100, 30);
var raphaelSet = paper.set();
raphaelSet.push(rect, rect1, cir);
raphaelSet.attr({
"fill": "red"
});
set的方法
接下來(lái)講解的方法是只有set對(duì)象才能調(diào)用的方法拆讯,前面我們已經(jīng)提到了set對(duì)象的聲明:
var raphaelSet = paper.set();
set.clear()
我們想要清空set脂男,可不要用remove()而是用clear(),remove()會(huì)把所有set里面的元素remove掉种呐。clear()只是清除set里的內(nèi)容宰翅,并不會(huì)對(duì)里面的內(nèi)容本身有影響。那就會(huì)有同鞋問(wèn)爽室,我不想清空set汁讼,只想刪除其中一個(gè)可以嗎?當(dāng)然是可以的阔墩。那就是下個(gè)方法了嘿架。
set.exclude()
set.exclude(rect);還記得我前面的代碼里面將rect添加進(jìn)入raphaelSet里面嗎?現(xiàn)在你可以試一試在在執(zhí)行raphaelSet.attr()之前使用raphaelSet.exclude(rect);試一試。效果和我們想象的一樣啸箫,第一個(gè)矩形沒(méi)有被填充紅色耸彪,因?yàn)樗粡膕et里面剔除出來(lái)了。
set.forEach()
看到forEach關(guān)鍵詞忘苛,我們立即就能理解到這個(gè)方式是干什么用的蝉娜。那就是日常開(kāi)發(fā)中最常碰到的循環(huán)唱较。set.forEach()就是去循環(huán)我們創(chuàng)建的set對(duì)象,然后通過(guò)遍歷對(duì)set內(nèi)的元素進(jìn)行操作召川。這個(gè)功能是差不多算是set里面最重要的方法了南缓,我們使用set大部分業(yè)務(wù)都需要這個(gè)循環(huán)了。
raphaelSet.forEach(function(ele){
ele.attr({"fill","red"});
});
這句代碼的效果大家可以試一試扮宠,可以替換我們剛才那個(gè)raphaelSet.attr({"fill","red"});
set.pop()
彈出set中的最后一個(gè)元素西乖,就是清除最后一個(gè)添加進(jìn)去的元素。
raphaelSet.push(rect, rect1, cir);
raphaelSet.pop();
raphaelSet.attr({
"fill": "red"
});
我們上面貼的那個(gè)代碼坛增,修改成為這段获雕,就會(huì)發(fā)現(xiàn)圓形并沒(méi)有被填充紅色,因?yàn)樵趫?zhí)行填充之前收捣,它已經(jīng)被從set里面pop了出來(lái)届案。
set.splice()
set.splice()方法和普通的js或者java的數(shù)據(jù)的slice有點(diǎn)不同。它有3個(gè)參數(shù)index,count,element罢艾。什么意思呢楣颠?set.splice(1,2,rect),我從set里面index為1的位置開(kāi)始往后刪除2個(gè)元素咐蚯,然后把rect添加進(jìn)來(lái)童漩。所以slice可以同時(shí)刪除和添加元素。注釋它是有返回值的春锋,它將返回被刪除掉的元素矫膨。
參考資料:
1 raphael github地址
2 raphael官方文檔
3 快速上手RaphaelJS
4 http://www.reibang.com/p/81c3fc5287d1