figureone
    Preparing search index...

    FigureElementPrimitive that can efficiently translate large numbers of points.

    The morph primitive is optimized to animate hundreds of thousands of points with minimal performance impact.

    Multiple arrays of points can be defined, and the translation of corresponding points in two arrays can be animated.

    Being able to accomodate so many points means this primitive can be used to efficiently morph shapes.

    All points in all point arrays can be assigned an individual color if desired. Use color: TypeColor to assign all points in all arrays the same color, color: Array<TypeColor> to assign all points in each array a specific color, color: Array<Array<TypeColor>> to assign each point in each array a specific color, and color: Array<TypeColor | Array<TypeColor> to assign some point arrays with one color, and others with a specific color per point.

    A point array is an array of numbers representing consecutive x, y points. For example, [x1, y1, x2, y2, ...].

    A color array is an array of numbers representing the color of each points. For example, [r1, g1, b1, a1, r2, g2, b2, a2, ...].

    If color is an array of colors and/or color arrays, then the its length must be equal to the number of point Arrays. The colors in the array will be matched up with the corresponding point arrays in points.

    This element's specialty is creating a visual effect, and so does not automatically calculate touch borders, and doesn't allow for color changes (with the setColor, dim, and undim methods). If touch borders are desired then either setup touch borders manually, or use a different element as a touch pad.

    This element comes with two specialized methods and an animation step:

    • setPoints - sets points to a specific point array
    • setPointsBetween - sets points to a position between two point arrays
    • animations.morph - morph between start and target

    Note, while animation is efficient, loading or generating hundreds of thousands of points when first instantiated can be slow on lower end systems, and may need to be accounted for (like letting the user know that loading is ongoing).

    const { polylineToShapes, getPolygonCorners } = Fig.morph;
    const { range } = Fig;

    // Number of shapes that make up the lines
    const n = 300;

    // Generate a line of points along a sinc function
    const sinc = (xIn, a, b) => {
    const x = xIn === 0 ? 0.00001 : xIn;
    return a * Math.sin(b * x) / (b * x);
    };

    // Generate line of shapes along a sinc function
    const xValues = range(-0.8, 0.8, 0.01);
    const [sincPoints] = polylineToShapes({
    points: xValues.map(x => [x, sinc(x, 0.6, 20)]),
    num: n,
    size: 0.04,
    shape: 15,
    });

    // Generate a line of shapes along a square
    const [squarePoints] = polylineToShapes({
    points: [[0.5, 0.5], [-0.5, 0.5], [-0.5, -0.5], [0.5, -0.5]],
    num: n,
    size: 0.04,
    close: true,
    shape: 15,
    });

    // Generate a line of shapes along a circle
    const [circlePoints] = polylineToShapes({
    points: getPolygonCorners({ radius: 0.5, sides: 50, rotation: Math.PI / 4 }),
    num: n,
    size: 0.04,
    close: true,
    shape: 15,
    });

    const morpher = figure.add({
    make: 'morph',
    names: ['sinc', 'square', 'circle'],
    points: [sincPoints, squarePoints, circlePoints],
    color: [1, 0, 0, 1],
    });

    // Animate morph
    morpher.animations.new()
    .delay(1)
    .morph({ start: 'sinc', target: 'square', duration: 2 })
    .morph({ start: 'square', target: 'circle', duration: 2 })
    .morph({ start: 'circle', target: 'sinc', duration: 2 })
    .start();
    const { imageToShapes, circleCloudShapes, polylineToShapes } = Fig.morph;
    const { range } = Fig;

    const image = new Image();
    image.src = './logocolored.png';
    image.onload = () => {
    const [logo, logoColors] = imageToShapes({
    image,
    width: 2,
    height: 2,
    dither: 0.003,
    });

    const n = logo.length / 2 / 6;
    const cloud = circleCloudShapes({
    radius: 3,
    num: n,
    size: 0.005,
    });

    const xValues = range(-0.8, 0.8, 0.001);
    const [sine] = polylineToShapes({
    points: xValues.map(x => [x, 0.3 * Math.sin(x * 2 * Math.PI / 0.4)]),
    num: n,
    size: 0.01,
    });

    const m = figure.add({
    make: 'morph',
    points: [cloud, logo, sine],
    names: ['cloud', 'logo', 'sine'],
    color: [logoColors, logoColors, [0, 0, 1, 1]],
    });

    m.setPoints('sine');
    m.animations.new()
    .delay(1)
    .morph({ start: 'sine', target: 'cloud', duration: 2 })
    .morph({ start: 'cloud', target: 'logo', duration: 2 })
    .start();
    };

    Hierarchy (View Summary)

    Index

    Constructors

    Methods

    • Conveniently set the first scale of the element's transform.

      Parameters

      • scaleOrX: number | TypeParsablePoint

        horizontal scale - either define as full x-y point, or as a number. If scaleOrX is a number and y is null, then both x and y will be equally scaled

      • y: number | null = null

        y coordinate if scaleOrX is a number (null)

      • z: number = 1

      Returns void

    • Pulse element.

      An element can be pulsed in scale, a rotation or a translation.

      The scale pulse can either be a single pulse, or a number of copies with a range of scales - which has the effect of making regular polygons thick.

      Either pass in a callback, or an options object defining the pulse and callback.

      Parameters

      • optionsOrDone: OBJ_Pulse | (() => void) | null = null

      Returns void

    • Transform a point between 'draw', 'local', 'figure', 'gl' and 'pixel' spaces.

      plane is only needed when converting from pixel space (a 2D space) to 'figure', 'local' or 'draw' spaces (a 3D space). A ray from the pixel is drawn into the screen and the intersection with the defined plane is returned.

      'pixel' to 'gl' is also a 2D to 3D transformation, but in this case the XY plane at z = 0 is used in gl space.

      Parameters

      • point: TypeParsablePoint
      • fromSpace: "figure" | "pixel" | "gl" | "local" | "draw"

        space to convert point from

      • toSpace: "figure" | "pixel" | "gl" | "local" | "draw"

        space to convert point to

      • toSpacePlane: TypeParsablePlane = ...

      Returns Point

    • Return the first rotation in the element's transform.

      Parameters

      • normalize: "" | "0to360" | "-180to180" = ''

        how to normalize the returned angle where '' returns the raw angle

      Returns number

      scale

    • Get position of element

      By default the first translation of the element's transform is returned. This is effectively the element's location in 'local' coordinates.

      The position of the element relative to its horizontal and vertical bounds can also be returned. Use xAlign to find the x coordinate of the left, center, right or percentage width from left of the element. Use yAlign to find the bottom, middle, top or percentage height from bottom of the element.

      Parameters

      • space: TypeCoordinateSpace = 'local'

        the space to return the position in

      • xAlign: number | "left" | "right" | "center" | "location" = 'location'

        horizontal alignment of position. Use a number to define the horizontal position in percentage width from the left.

      • yAlign: number | "top" | "bottom" | "middle" | "location" = 'location'

        vertical alignment of position. Use a number to define the vertical position in percentage height from the bottom.

      Returns Point

    • Set angle to draw.

      Some primitive elements can be partially drawn to some angle.

      An angle of -1 represents the maximum angle allowed by the primitive.

      Parameters

      • angle: number = -1

        Angle to draw

      Returns void

    • Set points position to be between two points arrays

      Parameters

      • from: string | number

        name or index of point array to morph from

      • to: string | number

        name or index of point array to morph to

      • percent: number

        percent of morph between from and to

      Returns void