python-lottie  0.6.11+deved4e6c7
A framework to work with lottie files and telegram animated stickers (tgs)
transform.py
Go to the documentation of this file.
1 import math
2 from ..nvector import NVector
3 
4 
5 def _sign(x):
6  if x < 0:
7  return -1
8  return 1
9 
10 
12  scalar = float
13 
14  def __init__(self):
15  """ Creates an Identity matrix """
16  self.to_identityto_identity()
17 
18  def clone(self):
19  m = TransformMatrix()
20  m._mat = list(self._mat_mat)
21  return m
22 
23  return self
24 
25  def __getitem__(self, key):
26  row, col = key
27  return self._mat_mat[row*4+col]
28 
29  def __setitem__(self, key, value):
30  row, col = key
31  self._mat_mat[row*4+col] = self.scalarscalar(value)
32 
33  @property
34  def a(self):
35  return self[0, 0]
36 
37  @a.setter
38  def a(self, v):
39  self[0, 0] = self.scalarscalar(v)
40 
41  @property
42  def b(self):
43  return self[0, 1]
44 
45  @b.setter
46  def b(self, v):
47  self[0, 1] = self.scalarscalar(v)
48 
49  @property
50  def c(self):
51  return self[1, 0]
52 
53  @c.setter
54  def c(self, v):
55  self[1, 0] = self.scalarscalar(v)
56 
57  @property
58  def d(self):
59  return self[1, 1]
60 
61  @d.setter
62  def d(self, v):
63  self[1, 1] = self.scalarscalar(v)
64 
65  @property
66  def tx(self):
67  return self[3, 0]
68 
69  @tx.setter
70  def tx(self, v):
71  self[3, 0] = self.scalarscalar(v)
72 
73  @property
74  def ty(self):
75  return self[3, 1]
76 
77  @ty.setter
78  def ty(self, v):
79  self[3, 1] = self.scalarscalar(v)
80 
81  def __str__(self):
82  return str(self._mat_mat)
83 
84  def scale(self, x, y=None):
85  if y is None:
86  y = x
87 
88  m = TransformMatrix()
89  m.a = x
90  m.d = y
91  self *= m
92  return self
93 
94  def translate(self, x, y=None):
95  if y is None:
96  x, y = x
97  m = TransformMatrix()
98  m.tx = x
99  m.ty = y
100  self *= m
101  return self
102 
103  def skew(self, x_rad, y_rad):
104  m = TransformMatrix()
105  m.c = math.tan(x_rad)
106  m.b = math.tan(y_rad)
107  self *= m
108  return self
109 
110  def skew_from_axis(self, skew, axis):
111  self.rotaterotate(axis)
112  m = TransformMatrix()
113  m.c = math.tan(skew)
114  self *= m
115  self.rotaterotate(-axis)
116  return self
117 
118  def row(self, i):
119  return NVector(self[i, 0], self[i, 1], self[i, 2], self[i, 3])
120 
121  def column(self, i):
122  return NVector(self[0, i], self[1, i], self[2, i], self[3, i])
123 
124  def to_identity(self):
125  self._mat_mat = [
126  1., 0., 0., 0.,
127  0., 1., 0., 0.,
128  0., 0., 1., 0.,
129  0., 0., 0., 1.,
130  ]
131 
132  def apply(self, vector):
133  vector3 = NVector(vector.x, vector.y, 0, 1)
134  return NVector(
135  self.columncolumn(0).dot(vector3),
136  self.columncolumn(1).dot(vector3),
137  )
138 
139  @classmethod
140  def rotation(cls, radians):
141  m = cls()
142  m.a = math.cos(radians)
143  m.b = -math.sin(radians)
144  m.c = math.sin(radians)
145  m.d = math.cos(radians)
146 
147  return m
148 
149  def __mul__(self, other):
150  m = TransformMatrix()
151  for row in range(4):
152  for col in range(4):
153  m[row, col] = self.rowrow(row).dot(other.column(col))
154  return m
155 
156  def __imul__(self, other):
157  m = self * other
158  self._mat_mat = m._mat
159  return self
160 
161  def rotate(self, radians):
162  self *= TransformMatrix.rotation(radians)
163  return self
164 
165  def extract_transform(self):
166  a = self.aaa
167  b = self.bbb
168  c = self.ccc
169  d = self.ddd
170  tx = self.txtxtx
171  ty = self.tytyty
172 
173  dest_trans = {
174  "translation": NVector(tx, ty),
175  "angle": 0,
176  "scale": NVector(1, 1),
177  "skew_axis": 0,
178  "skew_angle": 0,
179  }
180 
181  delta = a * d - b * c
182  if a != 0 or b != 0:
183  r = math.hypot(a, b)
184  dest_trans["angle"] = - _sign(b) * math.acos(a/r)
185  sx = r
186  sy = delta / r
187  dest_trans["skew_axis"] = 0
188  else:
189  r = math.hypot(c, d)
190  dest_trans["angle"] = math.pi / 2 + _sign(d) * math.acos(c / r)
191  sx = delta / r
192  sy = r
193  dest_trans["skew_axis"] = math.pi / 2
194 
195  dest_trans["scale"] = NVector(sx, sy)
196 
197  skew = math.atan2((a * c + b * d), r * r)
198  dest_trans["skew_angle"] = skew
199 
200  return dest_trans
201 
202  def to_css_2d(self):
203  return "matrix(%s, %s, %s, %s, %s, %s)" % (
204  self.aaa, self.bbb, self.ccc, self.ddd, self.txtxtx, self.tytyty
205  )
def __setitem__(self, key, value)
Definition: transform.py:29
def skew_from_axis(self, skew, axis)
Definition: transform.py:110
def translate(self, x, y=None)
Definition: transform.py:94
def skew(self, x_rad, y_rad)
Definition: transform.py:103