こんにちは、ユーリです!
少し前、SVGでアニメーションを行う記事を書きましたが、
その後の開発でブラウザ間の挙動の違いや、古いブラウザでうまく動かなかったりと色々と苦労いたしました。
うおー、やはり一定数の古い環境は切り捨てるしかないのかッ…!対応コードを書けば書くほど煩雑になってゆく!
そこに現れた救世主!!
SVG制御用ライブラリ… Raphael.js っ!!
↓さんぷる
自前のコードだけでの対応に限界を感じ、ライブラリを使用してめんどくさいところは全部吸収してもらうことにしました。
まさにうってつけのライブラリが見つかりました!
それがraphael.jsでございます。
■IEやsafqriの古いバージョンでも動作
特に何も意識せずとも、raphael.jsからの処理を使ってSVGを操作すれば、古いブラウザでもしっかり表示され、animateも問題なく動作してくれます!
svg要素を直接うごかしていたら、animateが動作しなかったり、変な位置に表示されたりしてしまい、たいへん苦労いたしました。
■jQueryライクな記述で、直感的に要素や値を操作できる
jQueryのような値の指定やメソッドチェーンが利用できます。
jQueryに慣れている方であればすんなり飲み込めるのではないでしょうか。
■基本的なeventをサポート
マウスオーバーやクリックのような処理も、svgの要素単位で実装ができます。
svg要素はマウス判定の範囲に複雑な形状を利用できるため、リッチな動作を実現できます。
divなどのブロック要素で任意の大きさを指定し、その中にsvgをwidth:100%、height:100%で配置するのがいちばん安定しました。
この方法の場合、あとからdiv要素の大きさが変わっても、中身のSVG要素もあわせて伸び縮みしてくれます。
viewboxでサイズ指定するとさらに堅牢です。
PCで閲覧している方は、このページを表示しているウィンドウ自体のサイズを変えてみていただけると伸び縮みに対応していることを確認できるハズです。
上記のコードで、このように表示されます。
先ほどようにSVGを生成してから、その要素に対してclick、mouseover、mouseoutの処理を定義してみます。
SVG要素が複雑な形をしていても、その形の通りに当たり判定が適応されます。
記述方法はjQueryのanimateとほぼ同じで、アニメーションさせるプロパティにsvg要素の色や座標を指定すればOKです。
この前の苦労はなんだったのか…。
やっぱりSVGはなめらかでたのしい!
これくらい手軽に扱えれば、どんどん夢が広がっていきます!
まさにうってつけのライブラリが見つかりました!
それがraphael.jsでございます。
raphael.jsのココがスゴイ!
■IEやsafqriの古いバージョンでも動作
特に何も意識せずとも、raphael.jsからの処理を使ってSVGを操作すれば、古いブラウザでもしっかり表示され、animateも問題なく動作してくれます!
svg要素を直接うごかしていたら、animateが動作しなかったり、変な位置に表示されたりしてしまい、たいへん苦労いたしました。
■jQueryライクな記述で、直感的に要素や値を操作できる
jQueryのような値の指定やメソッドチェーンが利用できます。
jQueryに慣れている方であればすんなり飲み込めるのではないでしょうか。
■基本的なeventをサポート
マウスオーバーやクリックのような処理も、svgの要素単位で実装ができます。
svg要素はマウス判定の範囲に複雑な形状を利用できるため、リッチな動作を実現できます。
サンプルコード
SVG要素を作成し、図形を描画する
SVG要素の大きさを指定する方法はいろいろありますが、いろいろ試した結果、divなどのブロック要素で任意の大きさを指定し、その中にsvgをwidth:100%、height:100%で配置するのがいちばん安定しました。
この方法の場合、あとからdiv要素の大きさが変わっても、中身のSVG要素もあわせて伸び縮みしてくれます。
viewboxでサイズ指定するとさらに堅牢です。
PCで閲覧している方は、このページを表示しているウィンドウ自体のサイズを変えてみていただけると伸び縮みに対応していることを確認できるハズです。
<!--svg配置用のdiv要素--> <script> $(function(){ var paper = Raphael("svg_wrap","100%","100%"); //Raphael()でSVG要素を生成する //引数1:生成する対象要素のid 引数2:width 引数3:height paper.setViewBox(0,0,600,200,true); //viewBoxの大きさを指定 paper.add([ //図形を追加する { type : "rect" , //四角形を追加 x : 10 , //X座標 y : 70 , //Y座標 width : 240 , //width height : 120 , //height fill : "#6E6" , //fill = 塗りつぶしの色 stroke : "#C33" , //stroke = 線の色 "stroke-width": 5, //線の太さ }, { type : "circle" ,//円を追加 cx : 280 , //X座標(circle) cy : 40 , //Y座標(circle) r : 80 , //半径 fill : "#AAF" , //fill = 塗りつぶしの色 stroke : "#66E" , //stroke = 線の色 "stroke-width": 5, //線の太さ } ]); var tri = paper.path("M350,10 L350,170 L 530,90 Z"); //パスを追加する(三角形) tri.attr({ //パス(三角形)のプロパティを変更 fill : "#C77" , stroke : "#F33" , opacity : 0.80 , //透明度 "stroke-width" : 10, //線の太さ }); }); </script>
上記のコードで、このように表示されます。
クリックやマウスオーバーなど、イベントの処理を書く
SVGを表示できたらぐにぐに動かしたいですよね!先ほどようにSVGを生成してから、その要素に対してclick、mouseover、mouseoutの処理を定義してみます。
SVG要素が複雑な形をしていても、その形の通りに当たり判定が適応されます。
var paper = Raphael("svg_wrap","100%","100%"); paper.setViewBox(0,0,600,200,true); //viewBoxの大きさを指定 var path = paper.path("M548,95v8H349C347,130,326,150,300,150c-19,0-36-11-45-28c-8,16-25,28-45,28s-36-11-45-28c-8,16-25,28-45,28c-26,0-47-20-49.8-45H50v-8h20C72,70,93,50,120,50c19,0,36,11,45,28c8-16,25-28,45-28s36,11,45,28c8-16,25-28,45-28c26,0,47,20,49,45H548z"); //パスを追加する path.attr({ //パスのプロパティを変更 fill : "#AAA" , stroke : "#666" , "stroke-width" : 3, //線の太さ }); path.click(function(){ //クリック時の処理 var r = Math.floor(Math.random () * 256); //赤ランダム var g = Math.floor(Math.random () * 256); //緑ランダム var b = Math.floor(Math.random () * 256); //青ランダム var color = "rgb("+r+","+g+","+b+")"; //ランダム色生成 path.attr({ //パスのプロパティを変更 fill : color, //塗りつぶしの色を変える }); }); path.mouseover(function(){ //マウスオーバー時の処理 path.attr({ //パスのプロパティを変更 "stroke-width" : 8, //線の太さを変える opacity : 0.8 //透明度を変える }); }); path.mouseout(function(){ //マウスアウト時の処理 path.attr({ //パスのプロパティを変更 "stroke-width" : 3, //線の太さを戻す opacity : 1.0 //透明度を戻す }); });上記のコードで、このように表示されます。マウスイベントに対応しています!
アニメーションを行う
前回のSVGの記事で苦労してアニメーション処理を書きましたが、raphael.jsにかかれば、非常に簡単にアニメーション処理ができてしまいます;;記述方法はjQueryのanimateとほぼ同じで、アニメーションさせるプロパティにsvg要素の色や座標を指定すればOKです。
path.mouseover(function(){ //マウスオーバー時の処理 path.animate({path:"M548,95v8H349c-54,7-23,2-49,2c-19.8,0-18,2-45,2c-25,2-25-1-45-1s-19,3-45-1c-27,5-25-1-45-1c-26,0-13,5-49-0.6H50v-8h20c31-2,23-1,49-1c19,0,17-11,45-0.8c25-3,25-3,45-3s22-3,45,3c29-4,25-1.2,45-1c26,0,27-0.7,49,3H548z"},250); //パスの形を変更 }); path.mouseout(function(){ //マウスアウト時の処理 path.animate({path:"M548,95v8H349C347,130,326,150,300,150c-19,0-36-11-45-28c-8,16-25,28-45,28s-36-11-45-28c-8,16-25,28-45,28c-26,0-47-20-49-45H50v-8h20C72,70,93,50,120,50c19,0,36,11,45,28c8-16,25-28,45-28s36,11,45,28c8-16,25-28,45-28c26,0,47,20,49,45H548z"},100); //パスの形を戻す });マウスオーバーでアニメーションします!
集合要素に対して処理を行う
要素をたくさん並べて処理をしたい場合、setという配列のようなクラスを使用して、forEachでそれぞれの要素に対してまとめて処理を行うことができます。var paper = Raphael("svg_wrap","100%","100%"); paper.setViewBox(0,0,600,200,true); //viewBoxの大きさを指定 var rectarray = paper.set(); //svg要素の集合を格納する"set"を作成 for( var i = 0, j = 20; i < j ; i++ ){ //20回繰り返す rectarray.push( //setに対してsvg要素を追加する paper.rect(i*(j+10),100,20,80) //paperの中に四角形を作成(x,y,w,h) ); } rectarray.forEach(function(e,i){ //setの中身の要素それぞれに対して処理(element,index) e.attr({ //プロパティを変更 fill : "#8CC" , //塗りつぶしの色 }); e.mouseover(function(){ //マウスオーバー時の処理 if( e.attr("y") == 0 ){ //yの値が0の場合 e.animate({y:100,fill:"#88C"},200,"<>"); //下に移動するアニメーション }else{ //yの値が0でない場合 e.animate({y:0,fill:"#C88"},200,"<>"); //上に移動するアニメーション } }); });マウスオーバーでアニメーションします!
これくらい手軽に扱えれば、どんどん夢が広がっていきます!