Skip to content

Commit 5914752

Browse files
committed
修正了所有文字位置的问题。
处理了全屏适配的问题。
1 parent 69d006e commit 5914752

File tree

6 files changed

+300
-11
lines changed

6 files changed

+300
-11
lines changed

Danmakux/ClipHelper.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,52 @@ namespace Danmakux
1111
{
1212
public static class ClipHelper
1313
{
14-
private static Regex svgPattern = new Regex(@"([A-Z])([ \t0-9\.,-]*)");
14+
public static Regex svgPattern = new Regex(@"([A-Z])([ \t0-9\.,-]*)");
15+
16+
public delegate void ElementHandler(string eleType, float currX, float currY, float ctl1X, float ctl1Y, float ctl2X, float ctl2Y);
17+
public static void SvgVisitor(string inputSvg, ElementHandler handler)
18+
{
19+
PathBuilder builder = new PathBuilder();
20+
var pointList = svgPattern.Matches(inputSvg);
21+
foreach (Match match in pointList)
22+
{
23+
var pointType = match.Groups[1].Value;
24+
var pointArgs = match.Groups[2].Value.Trim().Split(new char[] {' ', ','},
25+
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
26+
var currX = Single.NaN;
27+
var currY = Single.NaN;
28+
var ctl1X = Single.NaN;
29+
var ctl2X = Single.NaN;
30+
var ctl1Y = Single.NaN;
31+
var ctl2Y = Single.NaN;
32+
if (pointArgs.Length >= 6)
33+
{
34+
//C CTLX1 CTLY1 CTLX2 CTLY2 X Y
35+
ctl1X = float.Parse(pointArgs[0]);
36+
ctl1Y = float.Parse(pointArgs[1]);
37+
ctl2X = float.Parse(pointArgs[2]);
38+
ctl2Y = float.Parse(pointArgs[3]);
39+
currX = float.Parse(pointArgs[4]);
40+
currY = float.Parse(pointArgs[5]);
41+
}
42+
else if (pointArgs.Length >= 4)
43+
{
44+
//Q CTLX CTLY X Y
45+
ctl1X = ctl2X = float.Parse(pointArgs[0]);
46+
ctl1Y = ctl2Y = float.Parse(pointArgs[1]);
47+
currX = float.Parse(pointArgs[2]);
48+
currY = float.Parse(pointArgs[3]);
49+
}
50+
else if (pointArgs.Length >= 2)
51+
{
52+
//L AAA BBB
53+
currX = float.Parse(pointArgs[0]);
54+
currY = float.Parse(pointArgs[1]);
55+
}
56+
57+
handler(pointType, currX, currY, ctl1X, ctl1Y, ctl2X, ctl2Y);
58+
}
59+
}
1560

1661
/// <summary>
1762
/// 假定input是 X 方向向右, Y 方向向下空间里,大小 1024 x 1024 的一个路径,将 clipPath中的部分裁剪掉。

Danmakux/GraphicHelper.cs

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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}\ndef 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}\ndef 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
}

Danmakux/GraphicInfo.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ public class GraphicInfo
1010
[JsonProperty("strokes")]
1111
public List<string> Strokes { get; set; }
1212

13+
public float Width {get; set; }
14+
15+
public float Height { get; set; }
16+
1317
public struct Loc
1418
{
1519
[JsonProperty("x")]

Danmakux/MotionHelper.cs

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,64 @@ public class MotionHelper
66
{
77
private StringBuilder _publicBuilder = null;
88
private StringBuilder _backupBuilder = new StringBuilder();
9+
private StringBuilder _pathBuilder = null;//new StringBuilder();
910
private string _dstContainer = "";
1011
private string _dstBackup = "";
12+
private string _dstPath = "";
1113
private bool _isFirst = true;
1214
private bool _allBackupLayerRequired = false;
15+
//private bool _pathTransformRequired = false;
1316

14-
public MotionHelper(StringBuilder builder, string dstContainer, string dstBackup)
17+
public MotionHelper(StringBuilder builder, string dstContainer, string dstBackup, string dstPath)
1518
{
1619
_publicBuilder = builder;
1720
_dstContainer = dstContainer;
1821
_dstBackup = dstBackup;
22+
_dstPath = dstPath;
1923
}
24+
/*
25+
private MotionHelper ApplyPath(float duration, TextProperty prop = null, string motion = "linear")
26+
{
27+
var builder = _pathBuilder;
28+
bool isFirst = _isFirst;
29+
if (!_isFirst)
30+
builder.Append("then ");
31+
_isFirst = false;
32+
builder.Append($"set {_dstPath} {{");
33+
bool layerRequired = false;
34+
for (;;)
35+
{
36+
if (prop == null) break;
37+
if (prop.width != null)
38+
{
39+
builder.Append($"width={prop.width}%,");
40+
prop.width = null;
41+
layerRequired = true;
42+
}
2043
44+
if (prop.height != null)
45+
{
46+
builder.Append($"height={prop.height}%,");
47+
prop.height = null;
48+
layerRequired = true;
49+
}
50+
break;
51+
}
52+
53+
builder.Append($"}} {duration}s");
54+
if (motion != "linear" && layerRequired)
55+
{
56+
builder.Append($",\"{motion}\"");
57+
}
58+
builder.Append($"\n");
59+
60+
if (layerRequired)
61+
_pathTransformRequired = true;
62+
63+
return this;
64+
}
65+
*/
66+
2167
public MotionHelper Apply(float duration, TextProperty prop = null, string motion = "linear", bool isBackup = false)
2268
{
2369
//set b_3_1 {} 0.1s then set b_3_1 {x = 20%, y = 0%, rotateY = 0, alpha = 1} 1s, "ease-out" then set b_3_1{} 2s
@@ -34,14 +80,16 @@ public MotionHelper Apply(float duration, TextProperty prop = null, string moti
3480
if (prop == null) break;
3581
if (prop.x != null)
3682
{
37-
builder.Append($"x={prop.x}%,");
83+
//加 50 的原因参见 GraphicHelper对应部分
84+
builder.Append($"x={prop.x + 50}%,");
3885
prop.x = null;
3986
backupLayerRequired = true;
4087
}
4188

4289
if (prop.y != null)
4390
{
44-
builder.Append($"y={prop.y}%,");
91+
//加 50 的原因参见 GraphicHelper对应部分
92+
builder.Append($"y={prop.y + 50}%,");
4593
prop.y = null;
4694
backupLayerRequired = true;
4795
}
@@ -108,7 +156,12 @@ public MotionHelper Apply(float duration, TextProperty prop = null, string moti
108156
(prop.rotateX != null || prop.rotateY != null || prop.rotateZ != null || prop.scale != null))
109157
_allBackupLayerRequired = true;
110158
Apply(duration, prop, motion, true);
159+
160+
161+
//_isFirst = isFirst;
162+
//ApplyPath(duration, prop, motion);
111163
}
164+
112165

113166
return this;
114167
}
@@ -119,6 +172,12 @@ public void ProcessBackupLayer()
119172
{
120173
_publicBuilder.Append(_backupBuilder.ToString());
121174
}
175+
/*
176+
if (_pathTransformRequired)
177+
{
178+
_publicBuilder.Append(_pathBuilder.ToString());
179+
}
180+
*/
122181
}
123182
}
124183
}

0 commit comments

Comments
 (0)