OSDN Git Service

Support the rotate attribute of the animateMotion element
authordhrname <dhrname@users.sourceforge.jp>
Tue, 26 Jul 2016 14:05:11 +0000 (23:05 +0900)
committerdhrname <dhrname@users.sourceforge.jp>
Tue, 26 Jul 2016 14:05:11 +0000 (23:05 +0900)
org/w3c/dom/smil.js

index 9f58e03..3dbb712 100644 (file)
@@ -1699,7 +1699,7 @@ base("$calcMode").up("$attribute").mix( {
     },\r
     \r
     /*図の現在の角度rを求めて、rotate(rの文字列(最後に括弧はいらない)で返すメソッド*/\r
-    getRotate: function(path, advanceLength) {\r
+    getRotate: function(path, advanceLength, rotate) {\r
       /*パスセグメントの数値を求めてから、動いている図形の傾き角度r(ラジアンではなく度数)を算出する*/\r
       var length = path.getPathSegAtLength(advanceLength),\r
           seg = path.pathSegList.getItem(length),\r
@@ -1711,21 +1711,25 @@ base("$calcMode").up("$attribute").mix( {
         if (nextCommand === "M") {\r
           return "";\r
         } else if (nextCommand === "L") {\r
-          return ") rotate(" +Math.atan2(nextSeg.y-seg.y, nextSeg.x-seg.x)/Math.Pi*180+ "";\r
+          return ") rotate(" +(Math.atan2(nextSeg.y-seg.y, nextSeg.x-seg.x)/Math.Pi*180 + rotate)+ "";\r
         } else if (nextCommand === "C") {\r
+          return ") rotate(" +(Math.atan2(nextSeg.y1-seg.y, nextSeg.x1-seg.x)/Math.Pi*180 + rotate)+ "";\r
         }\r
       } else if ((command === "L") && (length-1 >= 0)) {\r
         var preSeg = path.pathSegList.getItem(length-1);\r
-        return ") rotate(" +Math.atan2(seg.y-preSeg.y, seg.x-preSeg.x)/Math.Pi*180+ "";\r
+        return ") rotate(" +(Math.atan2(seg.y-preSeg.y, seg.x-preSeg.x)/Math.Pi*180 + rotate)+ "";\r
       } else if (command === "C") {\r
-        /*3次ベジェ曲線は媒介曲線\r
-         *x = (x4-3*(x3-x2)-x1)*t*t*t + 3*(x3-2*x2+x1)*t*t + 3*(x2-x1)*t + x1\r
-         *y = (y4-3*(y3-y2)-y1)*t*t*t + 3*(y3-2*y2+y1)*t*t + 3*(y2-y1)*t + y1\r
-         *なので、媒介曲線の微分dy/dxが接線の傾きとなる\r
-         *したがって、微分したx'と微分したy'をatan2に入力すれば、角度が算出できる*/\r
+        /*3次ベジェ曲線を微分する方法はニュートン法など数値解析の必要があるので、\r
+         * 以下の通り、別の方法を採用する。\r
+         * 現在位置から一歩進んだ曲線上の点Bをとり、それを、現在の点Aと結んで線分ABとしたとき、\r
+         * その直線の傾きからおおよその角度を求める*/\r
          var point = path.getPointAtLength(advanceLength),\r
              x = point.x,\r
              y = point.y;\r
+         /*一歩進んだ点*/\r
+         point = path.getPointAtLength(advanceLength+1);\r
+         console.log(Math.PI);\r
+         return ") rotate(" +(Math.atan2(point.y-y, point.x-x)/Math.PI*180 + rotate)+ "";\r
       }\r
     },\r
     \r
@@ -1735,11 +1739,18 @@ base("$calcMode").up("$attribute").mix( {
       var path = this.path,\r
           advanceLength = advance * path.getTotalLength();\r
       /*全体の距離から、現在進めている距離を算出して、そこから、現在点を導き出す*/\r
-      var point = path.getPointAtLength(advanceLength);\r
+      var point = path.getPointAtLength(advanceLength),\r
+          rotate = 0; //追加すべき角度\r
       if (this.rotate === "0") {\r
         return point.x+ "," +point.y;\r
+      } else if (this.rotate === "auto") {\r
+        rotate = 0;\r
+      } else if (this.rotate === "auto-reverse") {\r
+        rotate = 180;\r
+      } else {\r
+        rotate = +this.rotate;\r
       }\r
-      return point.x+ "," +point.y + this.getRotate(path, advanceLength);\r
+      return point.x+ "," +point.y + this.getRotate(path, advanceLength, rotate);\r
     }\r
   } )\r
   .on("init", function (ele) {\r