Serie de práctica de Android (41), una animación simple del orden de los trazos de los caracteres chinos

En cuanto al contenido de la animación, he escrito varios artículos antes:

Esta sección implementa un efecto de animación de orden de trazos. La idea proviene de la biblioteca de código abierto Hanzi Writer , este es el efecto de su sitio web oficial:

Captura 2022-05-28 en 18.58.02.gif

Pero Android no se puede usar directamente, por lo que existe una idea de imitación. Encontré sus datos de origen en esta biblioteca hermana hanzi-writer-data , que es un json,

{"strokes": [], "medians": [], "radStrokes": []}
复制代码

Tome el carácter chino "I" como ejemplo, es así, es desordenado, ¿verdad? Afortunadamente, entiendo un poco el formato SVG:

imagen.png

Entre ellos, el formato SVG es fijo, y cada letra (sin distinción entre mayúsculas y minúsculas) tiene su significado:

  • M xy : Indica mover el pincel al punto (x, y), listo para comenzar a dibujar
  • L xy: significa Line toque el comando L dibujará un segmento de línea a (x, y)
  • Z: ZEl comando dibujará una línea recta desde el punto actual hasta el punto de inicio del camino, es decir, un camino cerrado
  • Q x1 y1, xy : dibujar una curva Bezier de segundo orden a través de un punto de control
  • C x1 y1, x2 y2, xy : dibuje una curva bezier cúbica a través de dos puntos de control a (x, y)

Se puede ver que strokeses un dato SVG de este tipo, mediansy radStrokeslo exploraremos más adelante, primero strokesdibuje y vea el efecto.

analizar trazos

Este paso es muy simple, pura sub-pregunta:

  1. No importa si guarda los datos de origen de hanzi-writer-data en el directorio de activos o en la ruta local
  2. Analice el carácter chino json en una ruta específica

Pegue el código directamente aquí:

imagen.png

dibujar trazos

El primer problema es que después de obtener los datos SVG, ¿cómo dibujarlos a través de Canvas?

Después de la investigación, se encuentra que el sistema nos PathParserproporciona una buena interfaz:

    // 可以解析 SVG 数据, 生成绘制所需要的 Path 
    PathParser.createPathFromPathData(String pathData)
复制代码

代码是这样的,拿到汉字笔画的 path 集合:

imagen.png

这样一来,我们就可以直接在 draw(Canvas) 接口中绘制了,

imagen.png

运行,发现并没有正常显示出来。经过排查,是因为 hanzi-writer-data 提供的源数据,绘制出来是上下翻转的,而且大小默认 1024 * 1024px, 所以在绘制的时候,我们需要将 y 轴翻转并等比缩放,来看下代码吧:

imagen.png

再运行,看下效果:

imagen.png

完美。但这是静态的,怎么能像 Hanzi Writer 这样动起来呢?

探究medians

在源数据 json 内的 medians ,这是干嘛的?

我们将 medians 解析出来,主要代码见下,medians 是解析出来的 path 集合:

imagen.png

在上文的 draw(Canvas) 方法中绘制出来:

imagen.png

效果见下:

imagen.png

可以猜测每个 path array 其实就是汉字的一个笔画,为了验证是否正确,我将每个笔画 array 的第一个 point 坐标都点了出来,来看下效果,是这样的:

imagen.png

至此,我们应该知道 medians 的含义了。

动起来

现在为止,我们已经知道了 每个汉字的笔画 和 组成笔画的若干骨干点。想动起来,是不是只需要按默认顺序绘制笔画就行了,为了更平滑的效果,我们可以在每个骨干点间进行差值动画。

说干就干,这是属性动画差值:

imagen.png

创建一个 PathMeasure 集合来存储 path, 目的是拿到路径长度和截取路径,具体就不在这里展开说了:

imagen.png

最后根据进度值,在 draw(Canvas) 方法内绘制即可,其中 temp 的作用是,将截取出来的路径,保存到 temp 内:

imagen.png

来看下效果:

trazo1.gif

ok, los trazos ya se están moviendo. Pero... el efecto que queremos es Hanzi Writerasí , esto obviamente no está a la altura del estándar, no se preocupe, si conoce la capa Canvas, creo que debería tener una idea en este momento.

Animación de orden de trazos

La capa del lienzo no es el foco de esta sección. Si aún no la conoce, puede inventarla.

La idea aquí es crear una capa y mostrar strokesel efecto mediansmixto de y sobre la capa.

imagen.png

Primero, de acuerdo con el progreso, dibuje todas las rutas de los trazos en el progreso y genere el mapa de bits de la imagen de destino. Aquí, se usa srcMode, lo que significa que solo se conserva la imagen de origen:

imagen.png

Establezca el modo de pincel actual en PorterDuff.Mode.SRC_IN, lo que significa que la imagen de origen solo se dibuja donde se cruzan la imagen de origen y la imagen de destino:

imagen.png

A continuación, de acuerdo con el progreso, dibuje todos los trazos en el progreso, es decir, la ruta mediana, donde se usa srcMode, lo que significa que solo se conserva la imagen de origen:

imagen.png

Finalmente, restaure el lienzo:

imagen.png

Echa un vistazo al efecto, ¿está bien?

trazo2.gif

De hecho, es casi, como un trastorno obsesivo-compulsivo, realmente no lo soporto, y me falta un poco.

Arco de inicio de pluma

Como solución, traté de dibujar un pequeño círculo en la posición del primer y último punto de la columna vertebral de cada trazo, y dibujé un pequeño círculo con él como centro, porque la dirección es incierta, el círculo es una buena opción, paga atención para dibujar en el srcCanvas.

Ubicación de datos, como se mencionó anteriormente, medianstome el primer punto y el último punto de cada trazo en , no se mencionará el método de análisis, consulte la demostración para el código específico.

imagen.png

Cuando dibuje srcBmp, agregue los radianes de inicio y descenso de la pluma, preste atención al índice:

imagen.png

Echa un vistazo al efecto, perfecto:

trazo4.gif

Bueno, esta sección está aquí, el código se ha subido a github , puedes echarle un vistazo si estás interesado.

Referencias

Supongo que te gusta

Origin juejin.im/post/7103192601515425823
Recomendado
Clasificación