Mercurial > MadButterfly
changeset 1123:aad659b6b625
Add motion animation editor.
author | wycc |
---|---|
date | Thu, 09 Dec 2010 07:48:08 +0800 |
parents | 3d438daea48c |
children | b5ff72dbc910 |
files | pyink/MBScene.py pyink/mbtest.svg |
diffstat | 2 files changed, 296 insertions(+), 47 deletions(-) [+] |
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():
--- a/pyink/mbtest.svg Thu Dec 09 07:47:14 2010 +0800 +++ b/pyink/mbtest.svg Thu Dec 09 07:48:08 2010 +0800 @@ -29,7 +29,7 @@ inkscape:zoom="1.6029106" inkscape:cx="238.58561" inkscape:cy="290.40921" - inkscape:current-layer="g3189" + inkscape:current-layer="layer2" inkscape:document-units="px" showgrid="false" inkscape:window-width="1400" @@ -180,6 +180,45 @@ y1="28.009714" x2="104.68548" y2="28.009714" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3211-0-5-5" + id="linearGradient3316-4-8-2" + gradientUnits="userSpaceOnUse" + x1="31.940987" + y1="28.009714" + x2="104.68548" + y2="28.009714" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3211-0-5-5"> + <stop + style="stop-color:#001dff;stop-opacity:1;" + offset="0" + id="stop3213-3-8-8" /> + <stop + style="stop-color:#001dff;stop-opacity:0;" + offset="1" + id="stop3215-9-4-6" /> + </linearGradient> + <filter + color-interpolation-filters="sRGB" + inkscape:collect="always" + id="filter3295-1-3-2"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.67110109" + id="feGaussianBlur3297-9-7-8" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3211-0-5-5" + id="linearGradient3909" + gradientUnits="userSpaceOnUse" + x1="31.940987" + y1="28.009714" + x2="104.68548" + y2="28.009714" /> </defs> <metadata id="metadata2388"> @@ -211,9 +250,13 @@ type="normal" /> <ns0:scene start="1" - ref="g3189" + ref="g3303" end="15" type="relocate" /> + <ns0:scene + start="16" + ref="Backgrounds4326" + type="normal" /> </ns0:scenes> </metadata> <g @@ -222,59 +265,58 @@ inkscape:label="Background" style="display:inline"> <g - id="g3189" - style=""> - <rect - style="fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-opacity:1;display:inline" - id="rect2437" - width="641.95721" - height="481.62387" - x="0.93578684" - y="-10.98185" /> + style="display:none" + transform="translate(-15.128732,2.0275737)" + id="g3303" + inkscape:label="action1"> + <g + id="g3189"> + <rect + style="fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-opacity:1;display:inline" + id="rect2437" + width="641.95721" + height="481.62387" + x="0.93578684" + y="-10.98185" /> + <rect + style="fill:#ffcc1d;fill-opacity:1;stroke:none" + id="rect3698" + width="624.48901" + height="46.789886" + x="6.8625164" + y="5.8625031" + rx="10" + ry="10" /> + </g> <rect - style="fill:#ffcc1d;fill-opacity:1;stroke:none" - id="rect3698" - width="624.48901" - height="46.789886" - x="6.8625164" - y="5.8625031" - rx="10" - ry="10" /> - <g - style="display:inline" - transform="translate(-15.128732,2.0275737)" - id="g3303" - inkscape:label="action1"> - <rect - y="15.22048" - x="32.440987" - height="25.57847" - width="71.744492" - id="rect2439" - style="fill:url(#linearGradient3237);fill-opacity:1;stroke:none;filter:url(#filter3295-1-3)" /> - <text - id="text3299" + y="15.22048" + x="32.440987" + height="25.57847" + width="71.744492" + id="rect2439" + style="fill:url(#linearGradient3237);fill-opacity:1;stroke:none;filter:url(#filter3295-1-3)" /> + <text + id="text3299" + y="33.312569" + x="39.927368" + style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + xml:space="preserve"><tspan + style="font-size:16px" y="33.312569" x="39.927368" - style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" - xml:space="preserve"><tspan - style="font-size:16px" - y="33.312569" - x="39.927368" - id="tspan3301" - sodipodi:role="line">Action</tspan></text> - </g> + id="tspan3301" + sodipodi:role="line">Action</tspan></text> <g style="display:inline" id="g3308" - transform="translate(76.891374,2.9633707)"> + transform="translate(75.331712,-0.46789912)"> <rect y="15.22048" x="32.440987" height="25.57847" width="71.744492" id="rect3310" - style="fill:url(#linearGradient3316-4-8);fill-opacity:1;stroke:none;filter:url(#filter3295-1-3)" /> + style="fill:url(#linearGradient3316-4-8-2);fill-opacity:1;stroke:none;filter:url(#filter3295-1-3-2)" /> <text id="text3312" y="33.312569" @@ -289,7 +331,72 @@ </g> </g> <g - id="s4393" /> + inkscape:label="action1" + id="Backgrounds4326" + transform="translate(-15.128732,2.0275737)" + style="" + inkscape:groupmode="layer"> + <g + id="g3889"> + <rect + y="-10.98185" + x="0.93578684" + height="481.62387" + width="641.95721" + id="rect3891" + style="fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-opacity:1;display:inline" /> + <rect + ry="10" + rx="10" + y="5.8625031" + x="6.8625164" + height="46.789886" + width="624.48901" + id="rect3893" + style="fill:#ffcc1d;fill-opacity:1;stroke:none" /> + </g> + <rect + style="fill:url(#linearGradient3237);fill-opacity:1;stroke:none;filter:url(#filter3295-1-3)" + id="rect3895" + width="71.744492" + height="25.57847" + x="32.440987" + y="15.22048" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + x="39.927368" + y="33.312569" + id="text3897"><tspan + sodipodi:role="line" + id="tspan3899" + x="39.927368" + y="33.312569" + style="font-size:16px">Action</tspan></text> + <g + transform="translate(170.78307,-0.46789912)" + id="g3901" + style="display:inline"> + <rect + style="fill:url(#linearGradient3909);fill-opacity:1;stroke:none;filter:url(#filter3295-1-3-2)" + id="rect3903" + width="71.744492" + height="25.57847" + x="32.440987" + y="15.22048" /> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + x="39.927368" + y="33.312569" + id="text3905"><tspan + sodipodi:role="line" + id="tspan3907" + x="39.927368" + y="33.312569" + style="font-size:16px">Select</tspan></text> + </g> + </g> </g> <g inkscape:groupmode="layer"