안드로이드 연습 시리즈(41), 한자 획순의 간단한 애니메이션

애니메이션의 내용과 관련하여 이전에 여러 기사를 작성한 적이 있습니다.

이 섹션에서는 획 순서 애니메이션 효과를 구현합니다. 아이디어는 오픈 소스 라이브러리 Hanzi Writer 에서 비롯되었으며 공식 웹 사이트의 효과입니다.

캡처 2022-05-28 at 18.58.02.gif

하지만 Android는 직접 사용할 수 없으므로 모방의 아이디어가 있습니다. 이 자매 라이브러리 hanzi-writer-data 에서 소스 데이터를 찾았습니다 . 이는 json입니다.

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

한자 "나"를 예로 들면 이런식으로 지저분해 보이죠? 다행히도 저는 SVG 형식에 대해 약간 이해하고 있습니다

이미지.png

그 중 SVG 형식은 고정되어 있으며 각 문자(대소문자 구분 안 함)에는 다음과 같은 의미가 있습니다.

  • M xy : 브러시를 (x, y) 지점으로 이동하여 그리기 시작할 준비가 되었음을 나타냅니다.
  • L xy : Line toL 명령이 (x, y)에 선분을 그립니다.
  • Z : Z이 명령은 현재 지점에서 경로의 시작점, 즉 닫힌 경로까지 직선을 그립니다.
  • Q x1 y1, xy : 제어점을 통해 2차 베지어 곡선을 그립니다.
  • C x1 y1, x2 y2, xy : 두 개의 제어점을 통해 (x, y)까지 3차 베지어 곡선을 그립니다.

strokes그것이 SVG 데이터라는 것을 알 수 있습니다. 우리medians 는 나중에 탐색할 것입니다. 먼저 그림을 그리고 효과를 보십시오.radStrokesstrokes

파싱 ​​스트로크

이 단계는 매우 간단하고 순수한 하위 질문입니다.

  1. hanzi-writer-data 소스 데이터를 assets 디렉토리에 저장하든 로컬 경로에 저장하든 상관 없습니다.
  2. 특정 경로에서 한자 json 구문 분석

여기에 코드를 직접 붙여넣습니다.

이미지.png

획을 그리다

첫 번째 문제는 SVG 데이터를 가져온 후 Canvas를 통해 어떻게 그립니다.

연구 후 시스템이 우리에게 좋은 인터페이스를 PathParser제공 .

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

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

이미지.png

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

이미지.png

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

이미지.png

再运行,看下效果:

이미지.png

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

探究medians

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

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

이미지.png

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

이미지.png

效果见下:

이미지.png

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

이미지.png

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

动起来

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

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

이미지.png

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

이미지.png

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

이미지.png

来看下效果:

스트로크1.gif

좋아요, 스트로크는 이미 움직이고 있습니다. 하지만.. 우리가 Hanzi Writer원하는 이러합니다. 이것은 분명히 표준에 맞지 않습니다. 걱정하지 마십시오. Canvas 레이어에 대해 알고 있다면 이 시점에서 아이디어가 있어야 한다고 생각합니다.

스트로크 순서 애니메이션

캔버스 레이어는 이 섹션의 초점이 아니므로 아직 모르면 만들 수 있습니다.

여기에서 아이디어는 레이어를 만들고 레이어 strokesmedians혼합 효과를 표시하는 것입니다.

이미지.png

먼저 진행 상황에 따라 진행 중인 모든 획 경로를 그리고 대상 이미지 비트맵을 생성합니다.여기서 srcMode가 사용되며 이는 원본 이미지만 유지됨을 의미합니다.

이미지.png

현재 브러시 모드를 로 설정합니다. PorterDuff.Mode.SRC_IN즉, 원본 이미지와 대상 이미지가 교차하는 위치에만 원본 이미지가 그려집니다.

이미지.png

다음으로 진행 상황에 따라 진행 중인 모든 획, 즉 srcMode가 사용되는 중간 경로를 그립니다. 즉, 원본 이미지만 유지됩니다.

이미지.png

마지막으로 캔버스를 복원합니다.

이미지.png

효과를 살펴보십시오. 괜찮습니까?

스트로크2.gif

사실 거의 강박장애라 참을 수 없고 조금 부족합니다.

펜 시작 호

해결책으로 각 스트로크의 첫 번째와 마지막 백본 포인트의 위치에 작은 원을 그리고 그것을 중심으로 작은 원을 그리려고 노력했습니다. 방향이 불확실하기 때문에 원이 좋은 선택, 지불 srcCanvas에 그리는 것에 주의하십시오.

데이터 위치는 위에서 언급한 바와 같이 각 스트로크의 첫 번째 지점과 마지막 지점을 medians취 합니다. 구문 분석 방법은 언급되지 않습니다. 특정 코드에 대한 데모를 참조하십시오.

이미지.png

srcBmp를 그릴 때 pen-start 및 pen-down 라디안을 추가하고 인덱스에 주의하십시오.

이미지.png

효과를 보세요. 완벽합니다.

스트로크4.gif

글쎄, 이 섹션은 여기에 있다. 코드는 github 에 업로드 되었다 . 관심이 있다면 살펴볼 수 있다.

참고문헌

рекомендация

отjuejin.im/post/7103192601515425823
рекомендация