學習RaphaelJS矢量圖形包--Learning Raphael JS Vector Graphics中文翻譯(一)


      (原文地址:http://www.cnblogs.com/idealer3d/p/LearningRaphaelJSVectorGraphics.html

      前面3篇博文里面,我們講解了一本叫做《Instant RaphaelJS Starter》的書,那本書里我們將RaphaelJS里面的基本內容都進行了比較詳細的講解。但是,坦白的說,那本書通俗易懂卻太過淺顯。現在我們下一本叫做《Learning Raphael JS Vector Graphics》的書,算是上一本的進階。當然,它里面大部分篇幅也是基本內容。因為一本書不能去講一個寫復雜的業務問題,你所要做的也是學會基本內容然后自己去活用。我這里翻譯此書的目的,第一是想加深對於RaphaelJS的理解,第二是本來也是要讀這本書的,就順帶翻譯了,或許還能給英語不拿手的同志們有點幫助,第三就是尋找一些突破的契機去解決我現在碰到的問題。好了,廢話少說。新的一本書,大家可以去網上搜索一下,應該可以找到下載。

      和上本書一樣,本書前面的幾頁是一些序言、版權聲明等東西,這里我也略過不講了。我們從目錄頁開始講。如果你認真學習過前面3篇翻譯上本書博文的內容,這本書的目錄寫出來的時候,你就應該能明白每個章節講的是什么內容。

                         目錄

序言 --------------------------------------------------- 1

第一章: Web圖形---------------------------------------- 5

     在Web上繪制矢量圖---------------------------------- 6

           矢量圖形繪制包-----------------------------------7

     詳述SVG-------------------------------------------- 8

           使用RaphaelJS包而不是直接使用SVG-------------- 9

     RaphaelJS的應用--------------------------------------9

     下載RaphaelJS-------------------------------------- 10

     創建RaphaelJS的Js項目------------------------------ 11

           項目的構建與優化 --------------------------------11

     小結-------------------------------------------------11

第二章: RaphaelJS基本圖形繪制 --------------------------13

      繪制環境------------------------------------------- 13

           畫布坐標系-------------------------------------- 15

      繪制基本圖形---------------------------------------- 16

      導入圖片--------------------------------------------18

      Raphael元素屬性------------------------------------ 18

           簡單(基礎)填充-------------------------------- 19

           圖片填充---------------------------------------- 19

           應用筆畫---------------------------------------- 20

           其它屬性---------------------------------------- 21

                 超鏈接--------------------------------------21

                 透明度--------------------------------------22

                 矩形裁剪------------------------------------22

           漸變應用----------------------------------------23

                線性漸變------------------------------------ 23

                徑向漸變------------------------------------ 25

           元素分組---------------------------------------- 27

     使用文本-------------------------------------------- 28

           引用常用字體------------------------------------ 29

     小結-------------------------------------------------30

第三章: 繪制Path(路徑)---------------------------- ----31

      Path繪制概念--------------------------------------- 32

      Path繪制命令--------------------------------------- 33

            "移動到"命令------------------------------------34

            "連接到"命令----------------------------------- 35

            "關閉路徑"命令--------------------------------- 37

      繪制曲線------------------------------------------- 38

            二次貝塞爾曲線--------------------------------- 38

            三次貝塞爾曲線--------------------------------- 41

            繪制弧線--------------------------------------- 43

      Path中比較實用的方法------------------------------- 46

            Element.getTotalLength() ---------------------46

            Element.getPointAtLength(length) -------------47

            Element.getSubpath(from, to)----------------- 48

           Catmull-Rom弧線------------------------------- 49

       小結----------------------------------------------- 50

第四章: 變形轉換和事件處理------------------------------ 51

      基本圖形變換和事件處理------------------------------52

            基本圖形變換------------------------------------52

                  平移----------------------------------------53

                  旋轉--------------------------------------- 53

                  縮放----------------------------------------55

            基本事件響應----------------------------------- 55

                  注冊基本事件響應 ---------------------------55

                  注銷基本事件響應----------------------------57

       使用矩陣------------------------------------------- 58

             轉換矩陣--------------------------------------- 58

             使用轉換矩陣----------------------------------- 58

       拖放功能------------------------------------------- 60

             Element.drag() 方法 ---------------------------60

             onstart事件----------------------------------- 60

             onend事件------------------------------------ 60

             onmove事件---------------------------------- 60

                   拖動的例子-------------------------------- 61

        丟下元素------------------------------------------ 62

              邊界框覆蓋 -----------------------------------62

              邊界框中的邊界框 -----------------------------63

        小結--------------------------------------------- 64

第五章: 向量動畫--------------------------------------- 65

           基本動畫 ---------------------------------------66

      變換路徑------------------------------------------ 67

      緩動類型 ------------------------------------------70

            內建的緩動算法規則 ----------------------------70

            使用三次貝塞爾公式的緩動 ----------------------71

       動畫轉換 ------------------------------------------72

       動畫常用屬性-------------------------------------- 73

             常用屬性 --------------------------------------73

             隨着一個長路徑動畫-----------------------------76

                  動畫的暫停和重新開始-----------------------78

      小結------------------------------------------------79

第六章: 使用已經存在的SVG文件--------------------------81

      Inkscape ------------------------------------------82

           下載Inkscape-----------------------------------82

           開始使用Inkscape-------------------------------82

       檢查path------------------------------------------87

             Inkscape的XML編輯器-------------------------87

             從存在的SVG圖片中提取path-------------------89

       SVG轉換到raphael對象的工具-----------------------90

             Ready Set Raphael ---------------------------90

             其它轉換工具 ----------------------------------91

       等值域圖 ------------------------------------------92

             創建等值域圖 ----------------------------------92

             開源SVG文件---------------------------------- 96

       小結-----------------------------------------------96

第七章: 創建一個可視化社交媒體--------------------------97

      社交媒體應用--------------------------------------- 97

           開始--------------------------------------------98

           使用JQeury-------------------------------------99

           系統可用數據------------------------------------99

           繪制人型圖表-----------------------------------100

           圖表點擊響應-----------------------------------101

           繪制一把鑰匙-----------------------------------102

      隨時間發布消息-------------------------------------103

            開始-------------------------------------------104

            推送的數據-------------------------------------104

(第七章這里有些專業術語,我在沒讀到這里之前,暫時不能獲得准確的意思,抱歉,翻譯到這里的時候講把這里補充一下。)

 

     我們從正文第一章開始講。

Web圖形

     在當前瀏覽器的領域,圖形的繪制是非常重要的。從圖表到簡單圖片,從數學到視覺藝術,哪里都需要圖形的繪制。所以瀏覽器對於這塊功能的需求大增。所以以此衍生了很多相關技術。不止VML和SVG,HTML5 Canvas和WebGL.每個都有它們適用的領域,VML和SVG處理2D矢量圖,HTML5Canvas的位圖繪制以及WebGL的3D繪制渲染。

     本書講述一個開源和輕量級的JS庫,Raphael,它使用SVG和VML在瀏覽器中繪制矢量圖形。 它提供了很多非常方便的用戶繪制和變換矢量圖的方法,在支持直接操作DOM的同時還支持導入位圖以及文本的繪制。它就是SVG和VML的優秀合體。一位內它已經將底層封裝完善,我們在使用時不需要去考慮SVG和VML的方面問題,只要集中精力搞好我們的Raphael就可以了。

     VML是微軟設計並且在1998年提交給W3C,基於XML技術的在IE版本5+后繪制矢量圖形。SVG使用W3C組織在2001自己推出的適量繪制圖形技術。也是基於XML的文件組織,但是它適用於所有主流瀏覽器。IE在9以后的版本也開始支持SVG。

矢量圖形繪制包

現在有很多比較成熟可用的矢量圖形繪制JS包。除了RaphaelJS,還有兩個非常流行的矢量圖形繪制工具包,Paper.js和D3.js,每個都有它們各種優缺點。下面有一個簡單的比較:

包名稱          IE6,7,8支持            開箱即用(個人理解是開源)   低層次包(意味着你可以操作的空間更大)

Raphael           Yes                        Yes                                   Yes

D3.js               No                         No                                     No

Paper.js           No                         No                                     No

Raphael是為一個支持VML的矢量圖形繪制包,其余的包都支持SVG,但是由於是高級包,在使用雖然可能簡單一些,但是你操作性大減。當我們可以直接對底層內容進行操作時,你會發現我們可以做的事情要遠比其它的多,當然代價就是學習周期長,難度大(實話說,如果你只是做比較普通的功能,Raphael還是非常簡單的,但是對於復雜的操作有些引擎操作需要自己去實現,還是有難度的)。

 SVG說明

SVG是當今Web應用最廣泛的矢量圖形繪制技術。所有主流瀏覽器都提供了全方位的支持,甚至最新的手機瀏覽器都已經加入對SVG的支持。

SVG是基於XML的,就是標簽對格式的。比如我們要畫從坐標(50,50)的點畫一個黑色實心線段到點(10,10)可以用下面的代碼:

<path d="M50 50 L10 10" stroke-width="1" stroke="#000" />

除了路徑path之外,SVG還支持圖形繪制、文本、填充、漸變、動畫以及用戶綁定的事件響應。你可以在http://raphaeljsvectorgraphics.com/the-graphical-web/raw-svg/網站上查看一些SVG的例子。

Raphael基本XML語言,所以這本書看完后,你會非常熟悉一些SVG的語法,特別是和path有關的。

使用Raphael而不要直接使用SVG

撇開瀏覽器支持不說,有一個非常好的原因讓我們使用Raphael而不是直接寫原生態的SVG,因為它讓矢量繪制簡單更多。舉個例子,我門要畫一個矩形並且讓它的寬度從50px動畫變成100px。原生態的SVG代碼:

<rect x="10" y="10" width="50" height="30">

      <animate attributeType="XML"

               attributeName="width"

               to="100"

               fill="freeze"

               dur="1s" />

</rect>

我們在(10,10)坐標位置開始畫一個寬50px,高30px的矩形也就是<rect>標簽,然后需要在內部、嵌入一個<animate>標簽,然后在animate標簽里面,並且進行說明哪里要變、怎么變。還要有fill="freeze"來保持變換的形狀,否則會被重置。這樣看上去代碼冗長而且不易操作。但是我們使用Raphael的話,只需要:

var rect = paper.rect(10, 10, 50, 30);

rect.animate({

      width: 100

      }, 1000);

我們的矩形創建和動畫變動都更加簡潔,而且如果你要變動的內容更多,那就對比更明顯。另外Raphael可以很好與其它包整合,比如jQeury,這歸功於Raphael聲明一個全局的變量Raphael。

Raphael的應用

Raphael現在已經廣泛應用在從地圖制圖Town Hall @ the White House event(http://askobama.twitter.com/)到網絡小游戲比如Ebocs(http://www.dejapong.com/ebocs/).

Raphael特別適用於制圖方面,因為RaphaelJS庫為我們提供了直接操作DOM元素的能力並且我們還可以隨意縮放而不擔心圖片的失真。你可以在http://raphaeljs.com/australia.html 找到一些很好的例子。

(接下來講的內容是如何下載RaphaelJS並且搭建起來環境,我們在第一篇博文里面已經有說明大家可以去看那個,這里不再贅述。地址:http://www.cnblogs.com/idealer3d/p/Instant_RaphaelJS_Starter.html)。還有大家搭建項目的時候要規划好,特別是文件夾以及路徑要管理規范。

 

第二章 使用Raphael繪制基本圖形

      Raphael提供了圖形繪制的基本元素:形狀、圖片和文本。圖形有預定義的矩形、圓形、橢圓以及組合圖形等。圖形和文本是可以填充的。變框的填充只能是單色但是可以修改。填充可以是線性也可以是漸變的。

      繪制環境

      要繪制圖形,我們需要一個繪制的環境。我們需要創建一個空間供我們去繪制和儲存。就像藝術家一樣,我們需要一個畫布。瀏覽器的視口,就是我們的畫布。SVG標准把視口認為是繪制區域自己,我們一般認為瀏覽器區域就是視口了。我們利用Raphael去創建畫布的代碼如下:

     var paper= Raphael(50,100,500,300);

它的效果如下:

 如上圖所示,我們在視口的區域,離左上角x軸(橫軸)50px,y軸(豎軸)100px的位置開始創建一個寬500,高300的矩形框,這就是我們的畫布。也就是說,paper對象,就是我們的畫布。我們更推薦,我們利用已經存在的dom元素來建立畫布而不是直接利用視口。在這種情況下,我們的畫布的位置就是相對DOM元素的位置來講的:

<div id="my-canvas"></div>

我們可以根據如下代碼來建立畫布:

var paper=Raphael("my-canvas",500,300);

也就是我們根據一個DOM的id去建立畫布。當然直接用Id也可以,獲得DOM對象也可以:

Raphael(document.getElementById("my-canvas"),500,300);

畫布坐標系

      我們可以根據下面的插圖來理解畫布的坐標系:

看圖我們可以發現,坐標系原點在畫布的左上角。(0,0)開始,x軸為從左到右,y軸為從上到下。另外如果出現負值,則位置如下:

這里是比較好理解的,但是需要注意的是,在負值的區域是不可見的:

Hidden:隱藏;Visible:可見的。

坐標系弄清楚以后,我們就可以開始繪制我們的圖形了。

繪制基本圖形

      Raphael提供了矩形、圓形、橢圓的作為基本圖形的預定義繪制方法。我們創建的畫布對象可以調用這些方法。Rect矩形的繪制語法:

Paper.rect(x,y,width,height,[r]);

我們可以看到paper.rect共有5個參數,其中前4個為必須參數,第五個為可選參數。前兩個,x,y 其實參照我們創建畫布就可以理解,這里的x,y是在畫布坐標系的(x,y)位置開始繪制,繪制一個寬度為第三個參數width、高度為第四個參數height的矩形。如果第5個參數設置並且大於0,則為圓角矩形。[r]以為圓角的半徑。代碼示例將在下面貼出。我們先講解圓形和橢圓。圓形的繪制語法:

Paper.circle(x,y,r);

在(x,y)位置繪制一個半徑為r的的圓。橢圓的語法:

Paper.ellipse(x,y,x-radius,y-radius);

在(x,y)位置繪制一個橫向半徑為x-radius,豎向半徑y-radius的橢圓。代碼如下:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Raphael Test</title>
    </head>
    <body>
        <div id="my-canvas" style="padding:0px;margin:0px;border:solid;">
        </div>
        <!--some html doms-->
        <!--some scripts-->
        <script type="text/javascript" src="../js/lib/raphael.js">
        </script>
        <script type="text/javascript">
            //在my-canvas節點上面創建畫布
            var paper = Raphael("my-canvas", 500, 300);
            //在(20,20)位置創建一個寬100,高60的直角矩形
            var rect = paper.rect(20, 20, 100, 60);
            //在(140,20)位置創建一個寬100,高60,圓角半徑10的圓角矩形
            var rectR = paper.rect(160, 20, 100, 60, 10);
            //在(50,150)位置繪制一個半徑為40的圓形
            var cir = paper.circle(50, 150, 40);
            //在(150,150)繪制一個橫向半徑50,豎向半徑35的橢圓
            var ellipse = paper.ellipse(150, 150, 50, 35);
            //位置提示
            var tip = paper.text(5, 20, "(10,20)");
            var tipR = paper.text(145, 20, "(160,20)");
            var tipC = paper.text(50, 150, "(100,50)");
            var tipE = paper.text(150, 150, "(100,140)");
        </script>
    </body>
</html>

 

效果圖如下:

如上圖,我們在代碼中有每個圖形的詳細解釋,這里不多解釋,大家可以閱讀代碼中的注釋。這里再引用原書的橢圓圖形加深理解:

 導入圖片

       Raphael允許我們導入位圖至畫布中。語法如下:

paper.image("a.png",50,50,200,200);

意味着我們在(50,50)的位置導入一個圖片,圖片被縮放到長200,寬200.圖片的路徑和名字為:"a.png"。我們在上面的那段代碼中加入:

//導入圖片
var agirl=paper.image("../images/mm.jpg",300,100,200,300);

 效果如下:

接下來我們繼續介紹每個我們創建的元素自帶的屬性。

元素屬性

      我們繪制的圖形都可以有填充、邊框屬性以及其它的很多屬性。我們創建圖形的時候,每個方法返回一個圖形對象,而這些對象就可以去賦予我們想要的屬性。這些對象都有一個attr()方法,里面參數為鍵值對(json),鍵為元素屬性名稱,值為屬性取值。

填充

     我們首先介紹填充屬性。填充可以是基本填充或者圖形填充。基本填充我們使用顏色去填充一個形狀,顏色的格式可以是#rrggbb、簡寫#rgb、rgb(r,g,b)甚至是顏色的英文單詞red、green等。我們在前面那段代碼中添加如下代碼測試:

  rect.attr({
     fill: "#000"
   });
  rectR.attr({
      fill:"rgb(0,0,0)"
    });
  cir.attr({
      fill: "green"
     });
  ellipse.attr({
      fill: "url(../images/mm.jpg)"
    });

 效果圖如下:

不過我們使用位圖填充橢圓的時候,由於橢圓太小我們這里只有原位圖的右上角被填充到了橢圓中。這里大家理解就好啦。

處理筆畫(邊框)

      元素的筆畫有很多屬性,最常用的是顏色和寬度。屬性的鍵名就是"stroke","stroke-width"。因此,我們把剛才代碼中添加幾行新的代碼:

var newcir = paper.circle(50, 250, 40);
            newcir.attr({
                fill: "green",
                stroke: "red",
                'stroke-width': "10"
            });

我們可以通過比叫兩個圓的不同來看到stroke筆畫設置的不同。這里需要知道的是,我們代碼里面的筆畫寬度是10,其實這個10有一半也就是5是在圖形內部,而剩余的則是在圖形的外面。也就是在你設置的筆畫寬度的中間是圖形的真是大小(准確的說,是你期望的圖形大小)。其實,即便我們不設置筆畫屬性,我們所繪制的所有圖形都有自帶的筆畫屬性,他們的寬度是1px。如果你確實不想設置筆畫屬性,那么你需要顯式地設置stroke-width:none。當然還有其它一些stroke屬性這里沒有提及,大家如果想了解可以到RaphaelJS的官方網站去查閱資料。

其它屬性

      herf

      元素上面添加一個鏈接,允許這個dom元素扮演一個超鏈接的角色。當點擊這個圖形時,它將打開一個新的鏈接。(為了演示方便,我們另起一份代碼,剛才的代碼內容已經比較繁雜)。代碼:

 var paper = Raphael("my-canvas", 500, 400);
            var rect = paper.rect(30, 30, 140, 140);
            rect.attr({
                fill: "green",
                href: "http://www.baidu.com"
            });

原書上講,這里將創建一個表現為超鏈接的矩形。但是我實際測試中點擊並沒有作用,這里我還需要找找問題。我們暫時記下來,繼續往下走。

      透明度

      元素透明度鍵名opacity,取值范圍為0(完全不透明)到1(完全透明),也可以分別設置stroke-opacity和fill-opacity。我們前面說過,stroke是以中心來還,一半在外,一半在內。這里就會出現副作用,因為可以分別設置透明度而導致分開設置透明度會有一些限制。這里我們不再貼代碼,原書的例子很好,我就直接貼出來了:

 矩形切割

       Raphael支持通過clip-rect屬性來進行元素的矩形切割,它允許我們將圖形切割出一部分下來。我們可以按照下面的代碼來進行圖形區域切割:

 var paper = Raphael("my-canvas", 500, 400);
            var circle = paper.circle(100, 100, 80);
            //原書是在attr里面直接加入了'clip-rect'屬性,將圓的1/4切割下來,我們分開兩步加入動畫,以便理解。這里最終達到的效果與原書一致
            circle.attr({
                fill: "pink",
                'stroke-width': 0,
            });
            circle.animate({
                'clip-rect': '20,20,80,80'
            }, 2000,'easeIn');

大家將這段代碼替換上面那大段代碼的js部分就可以看到效果了。效果如下:

2秒后:

clip-rect屬性的4個參數與矩形創建是一致的,x,y坐標開始寬、高定制的矩形。原書輔助解釋的圖:

虛線圓就是我們創建的circle對象,粉紅色的部分就是設置該屬性后剩余的部分。

漸變

     Raphael支持線性和梯度漸變去填充圖形,要達到這個效果,而不是直接用一個顏色的字符串去設置fill屬性。我們需要指定了下面這種字符串的格式去做到線性漸變:

            <angle>-<color>[-<color>[:<offset>]]*-<color>

下面的語法就是達到徑向漸變的效果:

      r[(<fx>,<fy>)]<color>[-<color>[:<offset>]]*-<color>

好吧,我承認我也沒看懂。我們來看例子幫助我這智五渣理解一下。

線性漸變

      最基本的線性漸變的格式:

            <angle>-<color1>-<color2>

比如:

       var rect=paper.rect(20,20,160,160);

       rect.attr({

               'stroke-width':0,

               fill:'0-#f00-#000'

             })

我們去實驗一下:

            var paper = Raphael("my-canvas", 500, 400);
            var rect = paper.rect(50, 50, 100, 100);
            var rect1 = paper.rect(200, 50, 100, 100);
            var rect2 = paper.rect(350, 50, 100, 100);
            rect.attr({
                'stroke-width': 0,
                fill: '0-#f00-#000'
            });
            rect1.attr({
                'stroke-width': 0,
                fill: '90-#f00-#000'
            });
            rect2.attr({
                'stroke-width': 0,
                fill: '45-#f00-#000'
            })

 還是把這段復制到js部分就可以了,我們的運行效果圖:

3個矩形,我們分別按照0度角、90度角、45度角實現從紅色到黑色的漸變。嘿嘿,似乎上面那段奇怪的代碼也不怎么難嘛。

     注意,我們的角度計算是從x軸正方向沿逆時針方向來定義角度(--這句話其實就是說角度和我們腦子里的原始想法一致,不要去糾結其它)。

     線性漸變可以有任意個數的顏色和這些顏色組成線性漸變的點,定義為offsets 。也就是有了下面的語法結構:

           [-<color>[:<offset>]]*

在這里,任何個數的-color:offset組合可以用來創建。比如,我們使用下面的string來看看:

      fill:"0-#00a9e0-#323490:20-#ea1688:40-#eb2e2e:60-#fde92d:80-#009e54"

我們用上面那行字符串可以建立一個彩虹樣式的矩形,每個顏色相比前一個顏色多占據20%。下面的字符串可以達到相同效果:

      "0-#00a9e0-#323490-#ea1688-#eb2e2e-#fde92d-#009e54"

這里只要把字符串貼到上面我們js代碼的fill屬性就行了,就不再截圖舉例了。

徑向漸變

      徑向漸變與線性漸變相似,但是徑向漸變繪制的時候是放射式的,從一個點開始(默認圖形的中心點),最基本的徑向漸變的語法:

      r<color>-<color>

      比如,我們在代碼里面加入:

    var paper = Raphael("my-canvas", 500, 400);
            var circle = paper.circle(150, 150, 100);
            circle.attr({
                'stroke-width': 0,
                fill: 'r#f00-000'
            })

 

我們可以得到:

 

我們得到一個從中心為紅色漸變到邊緣為黑色的圓形。根據我們上面線性漸變的描述,我們根據offsets屬性去“分段”定義顏色漸變,我們試驗一下徑向漸變的offsets效果:

  circle.attr({
                'stroke-width': 0,
                fill: 'r#f00-000:80-#f00'
            })

我們把上面的circle對象attr方法修改為上面的這句,效果如下:

 呶?看出來區別了吧。那么估計有童鞋要問了,我不想從中心點開始畫啊,我想隨意的點,記得前面語法出現的fx和fy嗎,它們就是來做這個的。這里我就不詳細舉代碼例子了,袁術的配圖真是不錯,一看就可以明白:

我們發現我在r命令后面的括號里面添加好fx和fy的值,可以獲得不同效果。fx和fy很容易能看出來取值范圍為[0,1],其實就是中心點在圖形的x和y最大值的比例位置。這里很容易理解,不多做解釋了。

     最后,提一點,path對象是不能用徑向漸變的。這是因為VML在這里有bug,所以這里的徑向漸變只適用於基本圖形。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM