Skip to content

Instantly share code, notes, and snippets.

@straight-shoota
Last active May 21, 2017 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save straight-shoota/3506b0a2197deb1cea723353f2f878e9 to your computer and use it in GitHub Desktop.
Save straight-shoota/3506b0a2197deb1cea723353f2f878e9 to your computer and use it in GitHub Desktop.
Create Slideshow with Panzoom Effect in Adobe After Effects
//
// Copyright 2017 Johannes Müller <straightshoota@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// This is a scipt for After Effects. Run it to create a composition containing
// a slideshow of images you select via a file chooser dialog.
//
//
// time span, a slide should be visible
var SLIDE_DURATION = 3; // in seconds
var TRANSITION_DURATION = 0.5; // in seconds
var TOTAL_DURATION = SLIDE_DURATION + TRANSITION_DURATION;
writeConsole("SLIDE_DURATION=" + SLIDE_DURATION);
writeConsole("TRANISTION_DURATION=" + TRANSITION_DURATION);
function createPanZoom(comp,layer) {
var rulesOfThirdsPoints = [[1/3,1/3],[2/3,1/3],[1/3,2/3],[2/3,2/3]]; // points of interest in image
var zoomModes = ["IN","OUT"];
var rdIdx = Math.floor(Math.random() * rulesOfThirdsPoints.length);
var f = rulesOfThirdsPoints[rdIdx];
var deltaZoomPoint = [f[0] * comp.width, f[1] * comp.height] - [comp.width/2,comp.height/2];
var rdIdx = Math.floor(Math.random() * zoomModes.length);
var zoomMode = zoomModes[rdIdx];
var keyTimes = [0, TOTAL_DURATION];
var keyValues;
switch(zoomMode) {
case "IN":
keyValues = [[100,100],[107,107]];
break;
case "OUT":
keyValues = [[109,109],[100,100]];
break;
default:
break;
}
var nullL = comp.layers.addNull();
layer.scale.expression =
"sx = 100 * thisComp.width / width; \r" +
"sy = 100 * thisComp.height / height; \r" +
"s = Math.max(sx,sy); \r" +
"[s,s];";
layer.parent = nullL;
nullL.anchorPoint.setValue(nullL.anchorPoint.value + deltaZoomPoint);
nullL.position.setValue(nullL.position.value + deltaZoomPoint);
nullL.scale.setValuesAtTimes(keyTimes,keyValues);
}
function isInArray(array, element) {
var found = false;
for (var i = 0; !found && i < array.length; i++) {
if (array[i] == element) found = true;
}
return found;
}
function isImageFile(fileName) {
var ext = fileName.split(".").pop().toUpperCase();
var imageFormats = ["BMP", "CIN", "IIF", "EXR", "GIF", "JPG", "JPEG", "PCX", "PCT", "PNG", "PSD", "PXR", "HDR", "SGI", "TIF", "TGA"];
return isInArray(imageFormats, ext);
}
function run() {
var imagesFolder = defaultFolder.selectDlg("Select images folder:");
if (imagesFolder) {
defaultFolder = imagesFolder;
app.beginUndoGroup("PanZoom.jsx");
var assetFolder = app.project.items.addFolder("PanZoom Assets - " + File.decode(imagesFolder.name));
var comps = [];
var files = imagesFolder.getFiles();
clearOutput();
for (var i = 0; i < files.length; i++) {
if (isImageFile(files[i].fsName)) {
clearOutput();
var io = new ImportOptions();
var item;
try
{
io.file = files[i];
if (io.canImportAs(ImportAsType.FOOTAGE)) {
io.importAs = ImportAsType.FOOTAGE;
}
item = app.project.importFile(io);
} catch(e) {
item = app.project.importPlaceholder(files[i].name,1920,1080,25,3600);
}
if (item) {
item.selected = false;
writeLn((i+1) + "/" + files.length + ": " + item.name);
var comp = app.project.items.addComp(item.name,item.width,item.height,item.pixelAspect,TOTAL_DURATION,25);
var layer = comp.layers.add(item);
createPanZoom(comp,layer);
item.parentFolder = assetFolder;
comp.parentFolder = assetFolder;
comps.push(comp);
}
}
}
// create final comp
if (comps.length > 0)
{
var finalComp = app.project.items.addComp("Final - " + File.decode(imagesFolder.name),1920,1080,1,comps.length * SLIDE_DURATION,25),
next_slide_animation_index = 5,
slide_animation_distance = 6
for (var i = 0; i < comps.length; i++) {
writeLn("Final Comp, Layer: " + (i+1) + "/" + comps.length);
var layer = finalComp.layers.add(comps[i]);
// scale to cover composition size
layer.scale.expression =
"sx = 100 * thisComp.width / width; \r" +
"sy = 100 * thisComp.height / height; \r" +
"s = Math.max(sx,sy); \r" +
"[s,s];";
var startTime = i * SLIDE_DURATION - TRANSITION_DURATION;
layer.startTime = startTime;
// add a white effect every six slides for some
if(i == next_slide_animation_index){
var keyTimes = [startTime, startTime + TRANSITION_DURATION];
var keyValues = [100,0];
layer.Effects.addProperty("Linear Wipe");
var wipe = layer.Effects.property("Linear Wipe");
wipe.property("Wipe Angle").setValue(0);
wipe.property("Transition Completion").setValuesAtTimes(keyTimes, keyValues);
//wipe.property("Feather").setValue(80);
next_slide_animation_index = i + slide_animation_distance
}
}
finalComp.workAreaDuration = Math.max(finalComp.frameDuration, startTime);
finalComp.selected = true;
}
if (assetFolder.numItems < 1)
assetFolder.remove();
writeLn("Done !");
app.endUndoGroup();
}
}
var defaultFolder;
if (defaultFolder == null) {
defaultFolder = Folder.current;
}
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment