It is fairly easy to extend as well. Simply duplicate expression layers as needed and do a CTRL-ALT-/ to replace solid with footage.

I notice, in the "controllayer" you have some key frames that are animating the layers position and y-rotation. They don't seem to have any effect, is that just left over from development or do they serve a purpose?

Well, I got a little carried away with playing with your comp this morning.
I was working on a variation of import all images in a folder script last night. So I incorporated your expressions into the script.
Here it is:

//Import Section By Byron Nash 10/2004
//Revised 12/03/2007 Atom
/*
This script imports a folder of images and sequences them in a predestined comp.
It also sets ALL comps in the project to be the length of the new sequenced comp.
This is useful if you are versioning a bunch of images into the same graphic bed.
It also also animates the fade in and fade out for each layer.
Instructions:
1. Make sure you have a project with a comp at the very top. Put a "1" in front of the name if need be to keep it the first object in the list.
2. Run script
3. Choose a folder of files when prompted
Just to clarify, this script runs in passes, so it will import a series of image, then create layers from that import.
Because this script operates on an existing comp, it does no know the name of the comp, so it references the first object in the project window as the comp.
Consider this, you create default comp called "Comp 1" then you import a series of images froma folder. The folder contains an image called "blueprint.jpg".
Now blueprint.jpg is above Comp 1 in the project list and the script will try to operate on the JPG as if it were a comp.
This is what causes the error if you do not put a 1 in front of the comp name. You might want to put a zero.
If an image comes in with a 0 instead of a 1 as it's first character you could also error out.
It's not perfect, but it took me a while to figure this out so I thought I'd mention why it will error out and how to avoid this.
Limitation/ Flaws:
I already mentioned the naming of the comp flaw in this script.
I have hard coded the comp size and height to 720x480.
The duration of each imported image is given 5 seconds, you can adjust this by changing the variable, below.
The frame rate is calculated at 29.97 fps so if you are using another rate please change this value as well.
The import will also fail if the images in the folder have numbers prefixing their filename.
*/
{
// create undo group
app.beginUndoGroup("Import and Sequence");
//Ask the user for a folder whose contents are to be imported
var targetFolder = folderGetDialog("Import Items from Folder..."); //returns a folder or null
if (targetFolder)
{
// if no project open, create a new project to toss the files into. [23839]
if (!app.project) {app.newProject();}
function processFile (theFile)
{
try {
var importOptions = new ImportOptions (theFile); //create a variable containing ImportOptions
importSafeWithError (importOptions);
} catch( error ) {
// eat errors.
}
}
function testForSequence (files)
{
var searcher = new RegExp ("[0-9]+");
var movieFileSearcher = new RegExp ("(mov|avi|mpg)$", "i");
var parseResults = new Array;
//test that we have a sequence, stop parsing after 10 files
for (x = 0; (x < files.length) & x < 10; x++)
{
var movieFileResult = movieFileSearcher.exec(files[x].name);
if (! movieFileResult)
{
var currentResult = searcher.exec(files[x].name);
//regular expressions return null if no match was found
//otherwise they return an array with the following information:
//array[0] = the matched string
//array[1..n] = the matched capturing parentheses
if (currentResult) { //we have a match - the string contains numbers
//the match of those numbers is stored in the array[1]
//take that number and save it into parseResults
parseResults[parseResults.length] = currentResult[0];
}
else {
parseResults[parseResults.length] = null;
}
}
else {
parseResults[parseResults.length] = null;
}
}
//if all the files we just went through have a number in their file names,
//assume they are part of a sequence & return the first file
var result = null;
for (i = 0; i < parseResults.length; ++i) {
if (parseResults[i]) {
if (! result) {
result = files[i];
}
} else {
//case in which a file name did not contain a number
result = null;
break;
}
}
return result;
}
function importSafeWithError (importOptions)
{
try {
app.project.importFile (importOptions);
} catch (error) {
alert(error.toString() + importOptions.file.fsName);
}
}
function processFolder(theFolder)
{
var files = theFolder.getFiles(); //Get an array of files in the target folder
//test whether theFolder contains a sequence
var sequenceStartFile = false; //testForSequence(files);
//if it does contain a sequence, import the sequence
if (sequenceStartFile) {
try {
var importOptions = new ImportOptions (sequenceStartFile); //create a variable containing ImportOptions
importOptions.sequence = true;
//importOptions.forceAlphabetical = true; //un-comment this if you want to force alpha order by default
importSafeWithError (importOptions);
} catch (error) {
}
}
//otherwise, import the files and recurse
//Go through the array and set each element to singleFile, then run the following
for (index in files)
{
if (files[index] instanceof File) {
if (! sequenceStartFile) { //if file is already part of a sequence, don't import it individually
processFile (files[index]); //calls the processFile function above
}
}
if (files[index] instanceof Folder) {
processFolder (files[index]); // recursion
}
}
}
processFolder(targetFolder);
}
//Script begins here.
var logoSel = app.project.selection; //set selected import items to an array
var logoComp = app.project.item(1); //select the logo comp
var compW = 720; // comp width
var compH = 480; // comp height
var perImageDuration= 900; //Frames divided by frame rate equals seconds.
logoComp.duration = perImageDuration/29.97 //set comp length to 1 second
//loop through and add layers to comp
for (i=0; i < logoSel.length; i++)
{
//Add to logo comp
if(logoSel[i] instanceof FootageItem)
{ //test to be sure it's not a comp or folder
var lcoll = logoComp.layers; //variable for collection of layer objects in logoComp
lcoll.add(logoSel[i]); //add layer
//alert (logoSel[i].name);
}
}
//At this point, all imported items are in the project window.
//Now we must add them to the comp.
var curIn = 0; //initialize in point variable
var i = 1; //collection items start at 1.
//Loop through layers
do
{
//Add footage layer.
var curLayer = lcoll[i];
curLayer.threeDLayer = true; //make 3d
curLayer.startTime = curIn; //set in point
var curOut = curLayer.outPoint; //set out
/*
//Auto animate the fade in and out for this layer.
myOpacity= curLayer.property("opacity");
myOpacity.setValueAtTime(curIn,0);
myOpacity.setValueAtTime(curIn + 0.25,100);
myOpacity.setValueAtTime(curOut - 0.25,100); //Effectively creates a hold frame, can cause problems on interlace footage.
myOpacity.setValueAtTime(curOut,0);
*/
var position_expression = "timeOffset = thisComp.layer('control layer').effect('Slider Control')('Slider') / 10;\nthisComp.layer('control layer').transform.position.valueAtTime(timeOffset + (index * thisComp.frameDuration * 50));\n"
var y_rotation_expression = "timeOffset = thisComp.layer('control layer').effect('Slider Control')('Slider') / 10;\nthisComp.layer('control layer').transform.yRotation.valueAtTime(timeOffset + (index * thisComp.frameDuration * 50));\n"
curLayer.property("position").expression = position_expression;
curLayer.property("yRotation").expression = y_rotation_expression;
//curIn = curOut; //new in point equals old out point.
//alert (curLayer.name);
i++;
}while(i<=(lcoll.length-2)); //Expects light layer and control layer to be in the comp hence the -2 layers.
// Set Final Comp to correct length.
logoComp.duration = (i-1) * logoComp.duration; //set comp end to reflect the new length.
compDur = logoComp.duration; //set variable for all comps
var stuff = app.project.items; //get collection of project items
for (i=1; i <= stuff.length; i++)
{//loop through project looking for our original comp item that was selected before we ran this script.
if(stuff[i] instanceof CompItem)
{//check for comp
stuff[i].duration = compDur; //set comp length
}
}
alert("Finished Importing and Sequencing of Images. Be sure to save the project as a new name.")
app.endUndoGroup();
}

