In Bezug auf den Inhalt der Animation habe ich bereits mehrere Artikel geschrieben:
Dieser Abschnitt implementiert einen Strichfolge-Animationseffekt. Die Idee stammt von der Open-Source-Bibliothek Hanzi Writer , dies ist der Effekt ihrer offiziellen Website:
Aber Android kann nicht direkt verwendet werden, daher gibt es eine Idee der Nachahmung. Ich habe seine Quelldaten in dieser Schwesterbibliothek hanzi-writer-data gefunden, die ein json ist,
{"strokes": [], "medians": [], "radStrokes": []}
复制代码
Nehmen Sie das chinesische Schriftzeichen „I“ als Beispiel, es ist so, es ist chaotisch, oder? Zum Glück habe ich ein wenig Verständnis für das SVG-Format:
Unter ihnen ist das SVG-Format festgelegt, und jeder Buchstabe (Groß-/Kleinschreibung wird nicht beachtet) hat seine Bedeutung:
- M xy : Zeigt an, dass der Pinsel zum Punkt (x, y) bewegt wird, bereit zum Zeichnen
- L xy : bedeutet
Line to
, der L-Befehl zeichnet ein Liniensegment zu (x, y) - Z :
Z
Der Befehl zeichnet eine gerade Linie vom aktuellen Punkt zum Startpunkt des Pfads, d. h. einen geschlossenen Pfad - Q x1 y1, xy : Zeichne eine Bezier-Kurve zweiter Ordnung durch einen Kontrollpunkt
- C x1 y1, x2 y2, xy : Zeichne eine kubische Bezierkurve durch zwei Kontrollpunkte zu (x, y)
Es ist ersichtlich, dass strokes
es sich um solche SVG-Daten handelt, medians
und radStrokes
wir werden später untersuchen, zuerst strokes
zeichnen und den Effekt sehen.
Striche parsen
Dieser Schritt ist sehr einfach, reine Teilfrage:
- Es spielt keine Rolle, ob Sie die Hanzi-Writer-Datenquellendaten im Assets-Verzeichnis oder im lokalen Pfad speichern
- Analysieren Sie das chinesische Zeichen json unter einem bestimmten Pfad
Fügen Sie den Code direkt hier ein:
Striche zeichnen
Das erste Problem besteht darin, dass Sie die SVG-Daten nach dem Abrufen durch Canvas zeichnen können.
Nach Recherchen hat sich herausgestellt, dass uns das PathParser
System eine gute Schnittstelle bietet:
// 可以解析 SVG 数据, 生成绘制所需要的 Path
PathParser.createPathFromPathData(String pathData)
复制代码
代码是这样的,拿到汉字笔画的 path 集合:
这样一来,我们就可以直接在 draw(Canvas)
接口中绘制了,
运行,发现并没有正常显示出来。经过排查,是因为 hanzi-writer-data
提供的源数据,绘制出来是上下翻转的,而且大小默认 1024 * 1024px, 所以在绘制的时候,我们需要将 y 轴翻转并等比缩放,来看下代码吧:
再运行,看下效果:
完美。但这是静态的,怎么能像 Hanzi Writer
这样动起来呢?
探究medians
在源数据 json 内的 medians
,这是干嘛的?
我们将 medians
解析出来,主要代码见下,medians 是解析出来的 path 集合:
在上文的 draw(Canvas)
方法中绘制出来:
效果见下:
可以猜测每个 path array 其实就是汉字的一个笔画,为了验证是否正确,我将每个笔画 array 的第一个 point 坐标都点了出来,来看下效果,是这样的:
至此,我们应该知道 medians
的含义了。
动起来
现在为止,我们已经知道了 每个汉字的笔画 和 组成笔画的若干骨干点。想动起来,是不是只需要按默认顺序绘制笔画就行了,为了更平滑的效果,我们可以在每个骨干点间进行差值动画。
说干就干,这是属性动画差值:
创建一个 PathMeasure
集合来存储 path, 目的是拿到路径长度和截取路径,具体就不在这里展开说了:
最后根据进度值,在 draw(Canvas)
方法内绘制即可,其中 temp 的作用是,将截取出来的路径,保存到 temp 内:
来看下效果:
ok, die Striche bewegen sich schon. Aber ... der Effekt, den wir wollen, ist Hanzi Writer
so , das entspricht offensichtlich nicht dem Standard, keine Sorge, wenn Sie sich mit der Canvas-Ebene auskennen, sollten Sie zu diesem Zeitpunkt eine Idee haben.
Strichreihenfolge-Animation
Die Leinwandebene steht nicht im Mittelpunkt dieses Abschnitts. Wenn Sie sie noch nicht kennen, können Sie sie nachholen.
Die Idee hier ist, eine Ebene zu erstellen und strokes
den medians
gemischten Effekt von und auf der Ebene anzuzeigen.
Zeichnen Sie zunächst alle Strichpfade entsprechend des Fortschritts und generieren Sie das Bitmap des Zielbilds.Hier wird srcMode verwendet, was bedeutet, dass nur das Quellbild erhalten bleibt:
Stellen Sie den aktuellen Pinselmodus auf ein PorterDuff.Mode.SRC_IN
, was bedeutet, dass das Quellbild nur dort gezeichnet wird, wo sich das Quellbild und das Zielbild schneiden:
Zeichnen Sie als Nächstes gemäß dem Fortschritt alle Striche im Fortschritt, dh den mittleren Pfad, in dem srcMode verwendet wird, was bedeutet, dass nur das Quellbild beibehalten wird:
Stellen Sie schließlich die Leinwand wieder her:
Schau dir mal den Effekt an, ist das ok:
Tatsächlich ist es fast so, als obsessive Zwangsstörung, ich kann es wirklich nicht ertragen, und mir fehlt ein bisschen.
Stiftstartbogen
Als Lösung habe ich versucht, an der Position des ersten und letzten Rückgratpunkts jedes Strichs einen kleinen Kreis zu zeichnen und einen kleinen Kreis mit ihm als Zentrum zu zeichnen, da die Richtung ungewiss ist, ist der Kreis eine gute Wahl, zahlen Sie Aufmerksamkeit auf die srcCanvas zu lenken.
Datenposition, wie oben erwähnt, medians
nehmen Sie den ersten Punkt und den letzten Punkt jedes Strichs in , die Parsing-Methode wird nicht erwähnt, bitte sehen Sie sich die Demo für den spezifischen Code an.
Fügen Sie beim Zeichnen von srcBmp das Bogenmaß Stift-Start und Stift-unten hinzu, achten Sie auf den Index:
Schauen Sie sich den Effekt an, perfekt:
Nun, dieser Abschnitt ist hier, der Code wurde auf github hochgeladen , Sie können einen Blick darauf werfen, wenn Sie interessiert sind.