JavaScript で SVG の角を丸める方法のメモ
二次スプライン曲線を利用して少ない手間で角を曲げる方法。
Firefox 3.0.5, Safari 3.2.1, Opera 9.63 にて動作確認済み。
参考サイト
http://www.geocities.co.jp/Playtown-Denei/7552/ScriptLib/roundRoC.html
http://hakuhin.hp.infoseek.co.jp/main/as/math.html
ソース (roundEdge.xml)
<?xml version='1.0'?> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg"> <head> <title>JavaScript で SVG の角を丸める</title> <script type="text/javascript"> <![CDATA[ function roundEdge(path, radius) { //パスをリセット resetPath(); //各ポイントの取得 var A = path.pathSegList.getItem(0); //左の点 var B = path.pathSegList.getItem(1); //真ん中の点 var C = path.pathSegList.getItem(2); //右の点 //任意の2点から角度を割り出す var angle1 = Math.atan2(B.y - A.y, B.x - A.x); //A,B間の角度 var angle2 = Math.atan2(C.y - B.y, C.x - B.x); //B,C間の角度 //二次スプライン曲線用のポイントB1とB2を割り出す var B1x = B.x - (Math.cos(angle1) * radius); var B1y = B.y - (Math.sin(angle1) * radius); var B2x = B.x + (Math.cos(angle2) * radius); var B2y = B.y + (Math.sin(angle2) * radius); //二次スプライン曲線を利用して角を丸める path.setAttribute('d', 'M '+A.x+','+A.y+' L '+B1x+','+B1y+' Q '+B.x+','+B.y+' '+B2x+','+B2y+' L '+C.x+','+C.y); } function resetPath() { document.getElementById('path').setAttribute('d', 'M 73.574464,78.567376 L 172.96453,26.936173 L 509.85816,121.16312'); return false; } function round() { var path = document.getElementById('path'); var radius = Number(document.getElementById('radius').value); if(radius <= 0 || isNaN(radius)) { window.alert('正数を入力してください。'); return false; } roundEdge(path, radius); return false; } ]]> </script> </head> <body> <h1>JavaScript で SVG の角を丸める</h1> <form action="./" onreset="return resetPath();" onsubmit="return round();"> <input type="text" id="radius" value="20" /> <input type="submit" name="submit" value="角を丸める" /> <input type="reset" value="リセット" /> </form> <p> <svg:svg width="600" height="300"> <svg:path d="M 73.574464,78.567376 L 172.96453,26.936173 L 509.85816,121.16312" id="path" style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </svg:svg> </p> </body> </html>