2016/12/01

【SVG】Raphael.jsとSnap.svgの比較と実装してみた感想(サンプルコードあり)

JavaScriptでSVGを扱いたくてググったら、Raphaël.jsSnap.svgというライブラリに出会った。
両者ともDmitry Baranovskiy氏が作成したもので、Snap.svgの方が後発だ。順当にいけばSnap.svgを使うのが良さそうだが、せっかくなので両者を比較した。

まずは両者の特徴。
比較項目Raphaël.jsSnap.svg
リリース2009年12月2013年 10月
最新バージョンv2.2.7v0.4.1
更新頻度定期的に更新されている2015年4月からほとんどなし
ブラウザサポートIE6.0+, Firefox3.0+, Safari3.0+, Chrome5.0+, Opera9.5+IE9.0+, 最新のブラウザ
特徴レガシーブラウザをサポートしている(VMLが使える)SVG仕様(マスキングやクリッピング、グラデーションなど)がフルで使える
※ 2016/11/30 現在

次に、実際にサンプルコードを書いて比較する。

図形をドラッグ&ドロップで移動させるサンプル


今回のサンプルの仕様は以下のとおり。

  • ボタンクリックで図形追加
  • ドラッグ&ドロップで移動
  • ダブルクリックで図形削除



Raphaël.js


const paper = Raphael('board', 800, 800);

const createBox = (paper, target) => {
  const box = paper.rect(
    target.cx,
    target.cy,
    target.width,
    target.height
    );
  box.attr({
    fill: '#333'
  });
  box.node.id = target.id;
  box.drag(drag.onMove, drag.onStart, drag.onEnd);
  box.dblclick(removeBox);
  return box;
}

const drag = {
  onStart (x, y, event) {
    const obj = objectMap[event.target.id];
    obj.node.dx = 0;
    obj.node.dy = 0;
  },
  onMove (dx, dy, x, y, event) {
    const obj = objectMap[event.target.id];
    const diffX = dx - obj.node.dx;
    const diffY = dy - obj.node.dy;
    
    obj.translate(diffX, diffY);
    obj.node.dx = dx;
    obj.node.dy = dy;
  },
  onEnd (event) {
  }
};

const removeBox = event => {
  const box = objectMap[event.target.id];
  box.remove();
};

let count = 0;
const objectMap = [];

document.getElementById('add').addEventListener('click', () => {
  const box = createBox(paper, {
    cx: 10,
    cy: 10,
    width: 100,
    height: 100,
    id: `box-${count}`
  });

  objectMap[`box-${count}`] = box;
  count++;
});


Snap.svg


const s = Snap(800, 800)

const createBox = (paper, target) => {
  const box = paper
    .rect(
      target.x,
      target.y,
      target.width,
      target.height
    )
    .attr({
      fill: '#333'
    })

  box.node.id = target.id
  box.drag()
  box.dblclick(removeBox)
  return box
}

let count = 0
const objectMap = []

const removeBox = event => {
  const box = objectMap[event.target.id]
  box.remove()
}
document.getElementById('add').addEventListener('click', () => {
  const box = createBox(s, {
    x: 100,
    y: 100,
    width: 100,
    height: 100,
    id: `box-${count}`
  })
  
  objectMap[`box-${count}`] = box
    count++
})


Raphaël.jsとSnap.svgを触った感想


レガシーブラウザの対応が必須ならRaphaël.js一択だが、モダンブラウザを使うならどちらでも良いと思う。
サンプルコードくらいしか書いていないので本質的な違いまではわからないが、これから「JSでSVG触りたい!」って人はSnap.svgを選択するのがベターだろう。

またRaphaël.jsはレガシーブラウザをサポートするため一部制約があるのに対し、Snap.svgはSVG仕様全般を利用するとこができる。これも大きなメリットだろう。

今回のサンプルコードを例にすると、ドラッグ&ドロップで図形を移動させる場合、Raphaël.jsだとドラッグ&ドロップのイベントも自分で書かなきゃいけなかったり、ドラッグ中に図形が重なったり、早くドラッグすると動作がおかしくなったりと面倒なことが多かった。
それに比べ、Snap.svgは「obj.drag()」だけで済む。


ということで、私は「Snap.svg」を使おうと思う。



参考サイト




以上

written by @bc_rikko

0 件のコメント :

コメントを投稿