Type ramp generator

It’s often helpful to use mathematical logic to iterate on type ramp options. This tool was made to generate different logical ramps quickly and visually.

Instructions

This script is intended to run within Figma through its plugin API. The fastest way to run this script is by copy-pasting within Scripter.

One note: There are two functions in this script - easeRamp and multRamp which respectively use easing functions and multipliers to generate the ramp values. The script defaults to using easeRamp, but that’s easily adjusted in code.

            
const FRAME_NAME = 'Type ramp'
const GAP = 10;
const PADDING = 20;
const FRAME_BACKGROUND = {r:1, g:1, b:1}
const RAMP_COLOR = {r:0, g:0, b:0}
const FILL_SEED = [{
    type: "SOLID",
    visible: true,
    opacity: 1,
    blendMode: "NORMAL",
    color: {
      r: 1,
      g: 1,
      b: 1
    },
    boundVariables: {}
  }]

const MULT_ONE_SIXTEENTH = 1.067;
const MULT_ONE_TWELVETH = 1.083;
const MULT_ONE_TENTH = 1.1;
const MULT_ONE_EIGHTH = 1.125;
const MULT_ONE_SIXTH = 1.167;
const MULT_ONE_FOURTH = 1.250;
const MULT_ONE_THIRD = 1.333
const MULT_ONE_HALF = 1.5;
const MULT_TWO_THIRDS = 1.667;
const MULT_THREE_FOURTHS = 1.750;

// Easing functions from https://gizma.com/easing/ - thank you!
const EASE_LINEAR = function(x) { return x; }
const EASE_IN_SINE = function(x) { return 1 - Math.cos((x * Math.PI) / 2); }
const EASE_OUT_SINE = function(x) { return Math.sin((x * Math.PI) / 2); }
const EASE_IN_OUT_SINE = function(x) { return -(Math.cos(Math.PI * x) - 1) / 2; }
const EASE_IN_QUAD = function(x) { return x * x; }
const EASE_OUT_QUAD = function(x) { return 1 - (1 - x) * (1 - x) }
const EASE_IN_OUT_QUAD = function(x) { return x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2; }
const EASE_IN_CUBIC = function(x) { return x * x * x; }
const EASE_OUT_CUBIC = function(x) { return 1 - Math.pow(1 - x, 3); }
const EASE_IN_OUT_CUBIC = function(x) { return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2; }
const EASE_IN_QUART = function(x) { return x * x * x * x; }
const EASE_OUT_QUART = function(x) { return 1 - Math.pow(1 - x, 4); }
const EASE_IN_OUT_QUART = function(x) { return x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2; }
const EASE_IN_QUINT = function(x) { return x * x * x * x * x; }
const EASE_OUT_QUINT = function(x) { return 1 - Math.pow(1 - x, 5); }
const EASE_IN_OUT_QUINT = function(x) { return x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2; }
const EASE_IN_EXPO = function(x) { return x === 0 ? 0 : Math.pow(2, 10 * x - 10); }
const EASE_OUT_EXPO = function(x) { return x === 1 ? 1 : 1 - Math.pow(2, -10 * x); }
const EASE_IN_OUT_EXPO = function(x) { return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? Math.pow(2, 20 * x - 10) / 2 : (2 - Math.pow(2, -20 * x + 10)) / 2; }
const EASE_IN_CIRC = function(x) { return 1 - Math.sqrt(1 - Math.pow(x, 2)); }
const EASE_OUT_CIRC = function(x) { return sqrt(1 - Math.pow(x - 1, 2)); }
const EASE_IN_OUT_CIRC = function(x) { return x < 0.5 ? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2 : (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2; }

const STEPS = 11
const STEP = 1/(STEPS-1);

/*
 * This is the calculation for the type ramp. Adjust the values accordingly.
 */
const RAMP = easeRamp(12, 72, 7, EASE_IN_SINE)

let i = 0;

function easeRamp(min, max, steps, ease) {
    let i = 0;
    let step = 1/(steps-1);
    let ramp = []
    while(i < steps) {
        ramp.push(( ease(i*step)*(max-min))+min )
        i++
    }
    return ramp
}

function multRamp(base, belowBaseCount, aboveBaseCount, multiplier) {
    let ramp = [base];
    let i = 0;
    while(i < belowBaseCount) {
        ramp.push(base* Math.pow(multiplier, -(i+1)))
        i++
    }
    i=0
    while(i < aboveBaseCount) {
        ramp.push(base * Math.pow(multiplier, i+1))
        i++ 
    }

    ramp.sort(compareNumbers)
    return ramp;
}

function compareNumbers(a, b) {
    return a - b;
  }

let rampFrame:FrameNode = figma.createFrame();
rampFrame.layoutMode = 'VERTICAL';
rampFrame.layoutSizingHorizontal = 'HUG';
rampFrame.layoutSizingVertical = 'HUG';
let frameFill = FILL_SEED;

frameFill[0].color.r = FRAME_BACKGROUND.r;
frameFill[0].color.g = FRAME_BACKGROUND.g;
frameFill[0].color.b = FRAME_BACKGROUND.b;
rampFrame.fills = frameFill;
rampFrame.name = FRAME_NAME;
rampFrame.paddingBottom = rampFrame.paddingTop = rampFrame.paddingLeft = rampFrame.paddingRight = PADDING;
rampFrame.itemSpacing = GAP;
figma.currentPage.appendChild(rampFrame)

let rampItem:TextNode;

let rampFill = FILL_SEED;
rampFill[0].color.r = RAMP_COLOR.r;
rampFill[0].color.g = RAMP_COLOR.g;
rampFill[0].color.b = RAMP_COLOR.b;


for(let i = 0; i< RAMP.length; i++) {
	rampItem = figma.createText()	
	rampItem.fills = rampFill;
	rampItem.characters = 'Type size ' + (i+1);
	rampItem.fontSize= RAMP[i] 

	rampFrame.appendChild(rampItem);
}