@@ -13,12 +13,96 @@ public class GraphicHelper
1313
1414
1515 private static string prev_template =
16- "def path pb {scale=0.1 borderWidth = 1 borderColor = 0xff11ff borderAlpha = 0.8 fillColor = 0x00a1d6 fillAlpha = 0.8 duration=30s}\n def text cb {content = \" \" fontSize = 10% anchorX = 0 .5 anchorY = 0 .5 rotateX = 180 duration=30s }\n \n " ;
16+ "def path pb {width=10% viewBox= \" -512.0 -512.0 1024 1024 \" fillColor = 0x00a1d6 fillAlpha = 1 duration=30s}\n def text cb {content = \" \" fontSize = 10% anchorX= .5 anchorY= .5 duration=30s x=50% y=50% }\n \n " ;
1717
1818 private static Regex mediansPattern1 = new Regex ( @"(.*),""medians"":\[\[\[.*\]\]\](.*)" ) ;
1919
2020 private StringBuilder builder = new StringBuilder ( ) ;
2121 private List < char > preparedTxt = new List < char > ( ) ;
22+
23+ private static ( float , float ) GetBoundingBoxOffset ( GraphicInfo info )
24+ {
25+ /*
26+ * 在 make mea hanzi 的原文档中是这样说明边界的:
27+ * strokes: List of SVG path data for each stroke of this character, ordered by proper stroke order. Each stroke is laid out on a 1024x1024 size coordinate system where:
28+ The upper-left corner is at position (0, 900).
29+ The lower-right corner is at position (1024, -124).
30+ Note that the y-axes DECREASES as you move downwards, which is strage! To display these paths properly, you should hide render them as follows:
31+ * 如果计算边界的话,会将单个汉字在整个方框中的位置丢失。
32+ */
33+ float xMax = 1024 ;
34+ float xMin = 0 ;
35+ float yMax = 900 ;
36+ float yMin = - 124 ;
37+ info . Width = xMax - xMin ;
38+ info . Height = yMax - yMin ;
39+ return ( ( xMax + xMin ) / 2 , ( yMax + yMin ) / 2 ) ;
40+ /*
41+ float xMax = Single.MinValue;
42+ float xMin = Single.MaxValue;
43+ float yMax = Single.MinValue;
44+ float yMin = Single.MaxValue;
45+ foreach (var stroke in info.Strokes)
46+ {
47+ ClipHelper.SvgVisitor(stroke, (_, x, y, _, _, _, _) =>
48+ {
49+ if (x > xMax) xMax = x;
50+ if (x < xMin) xMin = x;
51+ if (y > yMax) yMax = y;
52+ if (y < yMin) yMin = y;
53+ });
54+ }
55+
56+ info.Width = xMax - xMin;
57+ info.Height = yMax - yMin;
58+ return ((xMax + xMin) / 2, (yMax + yMin) / 2);
59+ */
60+ }
61+
62+ private static void MoveToCenter ( GraphicInfo info )
63+ {
64+ var ( xOffset , yOffset ) = GetBoundingBoxOffset ( info ) ;
65+ List < string > result = new List < string > ( ) ;
66+ foreach ( var stroke in info . Strokes )
67+ {
68+ StringBuilder strBuilder = new StringBuilder ( ) ;
69+ ClipHelper . SvgVisitor ( stroke , ( cmd , x , y , c1X , c1Y , c2X , c2Y ) =>
70+ {
71+ strBuilder . Append ( cmd ) ;
72+ x = ( x - xOffset ) * 1 ;
73+ c1X = ( c1X - xOffset ) * 1 ;
74+ c2X = ( c2X - xOffset ) * 1 ;
75+ y = ( y - yOffset ) * - 1 ;
76+ c1Y = ( c1Y - yOffset ) * - 1 ;
77+ c2Y = ( c2Y - yOffset ) * - 1 ;
78+ switch ( cmd )
79+ {
80+ case "Z" :
81+ break ;
82+ case "M" :
83+ case "L" :
84+ strBuilder . Append ( $ "{ x : F1} { y : F1} ") ;
85+ break ;
86+ case "Q" :
87+ //c1 == c2
88+ strBuilder . Append ( $ " { c1X : F1} { c1Y : F1} ") ;
89+ strBuilder . Append ( $ " { x : F1} { y : F1} ") ;
90+ break ;
91+ case "C" :
92+ strBuilder . Append ( $ " { c1X : F1} { c1Y : F1} ") ;
93+ strBuilder . Append ( $ " { c2X : F1} { c2Y : F1} ") ;
94+ strBuilder . Append ( $ " { x : F1} { y : F1} ") ;
95+ break ;
96+ default :
97+ throw new InvalidDataException ( ) ;
98+ }
99+ } ) ;
100+ result . Add ( strBuilder . ToString ( ) ) ;
101+ strBuilder . Clear ( ) ;
102+ }
103+
104+ info . Strokes = result ;
105+ }
22106
23107 public GraphicHelper ( string dataPath )
24108 {
@@ -28,6 +112,7 @@ public GraphicHelper(string dataPath)
28112 {
29113 var ignoreMedian = mediansPattern1 . Replace ( graph , "$1$2" ) ;
30114 var newGraphic = Newtonsoft . Json . JsonConvert . DeserializeObject < GraphicInfo > ( ignoreMedian ) ;
115+ MoveToCenter ( newGraphic ) ;
31116 graphicData . Add ( newGraphic . Character . First ( ) , newGraphic ) ;
32117 }
33118 }
@@ -58,6 +143,8 @@ public void DefParent(string alias, string parent, TextProperty prop)
58143 if ( prop . zIndex != null ) builder . Append ( $ ",zIndex={ prop . zIndex } ") ;
59144 if ( prop . duration != null ) builder . Append ( $ ",duration={ prop . duration } s") ;
60145 if ( prop . alpha != null ) builder . Append ( $ ",alpha={ prop . alpha } ") ;
146+ if ( prop . anchorX != null ) builder . Append ( $ ",anchorX={ prop . anchorX } ") ;
147+ if ( prop . anchorY != null ) builder . Append ( $ ",anchorY={ prop . anchorY } ") ;
61148
62149 builder . Append ( "}\n " ) ;
63150 }
@@ -100,11 +187,14 @@ public void AddText(string txt, string alias, string parent, TextProperty prop,
100187 var subContainerName = $ "{ alias } _{ chSeq } _b{ partIndex } ";
101188
102189 builder . Append ( $ "let { strokeName } =p{ chIndex } _{ partIndex } {{parent=\" { subContainerName } \" alpha=1") ;
190+ //builder.Append($"viewBox=\"{-chGraphic.Width / 2:F1} {-chGraphic.Height / 2:F1} {chGraphic.Width:F0} {chGraphic.Height:F0}\"");
103191 if ( prop . borderAlpha != null ) builder . Append ( $ " borderAlpha={ prop . borderAlpha } ") ;
104192 if ( prop . borderWidth != null ) builder . Append ( $ " borderWidth={ prop . borderWidth } ") ;
105193 if ( ! string . IsNullOrEmpty ( prop . borderColor ) ) builder . Append ( $ " borderColor={ prop . borderColor } ") ;
106194 if ( ! string . IsNullOrEmpty ( prop . fillColor ) ) builder . Append ( $ " fillColor={ prop . fillColor } ") ;
107195 if ( prop . fillAlpha != null ) builder . Append ( $ " borderWidth={ prop . fillAlpha } ") ;
196+ //if (prop.width != null) builder.Append($" width={prop.width}%");
197+ //if (prop.height != null) builder.Append($" height={prop.height}%");
108198 builder . Append ( "}" ) ;
109199 builder . Append ( $ "let { subContainerName } = cb{{parent=\" { containerName } \" ") ;
110200 //这里的原因是因为scale属性一般是放在第二层,用于缩放本身的内容。如果anchor属性放在第一层可能无法取得预期的效果?
@@ -114,8 +204,9 @@ public void AddText(string txt, string alias, string parent, TextProperty prop,
114204 builder . Append ( $ "}}") ;
115205 builder . Append ( $ "let { containerName } = cb{{parent=\" { parent } \" ") ;
116206
117- if ( prop . x != null ) builder . Append ( $ ",x={ prop . x } %") ;
118- if ( prop . y != null ) builder . Append ( $ ",y={ prop . y } %") ;
207+ //实际上因为anchor 移动的是文字,定位点依然在右上角,所以这里手动加上50%
208+ if ( prop . x != null ) builder . Append ( $ ",x={ prop . x + 50 } %") ;
209+ if ( prop . y != null ) builder . Append ( $ ",y={ prop . y + 50 } %") ;
119210 if ( prop . rotateX != null ) builder . Append ( $ ",rotateX={ prop . rotateX } ") ;
120211 if ( prop . rotateY != null ) builder . Append ( $ ",rotateY={ prop . rotateY } ") ;
121212 if ( prop . rotateZ != null ) builder . Append ( $ ",rotateZ={ prop . rotateZ } ") ;
@@ -127,7 +218,7 @@ public void AddText(string txt, string alias, string parent, TextProperty prop,
127218 builder . Append ( "}\n " ) ;
128219 if ( onProcessMotion != null )
129220 {
130- var motion = new MotionHelper ( builder , containerName , subContainerName ) ;
221+ var motion = new MotionHelper ( builder , containerName , subContainerName , strokeName ) ;
131222 onProcessMotion ( motion , prop , chSeq , partIndex ) ;
132223 motion . ProcessBackupLayer ( ) ;
133224 }
0 commit comments