Skip to content
This repository has been archived by the owner on Mar 30, 2023. It is now read-only.

Commit

Permalink
More Export Options
Browse files Browse the repository at this point in the history
Added export options: Scale, Dither, Colors, Optimize
  • Loading branch information
Creatide committed Jul 7, 2016
1 parent 1cd9239 commit 3d92650
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 56 deletions.
42 changes: 34 additions & 8 deletions AnimateMate.sketchplugin/Contents/Sketch/library/Animate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import 'library/Animation.js';

var debugLog = true;
var debugLog = false;
var animate = new Animate();
function Animate () {}

Expand Down Expand Up @@ -43,7 +43,7 @@ Animate.prototype.init = function (layers, loopNestedGroups) {
// ---------------------------------------- //


Animate.prototype.exportAnimation = function (exportName, exportGif, exportPng, renderStartFrame, renderEndFrame, referencePoint, loopAnimation, delayAnimation) {
Animate.prototype.exportAnimation = function (exportName, exportGif, exportPng, renderStartFrame, renderEndFrame, referencePoint, loopAnimation, delayAnimation, scaleValue, gifDither, gifOptimize, gifColors) {

// Set base name for exported items
this.exportName = exportName || this.exportName;
Expand Down Expand Up @@ -97,8 +97,11 @@ Animate.prototype.exportAnimation = function (exportName, exportGif, exportPng,
}
}

// Set scale value to default if it's wrongly typed
var scaleValue = utils.isNumeric(scaleValue) && scaleValue > 0 ? scaleValue : 1;

// Save PNG base images to selected location
this.saveImagePNG(utils.zeroPadding(k, digitsNumber), pngFilesLocation);
this.saveImagePNG(utils.zeroPadding(k, digitsNumber), pngFilesLocation, scaleValue);

// Log frame render time
if (debugLog) dialog.createLogMessage(1, [utils.zeroPadding(k, digitsNumber), utils.benchmarkTime.interval()]);
Expand All @@ -113,7 +116,7 @@ Animate.prototype.exportAnimation = function (exportName, exportGif, exportPng,
if (exportGif != 0 && this.exportFolders.tempFolder) {
// Log GIF starting message
if (debugLog) dialog.createLogMessage(2);
this.saveImageGIF(pngFilesLocation, delayAnimation, loopAnimation);
this.saveImageGIF(pngFilesLocation, delayAnimation, loopAnimation, gifDither, gifOptimize, gifColors);
}

// Remove temporary folder
Expand Down Expand Up @@ -512,17 +515,38 @@ Animate.prototype.getLayers = function (layers, loopNestedGroups) {
// ---------------------------------------- //


Animate.prototype.saveImagePNG = function (keyframeNumber, exportFolder) {
Animate.prototype.saveImagePNG = function (keyframeNumber, exportFolder, scaleValue) {
var exportFolder = exportFolder || this.exportFolders.tempFolder.folderPath;
var fileName = exportFolder.stringByAppendingPathComponent(this.exportName + '_' + keyframeNumber + '.png');
utils.doc.saveArtboardOrSlice_toFile_(utils.artboard, fileName);
var scaleSlice = [MSExportRequest requestWithRect:utils.artboardRect scale:scaleValue];
//utils.doc.saveArtboardOrSlice_toFile_(utils.artboard, fileName);
utils.doc.saveArtboardOrSlice_toFile_(scaleSlice, fileName);
};


Animate.prototype.saveImageGIF = function (pngFilesLocation, loopValue, delayValue) {
Animate.prototype.saveImageGIF = function (pngFilesLocation, loopValue, delayValue, gifDither, gifOptimizeLevel, gifColors) {

var loop = ' -l';
var loopValue = parseInt(loopValue);
var colorsValue = parseInt(gifColors);
var dither = parseInt(gifDither) ? ' --dither' : '';

// Colors between 2-256 value
colorsValue = colorsValue >= 2 && colorsValue <= 256 ? ' --colors=' + colorsValue : '';

// Switch optimize levels
var optimize = '';
switch (parseInt(gifOptimizeLevel)) {
case 1:
optimize = ' -O1';
break;
case 2:
optimize = ' -O2';
break;
case 3:
optimize = ' -O3';
break;
}

// Prevent Gifsicle one extra loop round
if (loopValue && !isNaN(loopValue)) {
Expand All @@ -547,7 +571,9 @@ Animate.prototype.saveImageGIF = function (pngFilesLocation, loopValue, delayVal

// Create bash command arguments
var convertGifImages = "find \"" + pngFilesLocation + "\" -name '*.png' -exec sips -s format gif -o \"" + tmpFolder + "\" {}.gif {} \\;";
var convertGifAnimation = "find \"" + tmpFolder + "\" -name '*.gif' -execdir bash -c '\"" + gifConverter + "\"" + loop + delay + " '*.gif' -o \"" + exportFolder + '/' + gifExportName + '.gif' + "\"' \\;";
var convertGifAnimation = "find \"" + tmpFolder + "\" -name '*.gif' -execdir bash -c '\"" + gifConverter + "\"" + colorsValue + dither + optimize + loop + delay + " '*.gif' -o \"" + exportFolder + '/' + gifExportName + '.gif' + "\"' \\;";

//log("AnimateMate: " + convertGifAnimation );

// Create GIF Image Sequence from exist PNG images
convertTask.setLaunchPath("/bin/bash");
Expand Down
128 changes: 92 additions & 36 deletions AnimateMate.sketchplugin/Contents/Sketch/library/Dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ function Dialog () {}
// EXPORT ANIMATION / RENDER ANIMATION
// "shortcut": "ctrl option cmd a"
Dialog.prototype.exportAnimation = function () {

// Warn if there is no animation in selected
if (animate.animationLayers.length == 0) {
dialog.createDialogMessage(3);
return false;
}

var elements = [
{
Expand Down Expand Up @@ -75,16 +81,23 @@ Dialog.prototype.exportAnimation = function () {
},
{
group: 'group',
columns: 1,
columns: 2,
items: [
{
defaultId: 'exportScaleValue',
type: 'input',
label: 'Scale (1 = 100%)',
value: 1,
column: 0
},
{
defaultId: 'exportAnchorPoint',
default: 0,
type: 'dropdown',
label: 'Anchor Point',
value: animate.referencePoints,
column: 0
}
column: 1
}
]
},
{
Expand All @@ -108,7 +121,36 @@ Dialog.prototype.exportAnimation = function () {
label: 'Loop Count (0 = infinite)',
value: 0,
column: 1
}
]
},
{
group: 'group',
columns: 3,
items: [
{
defaultId: 'exportGifDither',
type: 'checkbox',
value: 'Dither',
checked: false,
column: 2
},
{
defaultId: 'exportGifColors',
type: 'input',
label: 'Colors (2-256)',
value: 0,
column: 1
},
{
defaultId: 'exportGifOptimize',
type: 'dropdown',
label: 'Optimize Level',
value: ['Disabled', 1, 2, 3],
default: 3,
column: 0
}

]
},
{
Expand Down Expand Up @@ -191,15 +233,17 @@ Dialog.prototype.exportAnimation = function () {
if (response[0] == 1000) {

// Save new default values
dialog.defaultValues(elements, response[1]);
dialog.defaultValues(elements, response[1], undefined);

animate.exportAnimation(response[1][2].value, response[1][0].value, response[1][1].value, response[1][3].value, response[1][4].value, response[1][5].value, response[1][6].value, response[1][7].value);
animate.exportAnimation(response[1][2].value, response[1][0].value, response[1][1].value, response[1][3].value, response[1][4].value, response[1][6].value, response[1][7].value, response[1][8].value, response[1][5].value, response[1][11].value, response[1][9].value, response[1][10].value);

} else if (response[0] == 1002) {
dialog.defaultValues(elements, undefined, elementsDefaults[1]);
}
}
};


// CREATE ANIMATION / CREATE NEW KEYFRAME
// "shortcut": "ctrl option cmd k"
Dialog.prototype.createAnimation = function () {
Expand Down Expand Up @@ -281,6 +325,7 @@ Dialog.prototype.createAnimation = function () {
}
};


// REMOVE ANIMATION
// "shortcut": "ctrl option cmd d"
Dialog.prototype.removeAnimation = function () {
Expand All @@ -305,9 +350,9 @@ Dialog.prototype.removeAnimation = function () {
}

if (response[0] == 1000) animate.removeAnimation(removeAll);
//log(response)
};


// EDIT ANIMATION
// "shortcut": "ctrl option cmd l"
Dialog.prototype.editAnimation = function () {
Expand Down Expand Up @@ -371,6 +416,7 @@ Dialog.prototype.editAnimation = function () {
if (response[0] == 1000) animate.editAnimation(response[1][0].value, response[1][1].value);
};


// OFFSET ANIMATION
// "shortcut": "ctrl option cmd o"
Dialog.prototype.offsetAnimation = function () {
Expand Down Expand Up @@ -525,7 +571,18 @@ Dialog.prototype.offsetAnimation = function () {
// RESTORE KEYFRAME TO ITEM
// "shortcut": "ctrl option cmd r"
Dialog.prototype.returnKeyframe = function () {

// Warn if there is no animation in selected
if (animate.animationLayers.length == 0) {
dialog.createDialogMessage(3);
return false;
}

// Warn user if there is more than one layer selected
if (utils.selection.count() > 1 || utils.allLayersActive) {
dialog.createDialogMessage(10);
}

var elements = [
{
group: 'window',
Expand All @@ -549,18 +606,7 @@ Dialog.prototype.returnKeyframe = function () {
}
]
}
];

// Warn if there is no animation in selected
if (animate.animationLayers.length == 0) {
dialog.createDialogMessage(3);
return false;
}

// Warn user if there is more than one layer selected
if (utils.selection.count() > 1 || utils.allLayersActive) {
dialog.createDialogMessage(10);
}
];

var response = gui.createCustomForm(elements, true);
if (response[0] == 1000) animate.returnKeyframe(response[1][0].value);
Expand All @@ -571,6 +617,12 @@ Dialog.prototype.returnKeyframe = function () {
// "shortcut": "ctrl option cmd b"
Dialog.prototype.reverseKeyframes = function () {

// Warn if there is no animation in selected
if (animate.animationLayers.length == 0) {
dialog.createDialogMessage(3);
return false;
}

// Reverse all animations and warn user about it
if (utils.selection.count() > 1 || utils.allLayersActive) {
var elements = [
Expand Down Expand Up @@ -963,7 +1015,6 @@ Dialog.prototype.randomAnimation = function () {
animate.easingTypes.shift();

if (response[0] == 1000) {

// Save new default values
dialog.defaultValues(elements, response[1]);
animate.randomAnimation(responseValuesObj);
Expand All @@ -988,22 +1039,21 @@ Dialog.prototype.defaultValues = function (elements, responseValues, resetDefaul
var uiDefaults = {};
var userDefaults = {};
var storedDefaults = {};
var responseValues = responseValues;

// Get / Update stored default values to memory
function getStoredDefaults(initialValues) {

var refPluginDomain = utils.pluginDomain;
var defaults = [[NSUserDefaults standardUserDefaults] objectForKey: refPluginDomain];
var defaultValues = {};
var defaulVal;

for (var key in defaults) {
defaultValues[key] = defaults[key];
}

for (var key in initialValues) {
defaulVal = defaultValues[key];
if (defaulVal == null) defaultValues[key] = initialValues[key];
if (defaultValues[key] == null) defaultValues[key] = initialValues[key];
}

storedDefaults = defaultValues;
Expand All @@ -1018,23 +1068,25 @@ Dialog.prototype.defaultValues = function (elements, responseValues, resetDefaul

var defaults = [[NSUserDefaults standardUserDefaults] objectForKey: refPluginDomain];
var defaultValues = {};
var defaulVal;


for (var key in defaults) {
defaultValues[key] = defaults[key];
}

for (var key in newValues) {
defaulVal = defaultValues[key];
if (defaulVal != newValues[key]) {
if (defaultValues[key] != newValues[key]) {
defaultValues[key] = newValues[key];
}
}

// Replace defaults with ne object
// Replace defaults with new object
var defaultsRef = [NSUserDefaults standardUserDefaults];
[defaultsRef setObject: defaultValues forKey: refPluginDomain];


// Comment out to clear NSUserDefaults
// [defaultsRef setObject: null forKey: refPluginDomain];
// log("AnimateMate: " + defaults);

storedDefaults = defaults;
}
}
Expand All @@ -1045,11 +1097,15 @@ Dialog.prototype.defaultValues = function (elements, responseValues, resetDefaul
var foundObjectsArr = utils.findObjByProperty(elements, 'defaultId', 'items', true);

// Search pairs from submitted values and default values
function searchMatchResponseValues(tmpId) {
function searchMatchResponseValues(tmpObj) {
var tmpId = tmpObj.searchId;
var refObjId = tmpId.join('');
for (var i = 0; i < responseValues.length; i++) {
var refObjId = tmpId.join('');
var responseId = (responseValues[i]['id'].split(':')).slice(0, -1).join('');
if (refObjId == responseId) return responseValues[i].value;
if (refObjId == responseId) {
//log("AnimateMate: " + responseValues[i].value + " :: " + tmpObj.defaultId);
return responseValues[i].value;
}
}
}

Expand All @@ -1061,16 +1117,16 @@ Dialog.prototype.defaultValues = function (elements, responseValues, resetDefaul
switch (refObj.type) {
case 'input':
uiDefaults[refObj.defaultId] = refObj.value;
if (responseValues) userDefaults[refObj.defaultId] = searchMatchResponseValues(refObj.searchId);
if (responseValues) userDefaults[refObj.defaultId] = searchMatchResponseValues(refObj);
break;
case 'checkbox':
uiDefaults[refObj.defaultId] = refObj.checked;
if (responseValues) userDefaults[refObj.defaultId] = searchMatchResponseValues(refObj.searchId);
if (responseValues) userDefaults[refObj.defaultId] = searchMatchResponseValues(refObj);
break;
case 'dropdown':
uiDefaults[refObj.defaultId] = refObj.value[refObj.default];
//uiDefaults[refObj.defaultId] = refObj.default;
if (responseValues) userDefaults[refObj.defaultId] = searchMatchResponseValues(refObj.searchId);
if (responseValues) userDefaults[refObj.defaultId] = searchMatchResponseValues(refObj);
break;
}
}
Expand Down Expand Up @@ -1104,7 +1160,7 @@ Dialog.prototype.defaultValues = function (elements, responseValues, resetDefaul
}
}
for (var newProp in newValObj) {
if (refObj[oldProp] == newProp) {
if (refObj[oldProp] == newProp) {
switch (refObj.type) {
case 'input':
refObj.value = newValObj[newProp];
Expand Down
4 changes: 3 additions & 1 deletion AnimateMate.sketchplugin/Contents/Sketch/library/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,9 @@ Utils.prototype.findObjByProperty = function (obj, searchProperty, arrayName, in
for (var propName in refObjArr[i]) {

if (propName == searchProperty) {
if (incSearchIndex) refObjArr[i]["searchId"] = [foundId, i];
if (incSearchIndex) {
refObjArr[i]["searchId"] = [foundId, i];
}
result.push(refObjArr[i]);
}
}
Expand Down
Loading

0 comments on commit 3d92650

Please sign in to comment.