ブラウザでSVGを表示するSIEの開発 (SIE - to display SVG on legacy browsers)
| リビジョン | 6193feae7c888edd0253ace4c6d15c712b4fa948 (tree) |
|---|---|
| 日時 | 2016-07-26 23:05:11 |
| 作者 | dhrname <dhrname@user...> |
| コミッター | dhrname |
Support the rotate attribute of the animateMotion element
| @@ -1699,7 +1699,7 @@ base("$calcMode").up("$attribute").mix( { | ||
| 1699 | 1699 | }, |
| 1700 | 1700 | |
| 1701 | 1701 | /*図の現在の角度rを求めて、rotate(rの文字列(最後に括弧はいらない)で返すメソッド*/ |
| 1702 | - getRotate: function(path, advanceLength) { | |
| 1702 | + getRotate: function(path, advanceLength, rotate) { | |
| 1703 | 1703 | /*パスセグメントの数値を求めてから、動いている図形の傾き角度r(ラジアンではなく度数)を算出する*/ |
| 1704 | 1704 | var length = path.getPathSegAtLength(advanceLength), |
| 1705 | 1705 | seg = path.pathSegList.getItem(length), |
| @@ -1711,21 +1711,25 @@ base("$calcMode").up("$attribute").mix( { | ||
| 1711 | 1711 | if (nextCommand === "M") { |
| 1712 | 1712 | return ""; |
| 1713 | 1713 | } else if (nextCommand === "L") { |
| 1714 | - return ") rotate(" +Math.atan2(nextSeg.y-seg.y, nextSeg.x-seg.x)/Math.Pi*180+ ""; | |
| 1714 | + return ") rotate(" +(Math.atan2(nextSeg.y-seg.y, nextSeg.x-seg.x)/Math.Pi*180 + rotate)+ ""; | |
| 1715 | 1715 | } else if (nextCommand === "C") { |
| 1716 | + return ") rotate(" +(Math.atan2(nextSeg.y1-seg.y, nextSeg.x1-seg.x)/Math.Pi*180 + rotate)+ ""; | |
| 1716 | 1717 | } |
| 1717 | 1718 | } else if ((command === "L") && (length-1 >= 0)) { |
| 1718 | 1719 | var preSeg = path.pathSegList.getItem(length-1); |
| 1719 | - return ") rotate(" +Math.atan2(seg.y-preSeg.y, seg.x-preSeg.x)/Math.Pi*180+ ""; | |
| 1720 | + return ") rotate(" +(Math.atan2(seg.y-preSeg.y, seg.x-preSeg.x)/Math.Pi*180 + rotate)+ ""; | |
| 1720 | 1721 | } else if (command === "C") { |
| 1721 | - /*3次ベジェ曲線は媒介曲線 | |
| 1722 | - *x = (x4-3*(x3-x2)-x1)*t*t*t + 3*(x3-2*x2+x1)*t*t + 3*(x2-x1)*t + x1 | |
| 1723 | - *y = (y4-3*(y3-y2)-y1)*t*t*t + 3*(y3-2*y2+y1)*t*t + 3*(y2-y1)*t + y1 | |
| 1724 | - *なので、媒介曲線の微分dy/dxが接線の傾きとなる | |
| 1725 | - *したがって、微分したx'と微分したy'をatan2に入力すれば、角度が算出できる*/ | |
| 1722 | + /*3次ベジェ曲線を微分する方法はニュートン法など数値解析の必要があるので、 | |
| 1723 | + * 以下の通り、別の方法を採用する。 | |
| 1724 | + * 現在位置から一歩進んだ曲線上の点Bをとり、それを、現在の点Aと結んで線分ABとしたとき、 | |
| 1725 | + * その直線の傾きからおおよその角度を求める*/ | |
| 1726 | 1726 | var point = path.getPointAtLength(advanceLength), |
| 1727 | 1727 | x = point.x, |
| 1728 | 1728 | y = point.y; |
| 1729 | + /*一歩進んだ点*/ | |
| 1730 | + point = path.getPointAtLength(advanceLength+1); | |
| 1731 | + console.log(Math.PI); | |
| 1732 | + return ") rotate(" +(Math.atan2(point.y-y, point.x-x)/Math.PI*180 + rotate)+ ""; | |
| 1729 | 1733 | } |
| 1730 | 1734 | }, |
| 1731 | 1735 |
| @@ -1735,11 +1739,18 @@ base("$calcMode").up("$attribute").mix( { | ||
| 1735 | 1739 | var path = this.path, |
| 1736 | 1740 | advanceLength = advance * path.getTotalLength(); |
| 1737 | 1741 | /*全体の距離から、現在進めている距離を算出して、そこから、現在点を導き出す*/ |
| 1738 | - var point = path.getPointAtLength(advanceLength); | |
| 1742 | + var point = path.getPointAtLength(advanceLength), | |
| 1743 | + rotate = 0; //追加すべき角度 | |
| 1739 | 1744 | if (this.rotate === "0") { |
| 1740 | 1745 | return point.x+ "," +point.y; |
| 1746 | + } else if (this.rotate === "auto") { | |
| 1747 | + rotate = 0; | |
| 1748 | + } else if (this.rotate === "auto-reverse") { | |
| 1749 | + rotate = 180; | |
| 1750 | + } else { | |
| 1751 | + rotate = +this.rotate; | |
| 1741 | 1752 | } |
| 1742 | - return point.x+ "," +point.y + this.getRotate(path, advanceLength); | |
| 1753 | + return point.x+ "," +point.y + this.getRotate(path, advanceLength, rotate); | |
| 1743 | 1754 | } |
| 1744 | 1755 | } ) |
| 1745 | 1756 | .on("init", function (ele) { |