SVGの描画内容をCanvasで利用するのは、CanvasをSVGで利用するのに比べて幾分か大変です。
(CanvasをSVGで利用する方法はこちら)
Operaでは、
ctx.drawImage(svg, 0, 0);
という書き方が許されるのですが、残念ながらFirefoxやChrome、Safariといった他のメジャーなブラウザではこの方法は対応しておりません(そもそも仕様違反です)。というわけで、ちょっとひねった方法を使う必要があります。
<!DOCTYPE html>
<html><head><title>SVGをCanvasで利用する</title>
<script>
var svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' +
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' +
'<g transform="matrix(0.0298614501953125,-0.0054168701171875,0.0054168701171875,0.0298614501953125,79.8,32.25)">' +
'<path stroke="none" fill="rgb(0,0,0)" d="M -2782.7569658689836 608.6833301566228 L 84.893028645503 1128.8753322274672 ' +
'L 1683.7664050978372 132.97224006629114 L -858.0511140648059 -328.1137176765489 L 181.5633642527544 -1047.0521235003948 ' +
'L -275.57473549460883 -1129.9770215128187 L -2782.7569658689836 608.6833301566228 M -1951.5829286777084 429.60166597823917 ' +
'L -1237.2442827046566 -65.36827816052792 L 795.561309788937 303.38286406493205 L 19.622494346381792 787.1785311665641 ' +
'L -1951.5829286777084 429.60166597823917 "/></g></svg>';
window.onload = function() {
var img = new Image();
img.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
ctx.drawImage(img, 0, 0);
};
img.src = "data:image/svg+xml;base64," + btoa(svg);
};
</script></head><body><canvas id="canvas" width="150" height="100"></canvas></body></html>
コードの簡単な説明をします。
- 4行目から11行目までは、SVGの文字列です。Canvasで扱うには文字列にしなければいけません。
- 14行目でimgエレメントを作成し、19行目でソースに先程のSVGをbase64で指定します。
btoa・atobはbase64に変換する関数で、Canvasをサポートしている大抵のブラウザに組み込まれています - 15行目~18行目は、読みこんだ後にCanvasにコピーしています。imgはimgエレメントなので、ここの部分を
document.body.appendChild(img);
とやっても問題なく動きます。
このように、data:を使って画像ファイルとして埋め込むのがポイントです。
実行結果はこちらです。
既にDOM上に出来たSVGを読む場合は、次のURLのコードが参考になると思います。
http://www.svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/index.html
下記、転載です(varの付け忘れとセミコロンの付け忘れを補完しました)。
function importSVG(sourceSVG, targetCanvas) {
// https://developer.mozilla.org/en/XMLSerializer
var svg_xml = (new XMLSerializer()).serializeToString(sourceSVG);
var ctx = targetCanvas.getContext('2d');
// this is just a JavaScript (HTML) image
var img = new Image();
// http://en.wikipedia.org/wiki/SVG#Native_support
// https://developer.mozilla.org/en/DOM/window.btoa
img.src = "data:image/svg+xml;base64," + btoa(svg_xml);
img.onload = function() {
// after this, Canvas’ origin-clean is DIRTY
ctx.drawImage(img, 0, 0);
};
}
XMLSerializerも、大抵のブラウザで使用可能だと思います。ただ、このコードで気をつけなくてはいけないのは、XMLSerializerは一部のSVGのDOMに対してnamespaceを付与しないことがあります。xlinkなどが特にその犠牲になることがあるので、そのまま読み込むことが出来ない場合は一度シリアライズされたXMLをそのままブラウザで読めるかどうか確認してみてください。
また、一度SVGからCanvasに描画をしてしまうと、そのCanvasではgetImageData関数が使えなくなります。その詳細については先程のページに詳しく書いてありますが、下記のページにも日本語でのコメントが書いてありますので、気になる方は参考にしてみてください。
http://d.hatena.ne.jp/gyuque/20110510