Hey all!
I'm a newbie trying to build simple scripts for After Effects and I'm wondering how would be possible to embed images to scripts, without indicating a specific path. I've tried to convert the image to base 64 but with no success. What could I do to add custom icons, like the Motion 2 panel?
I need a direction on where to look for this info.
Thanks!
Simple question: how to embed images into jsx files?
Moderator: Paul Tuersley
Take a look at "Displaying Images" in the Javascript Tools Guide: http://estk.aenhancers.com/4%20-%20User ... ing-images
Hi!
About embed a image on a script file, I watched a course made my Mathias Möhl that shows how to do that. Take a look at the Class 3 description:
https://www.fxphd.com/details/539/
It's not so easy, you must to convert your image to binary, than import to your code. Usually you must to reconvert the binary code to image and save a temporary file on the user computer, so it will not be necessary to make all these conversions every time that you open the script.
It's a paid course, buy definitely worth it. I got the tip from Zack's website:
https://zacklovatt.com/ae-scripting-resources/
But...
Images on scripts have a huge problem these days: As far as I know, it doesn't support retina display (or the pc equivalent). It always shows a pixelated image, what's very annoying. Even Motion2 script has this problem, I think they used square style design buttons to try to minimize this problem.
I found 2 solutions for this problem:
Use CEP. As it use HTML5, you will not have problem with pixelated images, because you can work just as on web, put a image twice the space that you have, and it will be great in retina displays. But as far as I know, you will not be able to embed files directly on your script. In fact, I'm just starting in script as well, so I don't know very well how it works. Study CEP will be my next step .
The other solution I found because I notice that the RubberHose script didn't have this issue. So I casually found at Adam Plouff Github a open source script that tells how he did it:
https://github.com/adamplouff/scriptui-battlestyle
This script is amazing, just love how it works, it's very clever. It use vector coordinates to create images directly inside your script. There are some downsides:
You cannot use curves on the image design, just straight lines. In my workflow I create the images on Illustrator using curves, then I add as many anchorpoints as needed to make it look a curve, simplify it using the straight line option. Later, I export it to svg to get the coordinates.
The other issue is that your art must have just one color. In fact, I was able to create more than one color images, but it's very hard because you must handle every color as a kind of layer, and place it's position manually.
Using this technique you will be able to create Roll Over effects on the images, and use it as buttons too.
Take a look at my adapted code:
All the best, Jack.
About embed a image on a script file, I watched a course made my Mathias Möhl that shows how to do that. Take a look at the Class 3 description:
https://www.fxphd.com/details/539/
It's not so easy, you must to convert your image to binary, than import to your code. Usually you must to reconvert the binary code to image and save a temporary file on the user computer, so it will not be necessary to make all these conversions every time that you open the script.
It's a paid course, buy definitely worth it. I got the tip from Zack's website:
https://zacklovatt.com/ae-scripting-resources/
But...
Images on scripts have a huge problem these days: As far as I know, it doesn't support retina display (or the pc equivalent). It always shows a pixelated image, what's very annoying. Even Motion2 script has this problem, I think they used square style design buttons to try to minimize this problem.
I found 2 solutions for this problem:
Use CEP. As it use HTML5, you will not have problem with pixelated images, because you can work just as on web, put a image twice the space that you have, and it will be great in retina displays. But as far as I know, you will not be able to embed files directly on your script. In fact, I'm just starting in script as well, so I don't know very well how it works. Study CEP will be my next step .
The other solution I found because I notice that the RubberHose script didn't have this issue. So I casually found at Adam Plouff Github a open source script that tells how he did it:
https://github.com/adamplouff/scriptui-battlestyle
This script is amazing, just love how it works, it's very clever. It use vector coordinates to create images directly inside your script. There are some downsides:
You cannot use curves on the image design, just straight lines. In my workflow I create the images on Illustrator using curves, then I add as many anchorpoints as needed to make it look a curve, simplify it using the straight line option. Later, I export it to svg to get the coordinates.
The other issue is that your art must have just one color. In fact, I was able to create more than one color images, but it's very hard because you must handle every color as a kind of layer, and place it's position manually.
Using this technique you will be able to create Roll Over effects on the images, and use it as buttons too.
Take a look at my adapted code:
Code: Select all
// General Variables
var scriptName = '2df Icon';
var scriptVersion = '0.1';
//Windows
var w = new Window('palette', 'Create Text Animations', undefined, {resizeable: true});
w.alignChildren = ['fill', 'fill'];
w.margins = 8;
w.spacing = 8;
// ============ UI Elements and Metrics =================
////createGRP
var createGRP = w.add('group');
///////////////////////////////////////////////////////////
//IMAGES LAYERS
var icons = { vector_2dfLogoBlack: ["18.95 2.86 17.11 2.86 17.11 4.07 16.95 4.45 16.57 4.61 16.19 4.45 16.03 4.07 16.03 2.86 14.29 2.86 13.91 2.7 13.76 2.32 13.91 1.94 14.29 1.78 16.03 1.78 16.03 0 16.57 0.1 17.11 0.47 17.11 1.78 18.46 1.78 18.91 2.42 18.95 2.86 18.95 2.86 18.95 2.86 18.95 2.86",
"4.5 1.78 2.88 1.78 2.88 0.01 2.41 0.12 1.81 0.49 1.81 1.78 0.49 1.78 0.1 2.38 0 2.86 1.81 2.86 1.81 4.07 1.97 4.45 2.35 4.61 2.73 4.45 2.88 4.07 2.88 2.86 4.5 2.86 4.88 2.7 5.04 2.32 4.88 1.94 4.5 1.78 4.5 1.78 4.5 1.78 4.5 1.78"],
vector_2dfLogoBlackLive: ["1.54 0.77 1.31 1.31 0.77 1.54 0.23 1.31 0 0.77 0.23 0.23 0.77 0 1.31 0.23 1.54 0.77 1.54 0.77","11.54 0.77 11.31 1.31 10.77 1.54 10.22 1.31 10 0.77 10.22 0.23 10.77 0 11.31 0.23 11.54 0.77 11.54 0.77"],
vector_2dfLogoDarkGreen: ["15.52 6.51 15.28 6.34 14.14 4.06 12.5 2.41 10.44 1.35 8.07 0.97 5.72 1.35 3.65 2.41 2.01 4.06 0.85 6.36 0.53 6.53 0.17 6.42 0 6.1 0.02 5.9 1.19 3.55 3.04 1.67 5.42 0.42 8.07 0 10.73 0.42 13.12 1.67 14.96 3.55 16.13 5.9 16.1 6.27 15.81 6.51 15.52 6.51",
"2 18.43 2 9.5 2.84 18.43 2 18.43 2 18.43",
"5.62 18.43 5.62 10.7 5.95 18.43 5.62 18.43 5.62 18.43",
"10.2 18.43 10.53 10.7 10.53 18.43 10.2 18.43 10.2 18.43",
"13.31 18.43 14.15 9.5 14.15 18.43 13.31 18.43 13.31 18.43"],
vector_2dfLogoGreen: ["24.85 10.85 24.78 10.19 24.59 9.57 24.3 9 23.91 8.51 23.43 8.1 22.88 7.78 22.27 7.57 21.61 7.47 21.16 5.93 20.46 4.51 19.54 3.24 18.42 2.14 17.12 1.24 15.69 0.57 14.13 0.15 12.47 0 10.82 0.15 9.26 0.57 7.82 1.24 6.53 2.14 5.41 3.23 4.49 4.51 3.79 5.93 3.33 7.47 2.66 7.55 2.03 7.75 1.47 8.06 0.97 8.48 0.57 8.97 0.26 9.54 0.07 10.17 0 19.43 24.86 19.43 24.86 10.85 24.85 10.85 24.85 10.85"],
vector_2dfLogoWhite: ["1.79 6.42 2.13 4.75 3.06 3.38 4.42 2.46 6.1 2.12 7.31 2.29 8.38 2.78 9.27 3.53 9.93 4.49 7.79 5.11 5.89 6.2 4.3 7.69 3.1 9.51 2.56 8.86 2.15 8.12 1.89 7.3 1.79 6.42 1.79 6.42",
"19.8 9.56 20.36 8.91 20.8 8.16 21.07 7.33 21.17 6.42 20.83 4.75 19.91 3.38 18.54 2.46 16.86 2.12 15.65 2.29 14.58 2.78 13.69 3.54 13.03 4.51 15.16 5.14 17.04 6.24 18.61 7.74 19.8 9.56 19.8 9.56",
"22.55 0.81 22.62 0.62 22.55 0.43 22.87 0 22.44 0.32 22.25 0.26 22.06 0.32 21.63 0 21.95 0.43 21.89 0.62 21.95 0.81 21.63 1.24 22.06 0.92 22.25 0.98 22.44 0.92 22.87 1.24 22.55 0.81 22.55 0.81",
"0.92 0.81 0.98 0.62 0.92 0.43 1.24 0 0.81 0.32 0.62 0.26 0.43 0.32 0 0 0.32 0.43 0.26 0.62 0.32 0.81 0 1.24 0.43 0.92 0.62 0.98 0.81 0.92 1.24 1.24 0.92 0.81 0.92 0.81","11.89 1.75 12.04 1.35 11.89 0.96 12.27 0.53 11.83 0.9 11.43 0.74 11.04 0.9 10.61 0.53 10.97 0.96 10.82 1.35 10.97 1.75 10.61 2.18 11.04 1.81 11.43 1.97 11.83 1.81 12.27 2.18 11.89 1.75 11.89 1.75"]
};
uiPalette = {
white: "#DDDDDD",
lightGray: "#A4A4A4",
gray: "#434343",
darkGray: "#313131",
green: "#23ad8b",
lightGreen: "#00ffc1",
darkGreen: "#0f8655",
red: "#E9573F",
lightRed : "#FF6B6B",
yellow: "#F6BB42",
lightYellow: "#FFCE54"
}
//JUST CONVERT COLORS FROM HEX TO SCRIPT RGB
function hexToArray(hexString, alpha) {
if (alpha == undefined) alpha = 1;
var hexColor = hexString.replace('#', '');
var r = parseInt(hexColor.slice(0, 2), 16) / 255;
var g = parseInt(hexColor.slice(2, 4), 16) / 255;
var b = parseInt(hexColor.slice(4, 6), 16) / 255;
return [r, g, b, alpha];
}
//CREATING THE COORDENATES FROM THE CRAZY NUMBERS ABOVE
function vecToPoints(vecCoord) {
var points = [];
var n;
for (var i = 0; i < vecCoord.length; i++) {
var eachNum = vecCoord[i].split(/[\s,]/);
var coordinates = [];
var sets = [];
for (var k = 0; k < eachNum.length; k += 2) {
sets.push(eachNum[k] + "," + eachNum[k + 1]);
}
for (var j = 0; j < sets.length; j++) {
n = sets[j].split(",");
coordinates[j] = n;
coordinates[j][0] = (parseFloat(coordinates[j][0]));
coordinates[j][1] = (parseFloat(coordinates[j][1]));
}
points.push(coordinates);
}
return points;
}
//DRAWING THE PATHS
function tdf_2dfSmall_draw() {
this.graphics.drawOSControl();
this.graphics.rectPath(2, 2, this.size[0]-4, this.size[1]-4);
this.graphics.fillPath(this.fillBrush);
this.graphics.strokePath(this.strokeBrush);
var line;
try {
for (var a = 0; a < this.coord.length; a++) {
for (var i = 0; i < this.coord[a].length; i++) {
line = this.coord[a][i];
this.graphics.newPath();
var pX = this.iconPosition[a][0];
var pY = this.iconPosition[a][1];
this.graphics.moveTo(line[0][0] + (pX), line[0][1] + pY);
for (var j = 0; j < line.length; j++) {
this.graphics.lineTo(line[j][0] + pX, line[j][1] + pY);
}
this.graphics.fillPath(this.fillIcon[a]);
}
}
} catch (e) {}
}
//CREATING THE BUTTON
function tdf_2dfSmall(options){
options = options || {};
var parentObj = options.parentObject;
var size = options.sizeA;
var white = options.white;
var black = options.black;
var green = options.green;
var lightGreen = options.lightGreen;
var darkGreen = options.darkGreen;
var red = options.red;
var buttonText = options.buttonText;
var btn = parentObj.add("button", [0, 0, size[0]+10, size[1]+10, undefined]);
btn.strokeBrush = btn.graphics.newPen(btn.graphics.PenType.SOLID_COLOR, hexToArray(darkGreen), 2);
btn.fillBrush = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(red));
btn.fillIconA = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(green));
btn.fillIconB = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(white));
btn.fillIconC = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(darkGreen));
btn.fillIconD = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(black));
btn.icon = [options.icon[0],options.icon[1],options.icon[2],options.icon[3]];
btn.coord = [vecToPoints(btn.icon[0]), vecToPoints(btn.icon[1]), vecToPoints(btn.icon[2]), vecToPoints(btn.icon[3])];
btn.iconPosition = [[2.8,8.3],[4,4], [7.1,9.3], [6.1,6]];
btn.fillIcon = [btn.fillIconA, btn.fillIconB, btn.fillIconC, btn.fillIconD];
btn.text = buttonText + "/v";
btn.artSize = size;
btn.value = false;
btn.onDraw = tdf_2dfSmall_draw;
btn.addEventListener("mouseover", function() {
tdf_2dfSmall_update({
button: this,
iconColorD: black,
iconColorC: darkGreen,
iconColorA: green,
iconColorB: white,
strokeColor: lightGreen,
backgroundColor: red,
buttonText: buttonText,
size: this.artSize
});
var s = parentObj.size;
parentObj.size=[s[0], s[1]+1];
parentObj.size=[s[0], s[1]];
});
btn.addEventListener("mouseout", function() {
tdf_2dfSmall_update({
button: this,
iconColorD: black,
iconColorC: darkGreen,
iconColorA: green,
iconColorB: white,
strokeColor: darkGreen,
backgroundColor: red,
buttonText: buttonText,
size: this.artSize
});
var s = parentObj.size;
parentObj.size=[s[0], s[1]+1];
parentObj.size=[s[0], s[1]];
});
btn.addEventListener("mousedown", function() {
tdf_2dfSmall_update({
button: this,
iconColorD: black,
iconColorC: darkGreen,
iconColorA: green,
iconColorB: white,
strokeColor: green,
backgroundColor: red,
buttonText: buttonText,
size: this.artSize
});
this.value = true;
var s = parentObj.size;
parentObj.size=[s[0], s[1]+1];
parentObj.size=[s[0], s[1]];
});
btn.addEventListener("mousemove", function() {
if (btn.value){
tdf_2dfSmall_update({
button: this,
iconColorD: black,
iconColorC: darkGreen,
iconColorA: green,
iconColorB: white,
strokeColor: darkGreen,
backgroundColor: red,
buttonText: buttonText + this.value,
size: this.artSize
});
this.value = false;
var s = parentObj.size;
parentObj.size=[s[0], s[1]+1];
parentObj.size=[s[0], s[1]];
}
});
return btn;
}
//UPDATING THE BUTTON
function tdf_2dfSmall_update(options){
options = options || {};
var btn = options.button;
var buttonText = options.buttonText;
btn.strokeBrush = btn.graphics.newPen(btn.graphics.PenType.SOLID_COLOR, hexToArray(options.strokeColor), 2);
btn.fillBrush = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(options.backgroundColor));
btn.fillIconA = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(options.iconColorA));
btn.fillIconB = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(options.iconColorB));
btn.fillIconC = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(options.iconColorC));
btn.fillIconD = btn.graphics.newBrush(btn.graphics.BrushType.SOLID_COLOR, hexToArray(options.iconColorD));
btn.artSize = options.size;
btn.value = false;
btn.text = buttonText + "/v";
btn.onDraw = tdf_2dfSmall_draw;
return btn;
}
///////////////////////////////////////////////////////////
var create_2DF = tdf_2dfSmall({
parentObject : createGRP,
icon: [icons.vector_2dfLogoGreen,icons.vector_2dfLogoWhite,icons.vector_2dfLogoDarkGreen,icons.vector_2dfLogoBlack],
sizeA: [21,21],
white: uiPalette.white,
green: uiPalette.green,
lightGreen: uiPalette.lightGreen,
darkGreen: uiPalette.darkGreen,
black: uiPalette.darkGray,
red: uiPalette.red,
buttonText: ""
});
create_2DF.minimumSize.width = 28;
create_2DF.minimumSize.height = 28;
/////show
w.onResizing = w.onResize = function () { w.layout.resize();};
w.center();
if (!( w instanceof Panel)) w.show();
Jack Morgan
www.2deadfrog.com
www.2deadfrog.com