CAVEAT:
This script expects the light and the control layer to be in place before you run it. Also you need to rename your comp so there is a #1 as the first character in the comp name.

USAGE:
Downlaod Paul's coverflow aep (above) and open the project.
Delete everything except the light and a single control layer.
Rename the comp to 1Coverflow
Run the script and browse to a folder with a bunch of footage items.

RESULTS:
The script will make a 3d layer out of each footage item in the folder and assign the two expressions to position and y rotation. After execution, you can scrub slider control to flip throught the images.

TODO:
Ideally, I would like the script to make the light and the control layer, but I am not that well versed at creating different layer types and assigning effects to them (yet!).

FALLOUT:
Does not support the reflection, but it may not be that hard to recreate once the import has been done.

Thanks again for the great AEP Paul!

Last edited by Atomic on December 4th, 2007, 8:28 am, edited 4 times in total.

Atomic wrote:I notice, in the "controllayer" you have some key frames that are animating the layers position and y-rotation. They don't seem to have any effect, is that just left over from development or do they serve a purpose?

The keyframes on the control layer contain all the animation. All the other layers are using "valueAtTime" expressions to copy that animation, with a time offset based on their layer index. You can make multiple copies of the control layer and try out different kinds of animation...whichever is the topmost layer will become the actual controlling layer.

