Skip to main content
Inspiring
October 29, 2019
Answered

Copy keyframe from a library symbol and paste into current timeline

  • October 29, 2019
  • 2 replies
  • 1050 views

Trying to copy a keyframe from a symbol ("model") in the library to paste into the current timeline. But have had no luck getting the symbol's timeline object. 

This isn't working:

var item = dom.library.selectItem("model") 
var childTimeline = item.timeline

fl.trace(childTimeline) // outputs: childTimeline = undefined

Any advice much appreciated.

 

    This topic has been closed for replies.
    Correct answer kilopop2000

    setting a layer active (with the currentLayer property) isn't the same a selecting it (with setSelectedLayers method).  ie, use:

     

    tl.setSelectedLayers(i)


    Thanks kglad, that was it. So now, how to copy frames from a library item and paste into the same named layers in the current timeline:

     

    // Define this timeline
    
    var dom = fl.getDocumentDOM();
    var tl = dom.getTimeline();
    var layers = tl.layers;
    
    
    // Define the library item
    
    var pName = String(tl.name + '/puppet/' + tl.name + '_poses')
    
    dom.library.selectItem(pName) 
    var copyTL		 	= dom.library.getSelectedItems()[0].timeline;	
    var copyTLArray 	= copyTL[1];	
    
    // Copy and paste frames variables
    
    var cFrom = 1
    var cTo = 2
    var pFrom = tl.currentFrame
    var pTo = pFrom + (cTo - cFrom)
    
    
    // Iterate Over copyTLArray and copy frames to paste into tl
    
    for (i = 0; i < copyTLArray.length; i++) {
    	
    	// Copy frames from copyTL
    	
    	copyTL.setSelectedLayers(i)
    	copyTL.currentLayer = i
    	copyTL.setSelectedFrames(cFrom, cTo);
    	copyTL.copyFrames(cFrom, cTo+1);
    	
    	// Select layer in tl based on name of copyTL[i].name
    	
    	var index = Number(tl.findLayerIndex(copyTLArray[i].name))
    	
    	if (!index) {
    		fl.trace("No layer called + " + copyTLArray[i].name)
    	}
    	else {
    		
    		// Check if keyframe exists
    		
    		var cLayer = layers[index]
    		var frame = cLayer.frames[tl.currentFrame];
    		var keyframe = frame.startFrame == tl.currentFrame
    		
    		// Select layer and frames
    		
    		fl.trace("huh = " + copyTLArray[i].name + " " + index)
    		tl.setSelectedLayers(index)
    		tl.setSelectedFrames(pFrom, pTo);
    		
    		if(!keyframe){ // if false
    			
    			var tFrame = tl.currentFrame;
    			tl.convertToKeyframes(tFrame);			
    		} 
    		
    		tl.pasteFrames(pFrom, pTo+1);
    		
    	}	
    }

     

    This code also adds a keyframe in the current tl.layer if there isn't one, but so far only returns a trace output if there is a layer in the symbol item that isn't already in the tl. 

    2 replies

    kglad
    Community Expert
    Community Expert
    October 31, 2019

    copyTL needs to be a timeline.  you're making it an array of layers.

     

    try:

     

    copyTL = dom.library.getSelectedItems()[0].timeline;

    Inspiring
    October 31, 2019

    Thanks kglad, yep it works to differentiate between the timeline and the array. 


    Nearly there I think..

    In order to copy and paste between a library item and the current timeline, the following code iterates over the library item's timeline selecting a layer and copying some frames and then looks for the same layer name in the current timline to paste into. But when the following is run, nothing is pasted except an empty keframe on the currently selected layer (in this case, 1 of 20 layers). 

     

     

    	var dom = fl.getDocumentDOM();
    	var tl = dom.getTimeline();
    	var layers = tl.layers;
    	
    	// Define the library item
    	
    	var pName = String(tl.name + '/puppet/' + tl.name + '_poses')
    	
    	dom.library.selectItem(pName) 
    	var copyTL		= dom.library.getSelectedItems()[0].timeline;	
    	var copyTLArray 	= dom.library.getSelectedItems()[0].timeline[1];	
    	
    	// Copy and Paste Details
    	
    	// Copy
    	
    	var cFrom = 1
    	var cTo = 2
    	var pFrom = tl.currentFrame
    	var pTo = pFrom + (cTo - cFrom)
    	
    	// Iterate Over copyTL and copy frames to paste into tl
    	
    	for (i = 0; i < copyTLArray.length; i++) {
    		
    		// Copy frames from copyTL
    		
    		copyTL.currentLayer = i;
    		copyTL.setSelectedFrames(cFrom, cTo);
    		copyTL.copyFrames(cFrom, cTo+1);
    		
    		// Select layer in tl based on name of copyTL[i].name
    		
    		var index = tl.findLayerIndex(copyTLArray[i].name);
    		
    		if (!index) {
    			fl.trace("No layer called + " + copyTLArray[i].name)
    		}
    		else {
    			tl.currentLayer = index
    			tl.setSelectedFrames(pFrom, pTo);
    			tl.pasteFrames(pFrom, pTo+1);	
    		}	
    	}

     

     
    Any ideas why nothing is being pasted?

    kglad
    Community Expert
    Community Expert
    November 1, 2019

    setting a layer active (with the currentLayer property) isn't the same a selecting it (with setSelectedLayers method).  ie, use:

     

    tl.setSelectedLayers(i)

    kglad
    Community Expert
    Community Expert
    October 30, 2019

    does item exist?  (there's a itemExists() method that can also be used to check.)

    Inspiring
    October 30, 2019

    @kglad, thanks for your reply. Yes, the item does exist. I've arrived at the following way to now access the timeline object of the library item in question with:

    dom.library.selectItem("model")
    var copyTL = dom.library.getSelectedItems()[0].timeline[1]

     

    Question is, how to copy frames from this copyTL timeline? The following returns "TypeError: copyTL.setSelectedFrames is not a function"

     

    var cFrom = 1

    var cTo = 3

     

    for (i = 0; i < copyTL.length; i++) {
         copyTL.currentLayer = i;
         copyTL.setSelectedFrames(cFrom, cTo);
         copyTL.copyFrames(cFrom, cTo+1);

    }