Simple question: how to embed images into jsx files?

Find out why the . goes before the /

Moderator: Paul Tuersley

Post Reply
User avatar
evefalcao
Posts: 4
Joined: December 25th, 2016, 12:27 pm
Contact:

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! :D
User avatar
zlovatt
Posts: 48
Joined: October 31st, 2016, 5:00 pm
Location: Toronto
Contact:

Take a look at "Displaying Images" in the Javascript Tools Guide: http://estk.aenhancers.com/4%20-%20User ... ing-images
User avatar
2deadfrog
Posts: 3
Joined: February 22nd, 2019, 2:52 am

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 :D.

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();

All the best, Jack.
Jack Morgan
www.2deadfrog.com
Post Reply