Personally, I think you'd have to be nuts to try to do all the animation with some complicated expressions when it's so much easier to do it with keyframes.

How could you tweak this so instead of just having the images in a straight line, you could have a rotating cylinder in 3d space with all layers at a y rotation of 90Âº but when a layer is in the center/front it turns to 0Âº. and then back to 90Âº as it passes by?

Hi Guys !
I have managed to change the animation to a circle, instead of a straight line, just like pants asked !
I have tweaked the project file Paul uploaded, and added another Control Layers at the top, that does the job.
I added also a camera to show the scene a bit from above, and changed the location of the light source.

I made 2 options: one is a half circle, as in the link pants had sent, and the second one is a full circle !
You can download the project file here:

You can use that file, the same you used Pauls' file: the most upper Control Layer would control the motion.
(change the Control layer's Slider keyframes in order to flow the pictures, I've keyframed them to see the animation)

I managed to do it using a small script I wrote that changes the position and rotation keyframes of the Control layer, and replaces the keyframes needed for the circular motion.
If you find it interesting, here is the script:

You can use the script on the original file Paul uploaded, to achieve the same result of the project file I've uploaded:
1. choose one Control Layer (or duplicate one, and make sure to rename it to the same original name)
2. remove all it's position and rotation keyframes (by clicking the stop-watch of each property)
3. make sure that layer is selected and run the script (the script will automatically work only on the selected layer)
4. in order to see it propely, add a camera and position it above the scene to show the circular path of the pictures.
(I reccommend using a 138mm Preset Camera or above, in order to avoid perspective distortion of the pictures)
5. move the light source to the center of the screen, and pull it back in Z depth, to light the pictures correctly.
6. In order to have the reflections correclty, operate the script again on the Control Layers in the Refelction composition.

In order to do a half circle, change in the script the value of the K variable to 1, and for a full circle change it's value to 2.
(you'll see it as the first variable in the script: "var K = 1;" . Do this before you run the script off course)

NOTE: You could still use the script atom & byron wrote, in order to import pictures to the project file I've uploaded. Thank you guys for the great job ! Note that if you use atom & byron 's script on my project file, don't delete the camera and the light, and you can leave all Control layers (make them inactive) so you can change the behavior of the animation easily later (by changing their order). Note that when I tried that, I just had to disable the expression the light got by mistake from the script (by clicking the [=] signs), and then it worked perfectly (except the script doesn't add the reflections).

Great thanks to Paul, for making this animation and the expressions in the first place !

You could add an interesting motion effect to the animation if you space all the position & rotation keyframes a bit wider (by holding the ALT and then clicking & dragging the rightmost keyframe to the right something about 20-30 frames). That would create some kind of wave behaviour instead of all the pictures move together and then stand together (something reminding the wave effect a crowd sometimes makes in a soccer or a football game).

If you stretch all keyframes such that the last one is moved by exactly 50 frames to the right, you would get a constant movement wavy motion: Every picture would stand for the same amount of time, but there will be no time where nothing moves. You could try that operation on every Control layer that you want, but I think that with the full circle Control layer this would look best !

Lastly, you could try adding EaseIn/EaseOut (by using F9) to all position & rotation keyframes to get smoother and more natural motion.

Enjoy,
Koby.

p.s: You would have to increase the length of the composition (by using CTRL+K) to at least 36 seconds, in order to see all keyframes I made in the full circle control layer, and to be able to correctly choose ALL of them before you widen their spaces...