Mercurial > MadButterfly
diff pyink/MBScene.py @ 1123:aad659b6b625
Add motion animation editor.
author | wycc |
---|---|
date | Thu, 09 Dec 2010 07:48:08 +0800 |
parents | 214e1f628d63 |
children | 5b2394f67ad0 |
line wrap: on
line diff
--- a/pyink/MBScene.py Thu Dec 09 07:47:14 2010 +0800 +++ b/pyink/MBScene.py Thu Dec 09 07:48:08 2010 +0800 @@ -429,9 +429,35 @@ def setCurrentScene(self,nth): + """ + Update the scene group according to the curretn scene data. There are a couple of cases. + 1. If the type of the scene is normal, we display it when it contains the current + frame. Otherwise hide it. + 2. If the type of the scene is relocate or scale, we need to duplicate the scene group + and then modify its transform matrix according to the definition of the scene. Then, + hide the original scenr group and display the duplciate scene group. In addition, + we may need to delete the old duplicated scene group as well. + + For each layer, we will always use the duplicated scene group whose name as dup. + We will put the duplicated scene group inside it. We will create this group if it is not + available. + """ self.current = nth for layer in self._framelines: i=0 + + # Check the duplicated scene group and create it if it is not available + try: + if layer.duplicateGroup: + layer.duplicateGroup.parent().removeChild(layer.duplicateGroup) + layer.duplicateGroup = None + except: + traceback.print_exc() + pass + # Create a new group + layer.duplicateGroup = None + + while i < len(layer._keys): s = layer._keys[i] print s.ref.attribute("id"),s.idx,s.left_tween,s.right_tween @@ -442,15 +468,131 @@ s.ref.setAttribute("style","display:none",True) i = i + 1 continue - - if nth >= (s.idx+1) and nth <= (layer._keys[i+1].idx+1): + if nth == s.idx + 1: s.ref.setAttribute("style","",True) else: - s.ref.setAttribute("style","display:none",True) + if nth > (s.idx+1) and nth <= (layer._keys[i+1].idx+1): + if i+2 < len(layer._keys): + layer.duplicateGroup = self.desktop.doc().rdoc.createElement("svg:g") + layer.duplicateGroup.setAttribute("inkscape:label","dup",True) + s.ref.setAttribute("style","display:none",True) + s.ref.parent().appendChild(layer.duplicateGroup) + self.updateTweenContent(layer.duplicateGroup, layer.get_tween_type(s.idx),s, layer._keys[i+2], nth) + else: + s.ref.setAttribute("style","display:none",True) i = i + 2 pass pass pass + def updateTweenContent(self,obj, typ, source,dest,cur): + """ + Update the content of the duplicate scene group. We will use the (start,end) and cur to calculate the percentage of + the tween motion effect and then use it to update the transform matrix of the duplicated scene group. + """ + start = source.idx + end = dest.idx + print cur,start,end + percent = (cur-start)*1.0/(end-start) + i = 0 + s = source.ref.firstChild() + d = dest.ref.firstChild() + sources={} + dests={} + # Collect all objects + while d: + try: + label = d.attribute("inkscape:label") + except: + d = d.next() + continue + dests[label.value()] = d + d = d.next() + # Check if the object in the source exists in the destination + s = source.ref.firstChild() + d = dest.ref.firstChild() + while s: + print s,d + try: + label = s.attribute("inkscape:label") + # Use i8nkscape:label to identidy the equipvalent objects + if label: + if dests.hasattr(label.value()): + self.updateTweenObject(obj,typ,s,dests[label.value()],percent) + s = s.next() + continue + except: + pass + # Search obejcts in the destination + while d: + try: + d.attribute("inkscape:label") + d = d.next() + continue + except: + pass + if s.name() == d.name(): + self.updateTweenObject(obj,typ,s,d,percent) + d = d.next() + break + d = d.next() + s = s.next() + def parseTransform(self,obj): + """ + Return the transform matrix of an object + """ + try: + t = obj.attribute("transform") + print t + if t[0:9] == 'translate': + print "translate" + fields = t[10:].split(',') + x = float(fields[0]) + fields = fields[1].split(')') + y = float(fields[0]) + return [1,0,x,0,1,y] + elif t[0:6] == 'matrix': + print "matrix" + fields=t[7:].split(')') + fields = fields[0].split(',') + return [float(fields[0]),float(fields[1]),float(fields[2]),float(fields[3]),float(fields[4]),float(fields[5])] + except: + traceback.print_exc() + return [1,0,0,0,1,0] + + + def updateTweenObject(self,obj,typ,s,d,p): + """ + Generate tweened object in the @obj by using s and d in the @p percent + """ + print 'compare',s,d + if typ == 'relocate': + print "percent",p + newobj = s.duplicate(self.desktop.doc().rdoc) + top = self.desktop.doc().rdoc.createElement("svg:g") + top.appendChild(newobj) + obj.appendChild(top) + print s.name() + if s.name() == 'svg:g': + # Parse the translate or matrix + sm = self.parseTransform(s) + dm = self.parseTransform(d) + print "g", (dm[2]-sm[2])*p,(dm[5]-sm[5])*p + top.setAttribute("transform","translate(%g,%g)" % ((dm[2]-sm[2])*p,(dm[5]-sm[5])*p),True) + else: + try: + sx = float(s.attribute("x")) + sy = float(s.attribute("y")) + dx = float(d.attribute("x")) + dy = float(d.attribute("y")) + tx = (dx-sx)*p + ty = (dy-sy)*p + print tx,ty + top.setAttribute("transform","translate(%g,%g)" % (tx,ty),True) + except: + traceback.print_exc() + pass + pass + pass def enterGroup(self,obj): for l in self.layers: for s in l.node.childList():