comparison pyink/tween.py @ 1339:20cf3e2a0a9d

Fix weir behavior for tweening for opacity. - The opacity is not work for more than one object been tweening. - cause by the buggy style parser. - It is fixed by a better style parser.
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 06 Feb 2011 22:57:33 +0800
parents 0e27e3aa21ed
children a48df5d53ddc
comparison
equal deleted inserted replaced
1338:d0e6f350b3fd 1339:20cf3e2a0a9d
1 # -*- indent-tabs-mode: t; tab-width: 8; python-indent: 4; -*- 1 # -*- indent-tabs-mode: t; tab-width: 8; python-indent: 4; -*-
2 # vim: sw=4:ts=8:sts=4 2 # vim: sw=4:ts=8:sts=4
3 import traceback 3 import traceback
4 import math 4 import math
5 5
6 def parse_opacity(obj): 6
7 style = obj.getAttribute("style") 7 def parse_style(style):
8 arr = style.split(';') 8 attrs = {}
9 for a in arr: 9
10 f = a.split(':') 10 style_parts = style.split(';')
11 if f[0] == 'opacity': 11 for part in style_parts:
12 return float(f[1]) 12 part = part.strip()
13 return 1 13 if not part:
14 14 continue
15 def change_opacity(obj, opacity): 15 nv_pair = part.split(':')
16 try: 16 if len(nv_pair) != 2:
17 style = obj.getAttribute("style") 17 raise ValueError, 'invalid format for style "%s"' % (style)
18 except: 18
19 obj.setAttribute("style","opacity:%g" % opacity) 19 name = nv_pair[0].strip()
20 return 20 value = nv_pair[1].strip()
21 arr = style.split(';') 21 attrs[name] = value
22 s='' 22 pass
23 for a in arr: 23
24 f = a.split(':') 24 return attrs
25 f[0] = f[0].replace(' ','') 25
26 if f[0] == 'opacity': 26 def gen_style(attrs):
27 if s != '': 27 parts = [name + ':' + value for name, value in attrs.items()]
28 s = s + ('; opacity:%g' % opacity) 28 style = ';'.join(parts)
29 else: 29 return style
30 s = 'opacity:%g' % opacity
31 elif f[0] != '':
32 if s == '':
33 s = a
34 else:
35 s = s +';'+ a
36 obj.setAttribute("style",s)
37
38 30
39 class TweenObject(object): 31 class TweenObject(object):
40 TWEEN_TYPE_NORMAL = 0 32 TWEEN_TYPE_NORMAL = 0
41 #TWEEN_TYPE_RELOCATE = 1 33 #TWEEN_TYPE_RELOCATE = 1
42 TWEEN_TYPE_SCALE = 1 34 TWEEN_TYPE_SCALE = 1
214 newobj = s.duplicate(self._doc) 206 newobj = s.duplicate(self._doc)
215 newobj.setAttribute("ref", s.getAttribute("id")) 207 newobj.setAttribute("ref", s.getAttribute("id"))
216 obj.appendChild(newobj) 208 obj.appendChild(newobj)
217 pass 209 pass
218 210
211 def _update_tween_style(self, s, d, p, newobj):
212 try:
213 s_style = s.getAttribute('style')
214 except:
215 s_attrs = {}
216 else:
217 s_attrs = parse_style(s_style)
218 pass
219
220 try:
221 d_style = d.getAttribute('style')
222 except:
223 d_attrs = {}
224 else:
225 d_attrs = parse_style(d_style)
226 pass
227
228 attrs = dict(s_attrs)
229
230 if s_attrs.has_key('opacity'):
231 start_opacity = float(s_attrs['opacity'])
232 else:
233 start_opacity = 1
234 pass
235
236 if d_attrs.has_key('opacity'):
237 end_opacity = float(d_attrs['opacity'])
238 else:
239 end_opacity = 1
240 pass
241
242 cur_opacity = start_opacity * (1 - p) + end_opacity * p
243 attrs['opacity'] = '%g' % (cur_opacity)
244
245 new_style = gen_style(attrs)
246 newobj.setAttribute('style', new_style)
247 pass
248
219 def updateTweenObjectScale_Group(self, s, d, p, newobj, top): 249 def updateTweenObjectScale_Group(self, s, d, p, newobj, top):
220 # Parse the translate or matrix 250 # Parse the translate or matrix
221 # 251 #
222 # D = B inv(A) 252 # D = B inv(A)
223 try: 253 try:
232 except: 262 except:
233 dx = 0 263 dx = 0
234 dy = 0 264 dy = 0
235 pass 265 pass
236 266
237 try: 267 self._update_tween_style(s, d, p, newobj)
238 start_opacity = parse_opacity(s) 268
239 except:
240 start_opacity = 1
241 pass
242
243 try:
244 end_opacity =parse_opacity( d)
245 except:
246 end_opacity = 1
247 pass
248
249
250 cur_opacity = start_opacity*(1-p)+end_opacity*p
251 change_opacity(newobj,cur_opacity)
252 sm = self.parseTransform(s) 269 sm = self.parseTransform(s)
253 ss = self.decomposition(sm) 270 ss = self.decomposition(sm)
254 dm = self.parseTransform(d) 271 dm = self.parseTransform(d)
255 dd = self.decomposition(dm) 272 dd = self.decomposition(dm)
256 sx = (ss[0]*(1-p)+dd[0]*p)/ss[0] 273 sx = (ss[0]*(1-p)+dd[0]*p)/ss[0]
282 except: 299 except:
283 dx = 0 300 dx = 0
284 dy = 0 301 dy = 0
285 pass 302 pass
286 303
287 try: 304 self._update_tween_style(s, d, p, newobj)
288 start_opacity = parse_opacity(s) 305
289 except:
290 start_opacity = 1
291 pass
292
293 try:
294 end_opacity =parse_opacity( d)
295 except:
296 end_opacity = 1
297 pass
298
299 cur_opacity = start_opacity*(1-p)+end_opacity*p
300 change_opacity(newobj,cur_opacity)
301 dm = self.parseTransform(d) 306 dm = self.parseTransform(d)
302 dd = self.decomposition(dm) 307 dd = self.decomposition(dm)
303 sx = 1-(1-dd[0])*p 308 sx = 1-(1-dd[0])*p
304 sy = 1-(1-dd[1])*p 309 sy = 1-(1-dd[1])*p
305 a = dd[2]*p 310 a = dd[2]*p
338 dh = float(d.getAttribute("height")) 343 dh = float(d.getAttribute("height"))
339 except: 344 except:
340 dh = 1 345 dh = 1
341 pass 346 pass
342 347
343 try: 348 self._update_tween_style(s, d, p, newobj)
344 start_opacity = parse_opacity(s) 349
345 except:
346 start_opacity = 1
347 pass
348
349 try:
350 end_opacity =parse_opacity( d)
351 if d.name() == "svg:use":
352 end_opacity = end_opacity * start_opacity
353 pass
354 pass
355 except:
356 if d.name() == "svg:use":
357 end_opacity = start_opacity
358 else:
359 end_opacity = 1
360 pass
361
362 cur_opacity = start_opacity*(1-p)+end_opacity*p
363 change_opacity(newobj,cur_opacity)
364
365 try: 350 try:
366 (ox,oy) = s.spitem.getCenter() 351 (ox,oy) = s.spitem.getCenter()
367 except: 352 except:
368 ox = 0 353 ox = 0
369 oy = 0 354 oy = 0
428 obj.appendChild(top) 413 obj.appendChild(top)
429 else: 414 else:
430 top = newobj 415 top = newobj
431 newobj = newobj.firstChild() 416 newobj = newobj.firstChild()
432 pass 417 pass
433 print s.name()
434 if s.name() == 'svg:g': 418 if s.name() == 'svg:g':
435 self.updateTweenObjectScale_Group(s,d,p,newobj,top) 419 self.updateTweenObjectScale_Group(s,d,p,newobj,top)
436 elif s.name() == 'svg:use': 420 elif s.name() == 'svg:use':
437 self.updateTweenObjectScale_Use(s,d,p,newobj,top) 421 self.updateTweenObjectScale_Use(s,d,p,newobj,top)
438 else: 422 else: