• Jump To … +
    ./source/asset-management/image-asset.js ./source/asset-management/noise-asset.js ./source/asset-management/raw-asset.js ./source/asset-management/reaction-diffusion-asset.js ./source/asset-management/sprite-asset.js ./source/asset-management/video-asset.js ./source/core/animation-loop.js ./source/core/display-cycle.js ./source/core/document.js ./source/core/events.js ./source/core/init.js ./source/core/library.js ./source/core/snippets.js ./source/core/user-interaction.js ./source/factory/action.js ./source/factory/anchor.js ./source/factory/animation.js ./source/factory/bezier.js ./source/factory/block.js ./source/factory/button.js ./source/factory/canvas.js ./source/factory/cell.js ./source/factory/cog.js ./source/factory/color.js ./source/factory/conic-gradient.js ./source/factory/crescent.js ./source/factory/element.js ./source/factory/emitter.js ./source/factory/enhanced-label.js ./source/factory/filter.js ./source/factory/gradient.js ./source/factory/grid.js ./source/factory/group.js ./source/factory/label.js ./source/factory/line-spiral.js ./source/factory/line.js ./source/factory/loom.js ./source/factory/mesh.js ./source/factory/net.js ./source/factory/oval.js ./source/factory/particle-force.js ./source/factory/particle-spring.js ./source/factory/particle-world.js ./source/factory/particle.js ./source/factory/pattern.js ./source/factory/picture.js ./source/factory/polygon.js ./source/factory/polyline.js ./source/factory/quadratic.js ./source/factory/radial-gradient.js ./source/factory/rectangle.js ./source/factory/render-animation.js ./source/factory/shape.js ./source/factory/spiral.js ./source/factory/stack.js ./source/factory/star.js ./source/factory/tetragon.js ./source/factory/ticker.js ./source/factory/tracer.js ./source/factory/tween.js ./source/factory/unstacked-element.js ./source/factory/wheel.js ./source/helper/array-pool.js ./source/helper/color-engine.js ./source/helper/document-root-elements.js ./source/helper/filter-engine-bluenoise-data.js ./source/helper/filter-engine.js ./source/helper/random-seed.js ./source/helper/shape-path-calculation.js ./source/helper/shared-vars.js ./source/helper/system-flags.js ./source/helper/utilities.js ./source/helper/workstore.js ./source/mixin/anchor.js ./source/mixin/asset-advanced-functionality.js ./source/mixin/asset-consumer.js ./source/mixin/asset.js ./source/mixin/base.js ./source/mixin/button.js ./source/mixin/cascade.js ./source/mixin/cell-key-functions.js ./source/mixin/delta.js ./source/mixin/display-shape.js ./source/mixin/dom.js ./source/mixin/entity.js ./source/mixin/filter.js ./source/mixin/hidden-dom-elements.js ./source/mixin/mimic.js ./source/mixin/path.js ./source/mixin/pattern.js ./source/mixin/pivot.js ./source/mixin/position.js ./source/mixin/shape-basic.js ./source/mixin/shape-curve.js ./source/mixin/styles.js ./source/mixin/text.js ./source/mixin/tween.js ./source/scrawl.js ./source/untracked-factory/cell-fragment.js ./source/untracked-factory/coordinate.js ./source/untracked-factory/drag-zone.js ./source/untracked-factory/keyboard-zone.js ./source/untracked-factory/observe-update.js ./source/untracked-factory/palette.js ./source/untracked-factory/particle-history.js ./source/untracked-factory/quaternion.js ./source/untracked-factory/state.js ./source/untracked-factory/text-style.js ./source/untracked-factory/vector.js
  • §

    Rectangle factory

    A factory for generating rectangular shape-based entitys, including round-cornered rectangles

  • §

    Imports

    import { constructors } from '../core/library.js';
    
    import { addStrings, doCreate, mergeOver, Ωempty } from '../helper/utilities.js';
    
    import baseMix from '../mixin/base.js';
    import shapeMix from '../mixin/shape-basic.js';
  • §

    Shared constants

    import { ENTITY, RECTANGLE, ZERO_PATH } from '../helper/shared-vars.js';
  • §

    Local constants

    const RADIUS_ARRAY_ALL = ['radiusTLX', 'radiusTRX', 'radiusBRX', 'radiusBLX', 'radiusTLY', 'radiusTRY', 'radiusBRY', 'radiusBLY'],
        RADIUS_ARRAY_BOTTOM = ['radiusBRX', 'radiusBRY', 'radiusBLX', 'radiusBLY'],
        RADIUS_ARRAY_BOTTOM_LEFT = ['radiusBLX', 'radiusBLY'],
        RADIUS_ARRAY_BOTTOM_LEFT_X = ['radiusBLX'],
        RADIUS_ARRAY_BOTTOM_LEFT_Y = ['radiusBLY'],
        RADIUS_ARRAY_BOTTOM_RIGHT = ['radiusBRX', 'radiusBRY'],
        RADIUS_ARRAY_BOTTOM_RIGHT_X = ['radiusBRX'],
        RADIUS_ARRAY_BOTTOM_RIGHT_Y = ['radiusBRY'],
        RADIUS_ARRAY_BOTTOM_X = ['radiusBRX', 'radiusBLX'],
        RADIUS_ARRAY_BOTTOM_Y = ['radiusBRY', 'radiusBLY'],
        RADIUS_ARRAY_LEFT = ['radiusTLX', 'radiusTLY', 'radiusBLX', 'radiusBLY'],
        RADIUS_ARRAY_LEFT_X = ['radiusTLX', 'radiusBLX'],
        RADIUS_ARRAY_LEFT_Y = ['radiusTLY', 'radiusBLY'],
        RADIUS_ARRAY_RIGHT = ['radiusTRX', 'radiusTRY', 'radiusBRX', 'radiusBRY'],
        RADIUS_ARRAY_RIGHT_X = ['radiusTRX', 'radiusBRX'],
        RADIUS_ARRAY_RIGHT_Y = ['radiusTRY', 'radiusBRY'],
        RADIUS_ARRAY_TOP = ['radiusTLX', 'radiusTLY', 'radiusTRX', 'radiusTRY'],
        RADIUS_ARRAY_TOP_LEFT = ['radiusTLX', 'radiusTLY'],
        RADIUS_ARRAY_TOP_LEFT_X = ['radiusTLX'],
        RADIUS_ARRAY_TOP_LEFT_Y = ['radiusTLY'],
        RADIUS_ARRAY_TOP_RIGHT = ['radiusTRX', 'radiusTRY'],
        RADIUS_ARRAY_TOP_RIGHT_X = ['radiusTRX'],
        RADIUS_ARRAY_TOP_RIGHT_Y = ['radiusTRY'],
        RADIUS_ARRAY_TOP_X = ['radiusTLX', 'radiusTRX'],
        RADIUS_ARRAY_TOP_Y = ['radiusTLY', 'radiusTRY'],
        RADIUS_ARRAY_X = ['radiusTLX', 'radiusTRX', 'radiusBRX', 'radiusBLX'],
        RADIUS_ARRAY_Y = ['radiusTLY', 'radiusTRY', 'radiusBRY', 'radiusBLY'],
        T_RECTANGLE = 'Rectangle';
  • §

    Rectangle constructor

    const Rectangle = function (items = Ωempty) {
    
        this.shapeInit(items);
    
        this.currentRectangleWidth = 1;
        this.currentRectangleHeight = 1;
    
        return this;
    };
  • §

    Rectangle prototype

    const P = Rectangle.prototype = doCreate();
    P.type = T_RECTANGLE;
    P.lib = ENTITY;
    P.isArtefact = true;
    P.isAsset = false;
  • §

    Mixins

    baseMix(P);
    shapeMix(P);
  • §

    Rectangle attributes

    const defaultAttributes = {
    
        rectangleWidth: 10,
        rectangleHeight: 10,
        radiusTLX: 0,
        radiusTLY: 0,
        radiusTRX: 0,
        radiusTRY: 0,
        radiusBRX: 0,
        radiusBRY: 0,
        radiusBLX: 0,
        radiusBLY: 0,
        offshootA: 0.55,
        offshootB: 0,
    };
    P.defs = mergeOver(P.defs, defaultAttributes);
  • §

    Packet management

    No additional packet functionality required

  • §

    Clone management

    No additional clone functionality required

  • §

    Kill management

    No additional kill functionality required

  • §

    Get, Set, deltaSet

    const S = P.setters,
        D = P.deltaSetters;
    
    S.radius = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_ALL);
    };
    S.radiusX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_X);
    };
    S.radiusY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_Y);
    };
    S.radiusT = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP);
    };
    S.radiusB = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM);
    };
    S.radiusL = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_LEFT);
    };
    S.radiusR = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_RIGHT);
    };
    S.radiusTX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP_X);
    };
    S.radiusBX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM_X);
    };
    S.radiusLX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_LEFT_X);
    };
    S.radiusRX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_RIGHT_X);
    };
    S.radiusTY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP_Y);
    };
    S.radiusBY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM_Y);
    };
    S.radiusLY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_LEFT_Y);
    };
    S.radiusRY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_RIGHT_Y);
    };
    S.radiusTL = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP_LEFT);
    };
    S.radiusTR = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP_RIGHT);
    };
    S.radiusBL = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM_LEFT);
    };
    S.radiusBR = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM_RIGHT);
    };
    S.radiusTLX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP_LEFT_X);
    };
    S.radiusTLY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP_LEFT_Y);
    };
    S.radiusTRX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP_RIGHT_X);
    };
    S.radiusTRY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_TOP_RIGHT_Y);
    };
    S.radiusBRX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM_RIGHT_X);
    };
    S.radiusBRY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM_RIGHT_Y);
    };
    S.radiusBLX = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM_LEFT_X);
    };
    S.radiusBLY = function (item) {
    
        this.setRectHelper(item, RADIUS_ARRAY_BOTTOM_LEFT_Y);
    };
    D.radius = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_ALL);
    };
    D.radiusX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_X);
    };
    D.radiusY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_Y);
    };
    D.radiusT = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP);
    };
    D.radiusB = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM);
    };
    D.radiusL = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_LEFT);
    };
    D.radiusR = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_RIGHT);
    };
    D.radiusTX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP_X);
    };
    D.radiusBX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM_X);
    };
    D.radiusLX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_LEFT_X);
    };
    D.radiusRX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_RIGHT_X);
    };
    D.radiusTY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP_Y);
    };
    D.radiusBY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM_Y);
    };
    D.radiusLY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_LEFT_Y);
    };
    D.radiusRY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_RIGHT_Y);
    };
    D.radiusTL = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP_LEFT);
    };
    D.radiusTR = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP_RIGHT);
    };
    D.radiusBL = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM_LEFT);
    };
    D.radiusBR = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM_RIGHT);
    };
    D.radiusTLX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP_LEFT_X);
    };
    D.radiusTLY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP_LEFT_Y);
    };
    D.radiusTRX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP_RIGHT_X);
    };
    D.radiusTRY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_TOP_RIGHT_Y);
    };
    D.radiusBRX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM_RIGHT_X);
    };
    D.radiusBRY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM_RIGHT_Y);
    };
    D.radiusBLX = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM_LEFT_X);
    };
    D.radiusBLY = function (item) {
    
        this.deltaRectHelper(item, RADIUS_ARRAY_BOTTOM_LEFT_Y);
    };
    
    S.offshootA = function (item) {
    
        this.offshootA = item;
        this.updateDirty();
    };
    S.offshootB = function (item) {
    
        this.offshootB = item;
        this.updateDirty();
    };
    D.offshootA = function (item) {
    
        if (item.toFixed) {
    
            this.offshootA += item;
            this.updateDirty();
        }
    };
    D.offshootB = function (item) {
    
        if (item.toFixed) {
    
            this.offshootB += item;
            this.updateDirty();
        }
    };
    
    S.rectangleWidth = function (val) {
    
        if (val != null) {
    
            this.rectangleWidth = val;
            this.dirtyDimensions = true;
            this.dirtyFilterIdentifier = true;
        }
    };
    S.rectangleHeight = function (val) {
    
        if (val != null) {
    
            this.rectangleHeight = val;
            this.dirtyDimensions = true;
            this.dirtyFilterIdentifier = true;
        }
    };
    D.rectangleWidth = function (val) {
    
        this.rectangleWidth = addStrings(this.rectangleWidth, val);
        this.dirtyDimensions = true;
        this.dirtyFilterIdentifier = true;
    };
    D.rectangleHeight = function (val) {
    
        this.rectangleHeight = addStrings(this.rectangleHeight, val);
        this.dirtyDimensions = true;
        this.dirtyFilterIdentifier = true;
    };
  • §

    Prototype functions

  • §

    setRectHelper - internal setter helper function

    P.setRectHelper = function (item, corners) {
    
        this.updateDirty();
    
        corners.forEach(corner => {
    
            this[corner] = item;
        }, this);
    };
  • §

    deltaRectHelper - internal setter helper function

    P.deltaRectHelper = function (item, corners) {
    
        this.updateDirty();
    
        corners.forEach(corner => {
    
            this[corner] = addStrings(this[corner], item);
        }, this);
    };
  • §

    cleanSpecies - internal helper function - called by prepareStamp

    P.cleanSpecies = function () {
    
        this.dirtySpecies = false;
        this.pathDefinition = this.makeRectanglePath();
    };
  • §

    cleanDimensions - internal helper function called by prepareStamp

    • Unlike other Shape entitys, Rectangles have settable dimensions rectangleWidth and rectangleWidth.
    P.cleanDimensions = function () {
    
        this.dirtyDimensions = false;
    
        const host = this.getHost();
    
        if (host) {
    
            const hostDims = (host.currentDimensions) ? host.currentDimensions : [host.w, host.h],
                oldW = this.currentRectangleWidth || 1,
                oldH = this.currentRectangleHeight || 1;
    
            let w = this.rectangleWidth,
                h = this.rectangleHeight;
    
            if (w.substring) w = (parseFloat(w) / 100) * hostDims[0];
    
            if (h.substring) h = (parseFloat(h) / 100) * hostDims[1];
    
            const mimic = this.mimic;
    
            let mimicDims;
    
            if (mimic && mimic.name && this.useMimicDimensions) mimicDims = mimic.currentDimensions;
    
            if (mimicDims) {
    
                this.currentRectangleWidth = (this.addOwnDimensionsToMimic) ? mimicDims[0] + w : mimicDims[0];
                this.currentRectangleHeight = (this.addOwnDimensionsToMimic) ? mimicDims[1] + h : mimicDims[1];
            }
            else {
    
                this.currentRectangleWidth = w;
                this.currentRectangleHeight = h;
            }
    
            this.currentDimensions[0] = this.currentRectangleWidth;
            this.currentDimensions[1] = this.currentRectangleHeight;
    
            this.dirtyStart = true;
            this.dirtyHandle = true;
            this.dirtyOffset = true;
    
            if (oldW !== this.currentRectangleWidth || oldH !== this.currentRectangleHeight) this.dirtyPositionSubscribers = true;
    
            if (this.mimicked && this.mimicked.length) this.dirtyMimicDimensions = true;
        }
        else this.dirtyDimensions = true;
    };
  • §

    makeRectanglePath - internal helper function - called by cleanSpecies

    P.makeRectanglePath = function () {
    
        if (this.dirtyDimensions) this.cleanDimensions()
    
        const width = this.currentRectangleWidth,
            height = this.currentRectangleHeight;
    
        const A = this.offshootA,
            B = this.offshootB;
    
        let _tlx = this.radiusTLX,
            _tly = this.radiusTLY,
            _trx = this.radiusTRX,
            _try = this.radiusTRY,
            _brx = this.radiusBRX,
            _bry = this.radiusBRY,
            _blx = this.radiusBLX,
            _bly = this.radiusBLY;
    
        if (_tlx.substring || _tly.substring || _trx.substring || _try.substring || _brx.substring || _bry.substring || _blx.substring || _bly.substring) {
    
            _tlx = (_tlx.substring) ? (parseFloat(_tlx) / 100) * width : _tlx;
            _tly = (_tly.substring) ? (parseFloat(_tly) / 100) * height : _tly;
            _trx = (_trx.substring) ? (parseFloat(_trx) / 100) * width : _trx;
            _try = (_try.substring) ? (parseFloat(_try) / 100) * height : _try;
            _brx = (_brx.substring) ? (parseFloat(_brx) / 100) * width : _brx;
            _bry = (_bry.substring) ? (parseFloat(_bry) / 100) * height : _bry;
            _blx = (_blx.substring) ? (parseFloat(_blx) / 100) * width : _blx;
            _bly = (_bly.substring) ? (parseFloat(_bly) / 100) * height : _bly;
        }
    
        let myData = ZERO_PATH;
    
        if (width - _tlx - _trx !== 0) myData += `h${width - _tlx - _trx}`;
    
        if (_trx + _try !== 0) myData += `c${_trx * A},${_try * B} ${_trx - (_trx * B)},${_try - (_try * A)}, ${_trx},${_try}`;
    
        if (height - _try - _bry !== 0) myData += `v${height - _try - _bry}`;
    
        if (_brx + _bry !== 0) myData += `c${-_brx * B},${_bry * A} ${-_brx + (_brx * A)},${_bry - (_bry * B)} ${-_brx},${_bry}`;
    
        if (-width + _blx + _brx !== 0) myData += `h${-width + _blx + _brx}`;
    
        if (_blx + _bly !== 0) myData += `c${-_blx * A},${-_bly * B} ${-_blx + (_blx * B)},${-_bly + (_bly * A)} ${-_blx},${-_bly}`;
    
        if (-height + _tly + _bly !== 0) myData += `v${-height + _tly + _bly}`;
    
        if (_tlx + _tly !== 0) myData += `c${_tlx * B},${-_tly * A} ${_tlx - (_tlx * A)},${-_tly + (_tly * B)} ${_tlx},${-_tly}`;
    
        myData += 'z';
    
        return myData;
    };
    
    P.calculateLocalPathAdditionalActions = function () {
    
        let scale = this.scale;
    
        if (scale < 0.001) scale = 0.001;
    
        const [x, y] = this.localBox;
    
        this.pathDefinition = this.pathDefinition.replace(ZERO_PATH, `m${-x / scale},${-y / scale}`);
    
        this.pathCalculatedOnce = false;
  • §

    ALWAYS, when invoking calculateLocalPath from calculateLocalPathAdditionalActions, include the second argument, set to true! Failure to do this leads to an infinite loop which will make your machine weep.

    • We need to recalculate the local path to take into account the offset required to put the Rectangle entity’s start coordinates at the top-left of the local box, and to recalculate the data used by other artefacts to place themselves on, or move along, its path.
        this.calculateLocalPath(this.pathDefinition, true);
    };
  • §

    Factories

  • §
    makeRectangle

    Essentially this Shape looks like a Block with rounded corners

    Rectangle Shapes are unique in that they require width and height dimensions, supplied in the rectangleWidth and rectangleHeight attributes.

    Internally, Scrawl-canvas uses quadratic curves to construct the corners. The bend of these corners is set by the quadratic’s control point which doesn’t have its own coordinate but is rather calculated using two float Number variables: offshootA (default: 0.55) and offshootB (default: 0) - change these values to make the corners more or less bendy.

    Each corner of the rectangle can be rounded using radius values. Like the oval Shape, the corner has both a horizontal x radius and a vertical y radius. Thus to draw a rectangle, we need to supply a total of 8 radius measurements:

    • radiusTLX - the __T__op __L__eft corner’s x radius
    • radiusTLY - the __T__op __L__eft corner’s y radius
    • radiusTRX - the __T__op __R__ight corner’s x radius
    • radiusTRY - the __T__op __R__ight corner’s y radius
    • radiusBRX - the __B__ottom __R__ight corner’s x radius
    • radiusBRY - the __B__ottom __R__ight corner’s y radius
    • radiusBLX - the __B__ottom __L__eft corner’s x radius
    • radiusBLY - the __B__ottom __L__eft corner’s y radius

    For convenience a lot of pseudo-attributes are supplied, which make defining the radius of each corner a bit easier. We achieve this by adding a letter or combination of letters to the word 'radius':

    • radius - all 8 radius values are set to the given distance (measured in px)
    • radiusX - the 4 x radius values
    • radiusY - the 4 y radius values
    • radiusT - the 4 top radius values
    • radiusTX - both x radius values for the top corners
    • radiusTY - both y radius values for the top corners
    • radiusB - the 4 bottom radius values
    • radiusBX - both x radius values for the bottom corners
    • radiusBY - both y radius values for the bottom corners
    • radiusL - the 4 left radius values
    • radiusLX - both x radius values for the left corners
    • radiusLY - both y radius values for the left corners
    • radiusR - the 4 right radius values
    • radiusRX - both x radius values for the right corners
    • radiusRY - both y radius values for the right corners
    • radiusTL - both radius values for the top left corner
    • radiusTR - both radius values for the top right corner
    • radiusBL - both radius values for the bottom left corner
    • radiusBR - both radius values for the bottom right corner
    scrawl.makeRectangle({
    
        name: 'tab',
    
        startX: 20,
        startY: 200,
    
        rectangleWidth: 120,
        rectangleHeight: 80,
    
        radiusT: 20,
        radiusB: 0,
    
        fillStyle: 'lightblue',
        method: 'fillAndDraw',
    });
    
    export const makeRectangle = function (items) {
    
        if (!items) return false;
        items.species = RECTANGLE;
        return new Rectangle(items);
    };
    
    constructors.Rectangle = Rectangle;