mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import type {Position} from './@types'
2
3export type TransformMatrix = [
4 number,
5 number,
6 number,
7 number,
8 number,
9 number,
10 number,
11 number,
12 number,
13]
14
15// These are affine transforms. See explanation of every cell here:
16// https://en.wikipedia.org/wiki/Transformation_matrix#/media/File:2D_affine_transformation_matrix.svg
17
18export function createTransform(): TransformMatrix {
19 'worklet'
20 return [1, 0, 0, 0, 1, 0, 0, 0, 1]
21}
22
23export function applyRounding(t: TransformMatrix) {
24 'worklet'
25 t[2] = Math.round(t[2])
26 t[5] = Math.round(t[5])
27 // For example: 0.985, 0.99, 0.995, then 1:
28 t[0] = Math.round(t[0] * 200) / 200
29 t[4] = Math.round(t[0] * 200) / 200
30}
31
32// We're using a limited subset (always scaling and translating while keeping aspect ratio) so
33// we can assume the transform doesn't encode have skew, rotation, or non-uniform stretching.
34
35// All write operations are applied in-place to avoid unnecessary allocations.
36
37export function readTransform(t: TransformMatrix): [number, number, number] {
38 'worklet'
39 const scale = t[0]
40 const translateX = t[2]
41 const translateY = t[5]
42 return [translateX, translateY, scale]
43}
44
45export function prependTranslate(t: TransformMatrix, x: number, y: number) {
46 'worklet'
47 t[2] += t[0] * x + t[1] * y
48 t[5] += t[3] * x + t[4] * y
49}
50
51export function prependScale(t: TransformMatrix, value: number) {
52 'worklet'
53 t[0] *= value
54 t[1] *= value
55 t[3] *= value
56 t[4] *= value
57}
58
59export function prependTransform(ta: TransformMatrix, tb: TransformMatrix) {
60 'worklet'
61 // In-place matrix multiplication.
62 const a00 = ta[0],
63 a01 = ta[1],
64 a02 = ta[2]
65 const a10 = ta[3],
66 a11 = ta[4],
67 a12 = ta[5]
68 const a20 = ta[6],
69 a21 = ta[7],
70 a22 = ta[8]
71 ta[0] = a00 * tb[0] + a01 * tb[3] + a02 * tb[6]
72 ta[1] = a00 * tb[1] + a01 * tb[4] + a02 * tb[7]
73 ta[2] = a00 * tb[2] + a01 * tb[5] + a02 * tb[8]
74 ta[3] = a10 * tb[0] + a11 * tb[3] + a12 * tb[6]
75 ta[4] = a10 * tb[1] + a11 * tb[4] + a12 * tb[7]
76 ta[5] = a10 * tb[2] + a11 * tb[5] + a12 * tb[8]
77 ta[6] = a20 * tb[0] + a21 * tb[3] + a22 * tb[6]
78 ta[7] = a20 * tb[1] + a21 * tb[4] + a22 * tb[7]
79 ta[8] = a20 * tb[2] + a21 * tb[5] + a22 * tb[8]
80}
81
82export function prependPan(t: TransformMatrix, translation: Position) {
83 'worklet'
84 prependTranslate(t, translation.x, translation.y)
85}
86
87export function prependPinch(
88 t: TransformMatrix,
89 scale: number,
90 origin: Position,
91 translation: Position,
92) {
93 'worklet'
94 prependTranslate(t, translation.x, translation.y)
95 prependTranslate(t, origin.x, origin.y)
96 prependScale(t, scale)
97 prependTranslate(t, -origin.x, -origin.y)
98}