9 Replies Latest reply on Dec 15, 2015 5:16 AM by oliverIntergrafika

    Is there a way to get the current timeline frame number in Frame Animation mode?

    oliverIntergrafika Level 2

      I would like to know which frame is the active frame in Frame Animation mode.

       

      I am using three scriptListener funcitons in order to avoid frame 1 propagation to ruin the timeline when something is changing in frame 1:

      duplicateTimelineFrame(); <<< do something with layers >>>; deleteTimelineFrame(); stepBackOneTimelineFrame();

       

      But when im doing something on the last frame, this sequence is stepping back one more frame.

       

      I have found a few user made getCurrentFrame(), getFrameCount() functions but they all working on Video Timeline, and returnning 0 when I am trying to use them on a Frame Animation.

       

      The PS DOM dont have any timeline related calsses or methods and I am confused from the script listener output. I dont have the willpower and intelligence to reverse engineer the code and make modifications in it.

       

      Thank You!

        • 1. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
          te_co Level 3

          i too have this question. I could only figure out how to set selection to a frame. But not how to retrieve current selection

          • 2. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
            c.pfaffenbichler Level 9

            If a direct determination should be impossible a work-around presents itself:

            • set the animationFrameDelay of the selected Frame/s to some outlandish number

            • check all the Frames for that number thus identifying the affected Frames

            • undo the changing of the animationFrameDelay

             

            Now the second part may not be as straightforward as would be desirable as I am unsure one can determine the total number of Frames beforehand, but either deleting the first frame within a try clause until it throws an error or marking first and last Frame with another outlandish animationFrameDelay would be options.

            • 3. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
              oliverIntergrafika Level 2

              Hi c.pfaffenbichler!

               

              Thanks for your answer! How do you know these actionDescriptor and actionReference solutions? I am trying to understand them since weeks, searching for script examples, making modifications to them without success. I am unable to find a tutorial, or figure, or diagram about their structure.

               

              Is there a .jsx library which is handlig these cryptic statements and constants? Did someone code the the missig DOM classes?

               

              I feel myself an idiot, because all the wasted time and effort trying to solve these basic problems.

               

               

              The sciptListener plugin exported the code below:

              function setFrameDelay( delay )
              {
              var idsetd = charIDToTypeID( "setd" );
                  var desc5 = new ActionDescriptor();
                  var idnull = charIDToTypeID( "null" );
                      var ref2 = new ActionReference();
                      var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
                      var idOrdn = charIDToTypeID( "Ordn" );
                      var idTrgt = charIDToTypeID( "Trgt" );
                      ref2.putEnumerated( idanimationFrameClass, idOrdn, idTrgt );
                  desc5.putReference( idnull, ref2 );
                  var idT = charIDToTypeID( "T  " );
                      var desc6 = new ActionDescriptor();
                      var idanimationFrameDelay = stringIDToTypeID( "animationFrameDelay" );
                      desc6.putDouble( idanimationFrameDelay, delay );
                  var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
                  desc5.putObject( idT, idanimationFrameClass, desc6 );
              executeAction( idsetd, desc5, DialogModes.NO );
              }
              

               

              Could you please instruct me, how to turn this into a getter function?

               

              Thanks a lot!
              Oliver

              • 4. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
                c.pfaffenbichler Level 9

                Actually my own grasp on AM code is tenuous …

                But in this example I can provide the code:

                ////// get framedelay //////

                function getFrameDelay (theIndex) {

                var ref = new ActionReference(); 

                ref.putProperty(charIDToTypeID('Prpr'), stringIDToTypeID('animationFrameDelay')); 

                ref.putIndex(stringIDToTypeID('animationFrameClass'), theIndex);

                //ref.putEnumerated(stringIDToTypeID('animationFrameClass'), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));

                var desc=new ActionDescriptor(); 

                desc.putReference(charIDToTypeID('null'), ref);          

                var aaa = executeAction(charIDToTypeID('getd'), desc, DialogModes.NO);

                //checkDesc2 (aaa);

                return aaa.getDouble(stringIDToTypeID('animationFrameDelay'))

                };

                • 5. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
                  oliverIntergrafika Level 2

                  c.pfaffenbichler You are great! I owe You.  

                   

                  This is working. Ill put the 2 functions side by side and try to compare them. This will be my rosetta stone.

                  • 6. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
                    c.pfaffenbichler Level 9

                    I use this code when I need to figure out how to get at certain parameters of Photoshop, a Document or a Layer for example.

                    Maybe it can be helpful for you as well.

                    #target photoshop

                    //if (app.documents.length > 0) {

                    var ref = new ActionReference();

                    // application;

                    //ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

                    // document;

                    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

                    // layer;

                    //ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

                    var docDesc = executeActionGet(ref);

                    checkDesc2(docDesc);

                    //};

                    ////// based on code by michael l hale //////

                    function checkDesc2 (theDesc) {

                    var c = theDesc.count;

                    var str = '';

                    for(var i=0;i<c;i++){ //enumerate descriptor's keys

                      str = str + 'Key '+i+' = '+typeIDToStringID(theDesc.getKey(i))+': '+theDesc.getType(theDesc.getKey(i))+'\n'+getValues (theDesc, i)+'\n';

                      };

                    alert("desc\n\n"+str);

                    };

                    ////// check //////

                    function getValues (theDesc, theNumber) {

                    switch (theDesc.getType(theDesc.getKey(theNumber))) {

                    case DescValueType.BOOLEANTYPE:

                    return theDesc.getBoolean(theDesc.getKey(theNumber));

                    break;

                    case DescValueType.CLASSTYPE:

                    return theDesc.getClass(theDesc.getKey(theNumber));

                    break;

                    case DescValueType.DOUBLETYPE:

                    return theDesc.getDouble(theDesc.getKey(theNumber));

                    break;

                    case DescValueType.ENUMERATEDTYPE:

                    return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStr ingID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));

                    break;

                    case DescValueType.INTEGERTYPE:

                    return theDesc.getInteger(theDesc.getKey(theNumber));

                    break;

                    case DescValueType.LISTTYPE:

                    return theDesc.getList(theDesc.getKey(theNumber));

                    break;

                    case DescValueType.OBJECTTYPE:

                    return (theDesc.getObjectValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getObject Type(theDesc.getKey(theNumber))));

                    break;

                    case DescValueType.REFERENCETYPE:

                    return theDesc.getReference(theDesc.getKey(theNumber));

                    break;

                    case DescValueType.STRINGTYPE:

                    return theDesc.getString(theDesc.getKey(theNumber));

                    break;

                    case DescValueType.UNITDOUBLE:

                    return (theDesc.getUnitDoubleValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getUn itDoubleType(theDesc.getKey(theNumber))));

                    break;

                    default:

                    break;

                    };

                    };

                    • 7. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
                      oliverIntergrafika Level 2

                      It seems very useful like a swiss knife! I hardly wait to try it out on various descriptors. I really appreciated for Your help!

                      • 8. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
                        c.pfaffenbichler Level 9

                        I’m just trying to "pass on" some of the help I got from (at the time) Forum regulars like xbytor, Mike Hale, Paul Riggott and others.

                        • 9. Re: Is there a way to get the current timeline frame number in Frame Animation mode?
                          oliverIntergrafika Level 2
                          //////////////// TIMELINE
                          
                          
                          try{
                          #target "Photoshop" ;
                          
                          Timeline = {
                          
                          
                            selectFrame: function( theIndex )
                            {
                            try
                            {
                            var idslct = charIDToTypeID( "slct" );
                            var desc152 = new ActionDescriptor();
                            var idnull = charIDToTypeID( "null" );
                            var ref84 = new ActionReference();
                            var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
                            ref84.putIndex( idanimationFrameClass, theIndex );
                            desc152.putReference( idnull, ref84 );
                            executeAction( idslct, desc152, DialogModes.NO );
                            }
                            catch ( e ) {
                            return false;
                            }
                            return theIndex;
                            },
                          
                          
                            getFrameCount: function () // till no faster way to retrieve it
                            {
                            this.markFrame();
                            var f = 1;
                            while( this.selectFrame( f++ ) )
                            this.selectMarkedFrame();
                            this.unMarkFrame();
                            return f-2;
                            },
                          
                          
                            selectMarkedFrame: function () {
                            var f = 1;
                            while( this.selectFrame( f++ ) && !this.isMarked() )
                            },
                          
                          
                            markFrame: function ()
                            {
                            this.setFrameDelay ( this.getFrameDelay() + 1000 );
                            },
                          
                          
                            unMarkFrame: function ()
                            {
                            this.setFrameDelay ( this.getFrameDelay() - 1000 );
                            },
                          
                            isMarked: function ()
                            {
                            return this.getFrameDelay() >= 1000;
                            },
                          
                          
                            setFrameDelay: function ( delay )
                            {
                            var idsetd = charIDToTypeID( "setd" );
                               var desc = new ActionDescriptor();
                               var ref = new ActionReference();
                            ref.putEnumerated(stringIDToTypeID('animationFrameClass'), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
                          
                          
                               desc.putReference( charIDToTypeID( "null" ), ref );
                               var idT = charIDToTypeID( "T   " );
                               var desc6 = new ActionDescriptor();
                               desc6.putDouble( stringIDToTypeID( "animationFrameDelay" ), delay );
                               desc.putObject( idT, stringIDToTypeID( "animationFrameClass" ), desc6 );
                            executeAction( idsetd, desc, DialogModes.NO );
                            },
                          
                          
                            getFrameDelay: function ( theIndex )
                            {
                               var ref = new ActionReference();
                               ref.putProperty(charIDToTypeID('Prpr'), stringIDToTypeID('animationFrameDelay'));
                          
                            if ( theIndex ) {
                            ref.putIndex(stringIDToTypeID('animationFrameClass'), theIndex);
                            }
                            else {
                            ref.putEnumerated(stringIDToTypeID('animationFrameClass'), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
                            }
                              
                               var desc=new ActionDescriptor();
                               desc.putReference(charIDToTypeID('null'), ref);         
                               var aaa = executeAction(charIDToTypeID('getd'), desc, DialogModes.NO);
                               // this.checkDesc2 (aaa);
                               return aaa.getDouble(stringIDToTypeID('animationFrameDelay'))
                            },
                          
                          
                            duplicateFrame: function()
                            {
                            executeAction( stringIDToTypeID( "makeFrameAnimation" ), undefined, DialogModes.NO ); // crate timeline
                               var desc = new ActionDescriptor();
                               var ref = new ActionReference();
                               ref.putEnumerated( stringIDToTypeID( "animationFrameClass" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
                               desc.putReference( charIDToTypeID( "null" ), ref );
                               executeAction( charIDToTypeID( "Dplc" ), desc, DialogModes.NO );
                            },
                          
                          
                            deleteFrame: function()
                            {
                               try
                               {
                                   var desc = new ActionDescriptor();
                                   var ref = new ActionReference();
                                   ref.putEnumerated( stringIDToTypeID( "animationFrameClass" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
                                   desc.putReference( charIDToTypeID( "null" ), ref );
                                   executeAction( charIDToTypeID( "Dlt " ), desc, DialogModes.NO );
                               } catch ( e )
                               {
                                   $.writeln("No Timeline, Cannot delete!")
                               }
                            },
                          
                          
                            stepBackOneFrame: function()
                            {
                            var idanimationFrameActivate = stringIDToTypeID( "animationFrameActivate" );
                               var desc9 = new ActionDescriptor();
                               var idnull = charIDToTypeID( "null" );
                                   var ref4 = new ActionReference();
                                   var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
                                   var idOrdn = charIDToTypeID( "Ordn" );
                                   var idPrvs = charIDToTypeID( "Prvs" );
                                   ref4.putEnumerated( idanimationFrameClass, idOrdn, idPrvs );
                               desc9.putReference( idnull, ref4 );
                            executeAction( idanimationFrameActivate, desc9, DialogModes.NO );
                            },
                          
                          
                          
                          ////// based on code by michael l hale //////
                            checkDesc2: function  ( theDesc ) {
                               var c = theDesc.count;
                               var str = '';
                               for( var i=0; i<c; i++ ){ //enumerate descriptor's keys
                                   str = str + 'Key '+ i + ' = ' + typeIDToStringID(theDesc.getKey(i)) + ': ' + theDesc.getType(theDesc.getKey(i))+'\n'+ this.getValues (theDesc, i)+'\n';
                               };
                               alert("desc\n\n"+str);
                            },
                          
                          
                            ////// check //////
                            getValues: function  ( theDesc, theNumber ) {
                               switch (theDesc.getType(theDesc.getKey(theNumber))) {
                               case DescValueType.BOOLEANTYPE:
                               return theDesc.getBoolean(theDesc.getKey(theNumber));
                               break;
                               case DescValueType.CLASSTYPE:
                               return theDesc.getClass(theDesc.getKey(theNumber));
                               break;
                               case DescValueType.DOUBLETYPE:
                               return theDesc.getDouble(theDesc.getKey(theNumber));
                               break;
                               case DescValueType.ENUMERATEDTYPE:
                               return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStringID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));
                               break;
                               case DescValueType.INTEGERTYPE:
                               return theDesc.getInteger(theDesc.getKey(theNumber));
                               break;
                               case DescValueType.LISTTYPE:
                               return theDesc.getList(theDesc.getKey(theNumber));
                               break;
                               case DescValueType.OBJECTTYPE:
                               return (theDesc.getObjectValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getObjectType(theDesc.getKey(theNumber))));
                               break;
                               case DescValueType.REFERENCETYPE:
                               return theDesc.getReference(theDesc.getKey(theNumber));
                               break;
                               case DescValueType.STRINGTYPE:
                               return theDesc.getString(theDesc.getKey(theNumber));
                               break;
                               case DescValueType.UNITDOUBLE:
                               return (theDesc.getUnitDoubleValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getUnitDoubleType(theDesc.getKey(theNumber))));
                               break;
                               default:
                               break;
                               };
                            },
                          
                          
                          
                          
                          }
                          
                          
                          } catch ( e ) { alert ( e ) };
                          
                          

                           

                          This is a short timeline manipulation .jsx. Now I can continue working on my little project.