チェンジセット 1494

差分発生行の前後
無視リスト:
コミット日時:
2008/10/04 09:50:39 (3 年前)
コミッタ:
gyuque
ログメッセージ:

v0.4: correct draw order, disposing unused shape, radial gradient, alpha support

ファイル:

凡例:

変更無し
追加
削除
更新
コピー
移動
  • ruby/jsplash/trunk/client2/demo_20081001.xml

    r1479 r1494  
    1414                <script type="text/javascript" src="./jsplash/objects.js"></script> 
    1515                <script type="text/javascript" src="./jsplash/shaperenderer.js"></script> 
     16                <script type="text/javascript" src="./jsplash/shapedisposer.js"></script> 
    1617                <script type="text/javascript" src="./jsplash/executor.js"></script> 
    1718                <script type="text/javascript" src="./jsplash/swfglobal.js"></script> 
  • ruby/jsplash/trunk/client2/index.xml

    r1489 r1494  
    1414                <script type="text/javascript" src="./jsplash/objects.js"></script> 
    1515                <script type="text/javascript" src="./jsplash/shaperenderer.js"></script> 
     16                <script type="text/javascript" src="./jsplash/shapedisposer.js"></script> 
    1617                <script type="text/javascript" src="./jsplash/executor.js"></script> 
    1718                <script type="text/javascript" src="./jsplash/swfglobal.js"></script> 
     
    5354                <div id="progbar"><div>  </div></div> 
    5455                <p id="statusout"> </p> 
    55                 <p id="sout">starting <em>JSplash Player 0.2.4</em>...<br />-------------------------------------<br /></p> 
     56                <p id="sout">starting <em>JSplash Player 0.4.0</em>...<br />-------------------------------------<br /></p> 
    5657                <svg id="svgrt" xmlns="http://www.w3.org/2000/svg" style="width: 100px; height: 100px;"> 
    5758                </svg> 
  • ruby/jsplash/trunk/client2/jsplash/executor.js

    r1478 r1494  
    1717         
    1818        registerObject: function(obj) { 
     19                if (this.additionals) 
     20                        this.additionals.push(obj); 
     21         
    1922                if (obj._execid_) return; 
    2023                 
    2124                obj._execid_ = JSplash.Executor._nextid++; 
    2225                this.targets[obj._execid_] = obj; 
    23                  
    24                 if (this.additionals) 
    25                         this.additionals.push(obj); 
    2626        }, 
    2727         
     
    117117                                var icounts = []; 
    118118                                var topsvg = JSplash.gPlayer.svg.childNodes; 
    119                                 for (var i = 0;i < topsvg.length;i++) { 
    120                                         icounts.push( topsvg[i].childNodes.length ); 
    121                                 } 
    122                                 JSplash.$putstat("view objects: " + topsvg.length + " / " + icounts.join(' ')); 
     119//                              for (var i = 0;i < topsvg.length;i++) { 
     120//                                      icounts.push( topsvg[i].childNodes.length ); 
     121//                              } 
     122//                              JSplash.$putstat("view objects: " + topsvg.length + " / " + icounts.join(' ')); 
     123 
     124                                JSplash.$putstat("top level views: " + topsvg.length + "   total shapes: " + JSplash.gPlayer.disposer.stats); 
     125 
    123126                } 
    124127//////////////////////////////////// debug 
     
    126129                t = Math.floor(1000 / this.frameRate); 
    127130                 
    128 if(this.frameCount++ < 9999) 
     131                 
     132                this.invokeDisposer(); 
     133                 
     134if(this.frameCount++ < 99999) 
    129135                window.setTimeout(this.tick.bind(this), t); 
    130136        }, 
     
    138144                } 
    139145        }, 
     146         
     147        invokeDisposer: function() { 
     148                var stg = JSplash.gPlayer.stage; 
     149 
     150                var fi = stg.context.frameC - 100; 
     151                if (fi < 1) { 
     152                        if (stg.context.reachedFrame > 500) 
     153                                fi += stg.context.reachedFrame - 1; 
     154                        else 
     155                                return; 
     156                } 
     157                 
     158                JSplash.gPlayer.disposer.sweep(fi); 
     159 
     160                fi = stg.context.frameC - 1000; 
     161                if (fi < 1) { 
     162                        if (stg.context.reachedFrame > 2500) 
     163                                fi += stg.context.reachedFrame - 1; 
     164                        else 
     165                                return; 
     166                } 
     167                 
     168                JSplash.gPlayer.disposer.sweep(fi); 
     169        } 
    140170} 
  • ruby/jsplash/trunk/client2/jsplash/objects.js

    r1489 r1494  
    11JSplash.ObjectInstance = Class.create(); 
     2JSplash.ObjectInstance.next_id = 1; 
    23JSplash.EXECUTED_OK        = 1; 
    34JSplash.EXECUTED_SHOWFRAME = 2; 
     
    3637                this.klass     = null; 
    3738                this.proxy     = null; 
     39                this.appended = false; 
     40                this.shape_disposed = false; 
    3841 
    3942                this.framePersists = {}; 
     
    4245                this.nameMap     = {}; 
    4346                this.frameActionFuncs = {}; 
     47                this.topDepths = [0]; 
     48                 
     49                this.instance_uid = JSplash.ObjectInstance.next_id++; 
    4450         
    4551                if (g) 
     
    7783         
    7884        dispose: function() { 
    79                 if (this.executor) 
    80                         this.executor.removeObject(this); 
     85 
     86                if (this.shape_disposed) 
     87                        return false; 
     88                         
     89                if (this.g && this.g.firstChild && this.g.firstChild.tagName == "path") { 
     90                        this.sleeping = true; 
     91                        this.shape_disposed = true; 
     92                        if (this.appended) 
     93                                this.parent.removeForce(this); 
     94                        delete this.g; 
     95                        return true; 
     96                } 
     97 
     98                return false; 
    8199        }, 
    82100         
    83101        sleep: function() { 
    84                 this.g.style.display = "none"; 
    85                 this.sleeping = true; 
     102                if (!this.sleeping) 
     103                { 
     104                        this.g.style.display = "none"; 
     105                        this.sleeping = true; 
     106                } 
    86107                this.destroyProxy(); 
    87108        }, 
    88109         
    89         resume: function() { 
    90                 this.g.style.display = ""; 
     110        resume: function(depth) { 
     111         
     112 
     113                if (this.shape_disposed) /* Though this object is not sleeping, can be disposed when parent is sleeping */ 
     114                { 
     115                 
     116                        this.g = JSplash.$svg('g'); 
     117                        this.render(); 
     118                        this.shape_disposed = false; 
     119                                 
     120                        JSplash.gPlayer.disposer.register(this); 
     121                } 
     122                this.parent.appendViewAtDepth(this, depth); 
    91123                if (this.sleeping) { 
     124                        this.g.style.display = ""; 
     125         
    92126                        this.sleeping = false; 
    93127                        this.play(); 
    94128                        this.rewind(); 
    95                 } 
    96         }, 
    97          
    98         placeObject: function(depth, oid, iname, clip_depth) { 
     129                         
     130                } 
     131 
     132                if (this.isExecutable()) // This is needed to execute descendant tags! 
     133                        this.executor.registerObject(this);              
     134                }, 
     135         
     136        appendViewAtDepth: function(obj, depth) { 
     137 
     138                if (obj.appended) 
     139                        return; 
     140                         
     141                if (this.topDepths[this.topDepths.length-1] /* last */ < depth) 
     142                { 
     143                        this.topDepths.push(depth); 
     144                        this.g.appendChild(obj.g); 
     145                        obj.appended = true; 
     146                } 
     147                else { 
     148                        var old = this.depthMap[depth]; 
     149 
     150                        if (old && old.appended) { 
     151                                this.g.insertBefore(obj.g, old.g); 
     152                                this.g.removeChild(old.g); 
     153 
     154                                old.appended = false; 
     155                                obj.appended = true; 
     156                        } 
     157                        else { 
     158                                var nxtd = 65536; 
     159                                for (var d in this.depthMap) 
     160                                { 
     161                                        d -= 0; 
     162                                        if (d < nxtd && d > depth && this.depthMap[d].appended) 
     163                                                nxtd = d; 
     164                                } 
     165                                 
     166                                if (nxtd == 65536) { 
     167                                        console.warn("unknown case!"); 
     168                                        this.g.appendChild(obj.g); 
     169                                } 
     170                                else 
     171                                        this.g.insertBefore(obj.g, this.depthMap[nxtd].g); 
     172                                obj.appended = true; 
     173                        } 
     174                } 
     175                 
     176        }, 
     177         
     178        placeObject: function(depth, oid, iname, clip_depth, inherit_transform) { 
    99179                if (clip_depth) 
    100180                        this.clipMap[depth] = clip_depth; 
    101          
     181 
    102182                if (this.context.reachedFrame > this.context.frameC) { 
     183                 
    103184                        var po = this.framePersists[this.context.frameC+1].pickDepth(depth) || null; 
    104                          
    105185                        if (this.depthMap[depth] != po) 
     186                        { 
    106187                                this.removeObject(depth); 
    107                          
     188                        } 
     189 
    108190                        if (po) { 
     191                                po.resume(depth); 
     192                                if (inherit_transform && this.depthMap[depth]) 
     193                                        po.copyTransformFrom(this.depthMap[depth]); 
     194                                 
    109195                                this.depthMap[depth] = po; 
    110                                 po.resume(); 
    111196                        } 
    112197                 
    113198                        return po; 
    114199                } 
    115          
     200                
    116201                var inst = null; 
    117202                if (oid) { 
    118                         this.removeObject(depth); 
    119                  
     203                        var replaced = this.removeObject(depth, true); 
     204 
    120205                        var klass = JSplash.gPlayer.stage.fetchObject(oid); 
    121206                        if (!klass) 
    122207                                return null; 
    123208                        inst = klass.createInstance(this); 
     209                        if (klass.isShapeObject) 
     210                                JSplash.gPlayer.disposer.register(inst); 
    124211 
    125212                        if (klass.renderer) 
    126213                                inst.renderer = klass.renderer; 
     214 
     215                        /* when replace previous frame */ 
     216                        var g_before = null; 
     217                        if (inherit_transform && inst && replaced) { 
     218                                inst.copyTransformFrom(replaced); 
     219                                g_before = replaced.g; /* to correct draw order*/ 
     220                        } 
    127221                         
     222                        inst.render(); 
     223 
     224                        if (!g_before) 
     225                        { 
     226//try    { 
     227                                this.appendViewAtDepth(inst, depth); 
     228//} catch (e) { 
     229//this.trace(); 
     230//console.log(g_before+" "+depth+" "+oid+" "+replaced.appended); 
     231//throw "DOM ERR "+e; 
     232//} 
     233                        } 
     234                        else 
     235                        { 
     236//try    { 
     237try{ 
     238                                this.g.insertBefore(inst.g, g_before); 
     239}catch(e){return null;} 
     240//} catch (e) { 
     241//this.trace(); 
     242//console.log(g_before+" "+depth+" "+oid+" "+replaced.appended); 
     243//throw "DOM ERR"; 
     244//} 
     245                                inst.appended = true; 
     246                        } 
    128247                        this.depthMap[depth] = inst; 
    129                         inst.render(); 
    130                         this.g.appendChild(inst.g); 
    131248                         
    132249                        if (iname) { 
     
    137254                                inst.registerExecutor(JSplash.gPlayer.executor); 
    138255                        } 
     256                         
     257                        if (replaced && replaced.appended) 
     258                        { 
     259                                this.g.removeChild(replaced.g); 
     260                                replaced.appended = false; 
     261                        } 
    139262                } 
    140263                else { 
     
    148271                return inst; 
    149272        }, 
    150  
    151         removeObject: function(depth) { 
     273         
     274        removeIfTop: function(obj, depth) { 
     275                if (depth == this.topDepths[this.topDepths.length-1]) 
     276                { 
     277                        this.g.removeChild(obj.g); 
     278                        obj.appended = false; 
     279                        this.topDepths.pop(); 
     280                } 
     281        }, 
     282         
     283        removeForce: function(o) { 
     284                var d; 
     285                 
     286                this.g.removeChild(o.g); 
     287                o.appended = false; 
     288                 
     289                for (d in this.depthMap) 
     290                { 
     291                        d -= 0; 
     292                        if (this.depthMap[d] == o) { 
     293                                if (d == this.topDepths[this.topDepths.length-1]) 
     294                                        this.topDepths.pop(); 
     295 
     296                                delete this.depthMap[d]; 
     297                                return; 
     298                        } 
     299                } 
     300        }, 
     301         
     302 
     303        removeObject: function(depth, to_replace) { 
    152304                var o = this.pickPlacedObjectAt(depth); 
     305 
    153306                if (o) 
    154307                { 
     308                 
    155309                        delete this.clipMap[depth]; 
    156                         delete this.depthMap[depth]; 
     310                        // delete this.depthMap[depth]; 
    157311                        o.sleep(); 
     312try {                    
     313                        if (!to_replace) 
     314                                this.removeIfTop(o, depth); 
     315}catch(e) { 
     316console.log(this+" "+o.g + "  "+arguments.callee.caller); 
     317throw "DOM ERR"; 
     318} 
    158319//                      console.log( this + " removed at depth " +depth ); 
    159320                } 
     321                 
     322                return o; 
    160323        }, 
    161324                 
     
    176339                if (!skip_visual_change)         
    177340                        this.hideClippers(); 
     341        }, 
     342         
     343        setAlpha: function(a) { 
     344                this.g.style.opacity = a; 
    178345        }, 
    179346         
     
    193360        }, 
    194361         
    195         rewind: function() { 
     362        rewind: function(deep) { 
     363                if (this.context.frameC > 1) { 
     364                        for (var d in this.depthMap) { 
     365                                this.removeObject(d); 
     366                                if (deep && this.depthMap[d]) 
     367                                { 
     368                                        this.depthMap[d].rewind(true); 
     369                                } 
     370                        } 
     371                } 
     372         
    196373                this.context.frameC = 0; 
    197374                this.context.tagC   = 0; 
     
    242419                for (objname in this.nameMap) { 
    243420                        vlist.push(objname); 
    244                         this.getProxy().__locals__[objname] = this.nameMap[objname].getProxy(); 
    245                        this.getProxy().__setChidrenRefs__(); 
    246                 } 
     421                        P.__locals__[objname] = this.nameMap[objname].getProxy(); 
     422                } 
     423                P.__setChidrenRefs__(); 
    247424 
    248425                if (local_vlist) { 
     
    312489        toString: function() { 
    313490                return "Inst@"+this.klass+" belongs to " +this.parent; 
     491        }, 
     492         
     493        copyTransformFrom: function(src) { 
     494                this.pxTransform.mx = src.pxTransform.mx; 
     495                this.pxTransform.my = src.pxTransform.my; 
     496                this.pxTransform.sx = src.pxTransform.sx; 
     497                this.pxTransform.sy = src.pxTransform.sy; 
     498                this.pxTransform.kx = src.pxTransform.kx; 
     499                this.pxTransform.ky = src.pxTransform.ky; 
     500                 
     501                this.updateTransform(); 
     502                this.updateProxy(); 
    314503        }, 
    315504         
     
    443632                        ch = dmap[depth]; 
    444633                        if (!ch.sleeping) 
     634                        { 
    445635                                this.depthMap[depth] = ch; 
     636                        } 
    446637                } 
    447638        }, 
  • ruby/jsplash/trunk/client2/jsplash/player.js

    r1490 r1494  
    11var JSplash = {swfdata: null, gPlayer: null}; 
    22if (!window.console) 
    3         window.console = {log:function(){}}; 
     3        window.console = {log:function(){}, warn:function(){}}; 
    44 
    55 
     
    2121                svg.style.height = swf.pxHeight + "px"; 
    2222                this.stage = new JSplash.ObjectInstance.createStageObject(swf.taglist, svg, swf.label_map); 
     23                this.disposer = new JSplash.ShapeDisposer(this.stage); 
    2324                 
    2425                this.stage.klass = new JSplash.TagClass(null); 
  • ruby/jsplash/trunk/client2/jsplash/shaperenderer.js

    r1489 r1494  
    5050                } 
    5151                 
    52                 var gdef = JSplash.$svg("linearGradient", attrs); 
     52                if (filldata.grad!=1) 
     53                { 
     54                        attrs.r  = 819; 
     55                } 
     56                 
     57                var gdef = JSplash.$svg((filldata.grad==1) ? "linearGradient" : "radialGradient", attrs); 
    5358                JSplash.defsElement.appendChild(gdef); 
    5459                 
     
    5661                var len = filldata.s.length; 
    5762                for (var i = 0;i < len;i++) { 
    58                         var stp = JSplash.$svg("stop", {'stop-color': ('#'+filldata.c[i]), offset: (filldata.s[i] / 255)}); 
     63                        var attr = {'stop-color': ('#'+filldata.c[i]), offset: (filldata.s[i] / 255)}; 
     64                        if (filldata.a) { 
     65                                attr["stop-opacity"] = filldata.a[i]; 
     66                        } 
     67                        var stp = JSplash.$svg("stop", attr); 
    5968                        gdef.appendChild(stp); 
    6069                } 
     
    357366                 
    358367                commands.push('Z'); 
    359                  
    360                 g.appendChild( JSplash.$svg('path', {d: commands.join(' '), fill: style_str}) ); 
     368 
     369                attrs = {d: commands.join(' '), fill: style_str}; 
     370                if (style.a) { 
     371                        attrs.opacity = style.a; 
     372                } 
     373                g.appendChild( JSplash.$svg('path', attrs) ); 
    361374        }, 
    362375 
     
    394407                var edges = this.edgeList; 
    395408                var len = edges.length; 
    396                 var commands = []
     409                var commands = [], attrs
    397410                 
    398411                var paths = []; 
    399412                var curWidth = 0; 
    400413                var curStyle = null; 
     414                var curAlpha = undefined; 
    401415                 
    402416                var oneshot = 0; 
     
    415429                                        //commands.push('Z'); 
    416430                                        if (commands.length > 1) 
    417                                                 paths.push(JSplash.$svg('path', {d: commands.join(' '), fill: 'none', stroke: curStyle, 'stroke-width': curWidth})); 
     431                                        { 
     432                                                attrs = {d: commands.join(' '), fill: 'none', stroke: curStyle, 'stroke-width': curWidth}; 
     433                                                if (curAlpha != undefined) attrs['stroke-opacity'] = curAlpha; 
     434                                         
     435                                                paths.push(JSplash.$svg('path', attrs)); 
     436                                        } 
    418437                                } 
    419438 
     
    425444                                        curWidth = JSplash.$twips( this.edgeStyles[ E.lineStyle-1 ].w ); 
    426445                                        curStyle = '#' + this.edgeStyles[ E.lineStyle-1 ].rgb; 
     446                                        curAlpha =       this.edgeStyles[ E.lineStyle-1 ].a; 
    427447                                } 
    428448                                 
     
    445465 
    446466                if (commands.length > 1) 
    447                         paths.push(JSplash.$svg('path', {d: commands.join(' '), fill: 'none', stroke: curStyle, 'stroke-width': curWidth})); 
     467                { 
     468                        attrs = {d: commands.join(' '), fill: 'none', stroke: curStyle, 'stroke-width': curWidth}; 
     469                        if (curAlpha != undefined) attrs['stroke-opacity'] = curAlpha; 
     470 
     471                        paths.push(JSplash.$svg('path', attrs)); 
     472                } 
    448473                for (;paths.length;) 
    449474                        g.appendChild(paths.shift()); 
  • ruby/jsplash/trunk/client2/jsplash/tags.js

    r1478 r1494  
    1111 
    1212                tPlaceObject2: function(data, owner) { 
    13                         var inst = owner.placeObject(data.d, data.id, data.name, data.cl); 
     13                        var inst = owner.placeObject(data.d, data.id, data.name, data.cl, data.r); 
    1414                        if (!inst) { 
    15                                 console.log("WARNING: unregistered object id="+data.d); 
     15                                console.warn("WARNING: unregistered object id="+data.d); 
    1616                                return; 
    1717                        } 
    18                         if (data.mov || data.scl) { 
     18                        if (data.mov || data.scl || data.skw) { 
    1919                                var tx = 0, ty = 0; 
    2020                                var sx = 1, sy = 1; 
     
    3535                                        ky = data.skw[1]; 
    3636                                } 
    37  
    38                                 inst.g.style.zIndex = 65536-data.d; 
     37try { 
    3938                                inst.setTransform(tx, ty, sx, sy, kx, ky); 
     39}catch(e) { 
     40        throw inst; 
     41} 
     42                        } 
     43                         
     44                        if (data.cfct || data.cofs) { 
     45                                /* Google Chrome does not support feColorMatrix now. */ 
     46                                 
     47                                // ...but alpha transform is available with opacity style. 
     48                                var a = data.cfct ? data.cfct[3] : 1  
     49                                a += data.cofs ? data.cofs[3] : 0; 
     50                                 
     51                                if (a <= 0.99) 
     52                                        inst.setAlpha(a); 
    4053                        } 
    4154                }, 
     
    5669                        if (owner.context.frameC == 1) // stop when single frame MC ends 
    5770                                owner.stop(); 
    58                         owner.rewind(); 
     71                        owner.rewind(true); 
    5972//                      console.log("END"); 
    6073                }, 
     
    87100                                        this.renderer = new JSplash.ShapeRenderer(data); 
    88101                                        this.renderer.buildEdgeIndex(); 
     102                                        this.isShapeObject = true; 
    89103                                } 
    90104                                else if (data.tag == JSplash.tDefineSprite) { 
  • ruby/jsplash/trunk/jextract.rb

    r1490 r1494  
    2828        stops = [] 
    2929        rgbs = [] 
     30        alphas = [] 
     31        has_alpha = false 
    3032 
    3133        glist.each {|gi| 
    3234                stp = gi.attributes['position'] 
    3335                stops << stp 
    34                 rgbs  << "'#{make_rgb(gi.elements['./color/Color'].attributes)}'" 
     36                clra = gi.elements['./color/Color'].attributes 
     37                rgbs  << "'#{make_rgb(clra)}'" 
     38 
     39                has_alpha = true if clra['alpha'] 
     40                alphas << (clra['alpha'] ? (clra['alpha'].to_f/255.0) : 1) 
    3541        } 
    3642 
     
    4753        end 
    4854 
    49         "{grad:#{tp+1},s:[#{stops.join(',')}],c:[#{rgbs.join(',')}]#{mov}#{scl}#{skw}}" 
     55        alphas = ",a:[#{alphas.join(',')}]" 
     56        "{grad:#{tp+1},s:[#{stops.join(',')}],c:[#{rgbs.join(',')}]#{ (has_alpha ? alphas : nil) }#{mov}#{scl}#{skw}}" 
    5057end 
    5158 
     
    5562                case ch.name 
    5663                when 'Solid' 
    57                         styles << "{rgb:'#{make_rgb(ch.elements['./color/Color'].attributes)}'}" 
     64                        clra = ch.elements['./color/Color'].attributes 
     65 
     66                        alpha = nil 
     67                        alpha = ",a:#{ clra['alpha'].to_f/255 }" if clra['alpha'] 
     68                        styles << "{rgb:'#{make_rgb(clra)}'#{alpha}}" 
    5869                when 'LinearGradient' 
    5970                        styles << read_gradient(ch, 0) 
     71                when 'RadialGradient' 
     72                        styles << read_gradient(ch, 1) 
    6073                end 
    6174        } 
     
    7184                case ch.name 
    7285                when 'LineStyle' 
    73                         styles << "{w:#{a['width']},rgb:'#{make_rgb(ch.elements['./color/Color'].attributes)}'}" 
     86                        clra = ch.elements['./color/Color'].attributes 
     87                        alpha = nil 
     88                        alpha = ",a:#{ clra['alpha'].to_f/255 }" if clra['alpha'] 
     89 
     90                        styles << "{w:#{a['width']},rgb:'#{make_rgb(clra)}'#{alpha}}" 
    7491                end 
    7592        } 
     
    158175                trans = tg.elements['./transform/Transform'].attributes if tg.elements['./transform'] 
    159176 
     177                ctrans = nil 
     178                ctrans = tg.elements['./colorTransform/ColorTransform2'].attributes if tg.elements['./colorTransform/ColorTransform2'] 
     179 
    160180                rep = nil 
    161181                rep = ",r:true" if tg.attributes['replace'].to_i == 1 
     
    167187                cl = ",cl:#{tg.attributes['clipDepth']}" if tg.attributes['clipDepth'] 
    168188 
     189                mov = nil 
     190                scl = nil 
     191                skw = nil 
    169192                if trans 
    170193                        a = trans 
    171                         mov = nil 
    172                         scl = nil 
    173                         skw = nil 
    174194 
    175195                        mov = ",mov:[#{a['transX']},#{a['transY']}]" if a['transX'] 
     
    178198                end 
    179199 
     200                cfct = nil 
     201                cofs = nil 
     202                if ctrans 
     203                        a = ctrans 
     204 
     205                        if a['factorRed'] 
     206                                cfct = ",cfct:[#{a['factorRed'].to_f/255},#{a['factorGreen'].to_f/255},#{a['factorBlue'].to_f/255},#{a['factorAlpha'].to_f/255}]" 
     207                        end 
     208 
     209                        if a['offsetRed'] 
     210                                cofs = ",cofs:[#{a['offsetRed'].to_f/255},#{a['offsetGreen'].to_f/255},#{a['offsetBlue'].to_f/255},#{a['offsetAlpha'].to_f/255}]" 
     211                        end 
     212                end 
     213 
    180214                pid = nil 
    181215                pid = ",id:#{tg.attributes['objectID']}" if tg.attributes['objectID'] != nil 
    182216 
    183                 "{tag:JSplash.tPlaceObject2#{pid},d:#{tg.attributes['depth']}#{cl}#{rep}#{mov}#{scl}#{skw}#{nm}}" 
     217                "{tag:JSplash.tPlaceObject2#{pid},d:#{tg.attributes['depth']}#{cl}#{rep}#{mov}#{scl}#{skw}#{nm}#{cofs}#{cfct}}" 
    184218        end 
    185219 
     
    325359 
    326360top_tags   = parse_taglist(tags.elements, lmap) 
    327 split_file = (top_tags.length > 20000) 
     361split_file = (top_tags.length > 25000) 
    328362 
    329363out1 = "#{out_dir}/movie1.js" 
     
    331365File.open(out1,'w'){|f1| 
    332366        next_file = nil 
    333         tags_1 = top_tags.slice!(0, 20000) 
     367        tags_1 = top_tags.slice!(0, 25000) 
    334368        if split_file 
    335369                next_file = ", 'movie2.js'"