opsCanvas

createOpsCanvas

// Creates an opsCanvas

width
number
height
number

createOpsCanvasFromPng

// Creates an opsCanvas from a png

pngPath
string

createOpsCanvasFromSvg

// Creates an opsCanvas from an svg

svgPath
string
sizing?
{
width:number
}
{
height:number
}
"auto"

ioOps

// read and write images

toPngBuffer

// Get png buffer from opsCanvas

Parameters
none
Return

get1bitImageData

Parameters
channel
"r""g""b""a"
threshold?
number
Return

noiseOps

addRandom

Parameters
range
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
options?
{
seed?:string

// default {false}

monochrome?:boolean

// default {"rgb"}

mask?:"r""g""b""a""rgb""rgba"
}
Return
void

mulRandom

Parameters
range
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
options?
{
seed?:string
monochrome?:boolean
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

addNoise

Parameters
range
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
scale
{
value:number
space:absoluterelativeXrelativeYrelativeMinrelativeMax
}
type
"random""value""perlin""openSimplex""worley""worleyDistance""sinX""sinY"
options?
{
seed?:string

// default {true}

monochrome?:boolean

// default {"rgb"}

mask?:"r""g""b""a""rgb""rgba"
}
Return
void

mulNoise

Parameters
range
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
scale
{
value:number
space:absoluterelativeXrelativeYrelativeMinrelativeMax
}
type
"random""value""perlin""openSimplex""worley""worleyDistance""sinX""sinY"
options?
{
seed?:string
monochrome?:boolean

// default {"rgb"}

mask?:"r""g""b""a""rgb""rgba"
}
Return
void

noiseDistort

Parameters
range
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
scale
{
value:number
space:absoluterelativeXrelativeYrelativeMinrelativeMax
}
mask
"r""g""b""a""rgb""rgba"
type
"random""value""perlin""openSimplex""worley""worleyDistance""sinX""sinY"
options?
{
seed?:string
axis?:xyboth
}
Return
void

fillOps

fills

lines

Parameters
options
{
lineWidth:number
angle:\|/-
spacing:number
}
{
color?:string[numbernumbernumbernumber]
invertAlpha?:boolean
repeatType?:"repeat""mirror""clamp"
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

Examples

angles
angles example
Example Code
import { createOpsCanvas, LineFillAngleValues } from "@ops/canvas";

const sizes = [
  { lineWidth: 1, spacing: 20 },
  { lineWidth: 2, spacing: 4 },
  { lineWidth: 20, spacing: 1 },
];

const example = createOpsCanvas(
  2 + LineFillAngleValues.length * 102,
  2 + sizes.length * 102,
);

for (const [i, angle] of Object.entries(LineFillAngleValues)) {
  for (const [y, { lineWidth, spacing }] of Object.entries(sizes)) {
    const test = createOpsCanvas(100, 100);
    test.fills.lines({
      lineWidth,
      angle,
      spacing,
      invertAlpha: false,
      color: "#d45f97",
    });
    example.blend(test, 2 + parseInt(i, 10) * 102, 2 + parseFloat(y) * 102);
  }
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

linesGrid

Parameters
options
{
lineWidth:number
diagonal?:boolean
spacing:number
}
{
color?:string[numbernumbernumbernumber]
invertAlpha?:boolean
repeatType?:"repeat""mirror""clamp"
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

Examples

angles
angles example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const diagonals = [false, true];
const sizes = [
  { lineWidth: 1, spacing: 20 },
  { lineWidth: 2, spacing: 4 },
  { lineWidth: 10, spacing: 1 },
];

const example = createOpsCanvas(
  2 + diagonals.length * 102,
  2 + sizes.length * 102
);

for (const [i, diagonal] of Object.entries(diagonals)) {
  for (const [y, { lineWidth, spacing }] of Object.entries(sizes)) {
    const test = createOpsCanvas(100, 100);
    test.fills.linesGrid({
      lineWidth,
      diagonal,
      spacing,
      invertAlpha: false,
      color: "#d45f97",
    });
    example.blend(test, 2 + parseInt(i, 10) * 102, 2 + parseInt(y, 10) * 102);
  }
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

shapesGrid

Parameters
options
{
spacing:number
shapeSize:number
shape:dotboxdiamond
layout?:squarecirclebrickdiamond
}
{
color?:string[numbernumbernumbernumber]
invertAlpha?:boolean
repeatType?:"repeat""mirror""clamp"
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

Examples

example example
Example Code
import {
  createOpsCanvas,
  FillShapesGridLayoutValues,
  FillShapesGridShapeValues,
} from "@ops/canvas";

const sizes = [
  { shapeSize: 6, spacing: 3 },
  { shapeSize: 20, spacing: 2 },
  { shapeSize: 40, spacing: -2 },
];

const groupWidth = 8 + FillShapesGridShapeValues.length * 102;

const example = createOpsCanvas(
  2 + FillShapesGridLayoutValues.length * groupWidth,
  2 + sizes.length * 102,
);

for (const [layoutsId, layout] of Object.entries(FillShapesGridLayoutValues)) {
  for (const [i, shape] of Object.entries(FillShapesGridShapeValues)) {
    for (const [y, { shapeSize, spacing }] of Object.entries(sizes)) {
      const test = createOpsCanvas(100, 100);
      test.fills.shapesGrid({
        shape,
        shapeSize,
        spacing,
        invertAlpha: false,
        layout,
        color: "#d45f97",
      });
      example.blend(
        test,
        2 + parseInt(layoutsId, 10) * groupWidth + parseInt(i, 10) * 102,
        2 + parseInt(y, 10) * 102,
      );
    }
  }
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

pixelCornerTL

Parameters
options
{
color?:string[numbernumbernumbernumber]
invertAlpha?:boolean
repeatType?:"repeat""mirror""clamp"
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

pixelCornerBR

Parameters
options
{
color?:string[numbernumbernumbernumber]
invertAlpha?:boolean
repeatType?:"repeat""mirror""clamp"
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

cornerBoxes

Parameters
options
{
size?:number
boxSize?:number
}
{
color?:string[numbernumbernumbernumber]
invertAlpha?:boolean
repeatType?:"repeat""mirror""clamp"
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

hex

Parameters
options
{
size:number
lineWidth:number
}
{
color?:string[numbernumbernumbernumber]
invertAlpha?:boolean
repeatType?:"repeat""mirror""clamp"
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

mathOps

set

// set target channels to value

Parameters
value
number
mask
"r""g""b""a""rgb""rgba"
Return
void

clear

// sets selected channels to 0

Parameters
mask?
"r""g""b""a""rgb""rgba"
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(100, 46);

const test = createOpsCanvas(96, 20);
test.gradient(
  [
    {
      step: 0,
      color: "#e5f392ff",
    },
    {
      step: 1,
      color: "#e5f39200",
    },
  ],
  "linear",
  [0.1, 0],
  [0.9, 0],
  { scaleSpace: "relative" },
);

example.blend(test, 2, 2, { mode: "add", showDebugBounds: true });

test.clear();
example.blend(test, 2, 24, { mode: "add", showDebugBounds: true });

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

threshold

// set channels to 0 or 255, check is >= edge

// param {<integer [0-255]>}

Parameters
edge?
number
mask?
"r""g""b""a""rgb""rgba"
Return
void

thresholdBounds

// set target Channels to 255, if src channel value is between min and max, otherwise 0

// param {<integer [0-255]>[inclusive]}

// param {<integer [0-255][inclusive]>}

Parameters
min
number
max
number
src
"r""g""b""a"
target?
"r""g""b""a""rgb""rgba"
Return
void

add

// add value to channels

// param {<integer>}

Parameters
value
number
mask
"r""g""b""a""rgb""rgba"
Return
void

sub

// substract value from channels

// param {<integer>}

Parameters
value
number
mask
"r""g""b""a""rgb""rgba"
Return
void

mul

// multiply values in channels

// param {<float>}

Parameters
value
number
mask
"r""g""b""a""rgb""rgba"
Return
void

div

// divide values in channels

// param {<float>}

Parameters
value
number
mask
"r""g""b""a""rgb""rgba"
Return
void

pow

// raise values in channels to power

// param {<float>}

Parameters
value
number
mask
"r""g""b""a""rgb""rgba"
Return
void

min

// clamps the values to be no bigger than value

// param {<integer>}

Parameters
value
number
mask
"r""g""b""a""rgb""rgba"
Return
void

max

// clamps the values to be no smaller than value

// param {<integer>}

Parameters
value
number
mask
"r""g""b""a""rgb""rgba"
Return
void

clamp

// clamps the values to be larger than min and smaller than max

// param {<integer>}

Parameters
min
number
max
number
mask
"r""g""b""a""rgb""rgba"
Return
void

mapClamped

// maps values from input to output range in channels values outside input range are clamped

Parameters
input
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
output
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
mask
"r""g""b""a""rgb""rgba"
Return
void

map

// maps values from input to output range in channels

Parameters
input
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
output
{
min:number
max:number
}
{

// center

c?:number

// width

w:number
}
mask
"r""g""b""a""rgb""rgba"
Return
void

colorOps

// change and manipulate colors

setColor

// set channels to color with css color string or array of numbers `[0-255, 0-255, 0-255, 0-255]`

Parameters
color
[numbernumbernumbernumber]string
mask?
"r""g""b""a""rgb""rgba"
Return
void

fillBackground

// set channels of transparent pixels to color with css color string or array of numbers `[0-255, 0-255, 0-255, 0-255]`

Parameters
color
[numbernumbernumbernumber]string
options?
{
alphaChannel?:"r""g""b""a"
mask?:"r""g""b""a""rgb""rgba"
}
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(200, 112);

example.drawFillPath(
  (ctx) => {
    ctx.addRect(100, 0, 100, 178);
  },
  { color: "white" }
);

const test = createOpsCanvas(96, 20);
test.gradient(
  [
    {
      step: 0,
      color: "#e5f392ff",
    },
    {
      step: 1,
      color: "#e5f39200",
    },
  ],
  "linear",
  [0.1, 0],
  [0.9, 0],
  { scaleSpace: "relative" }
);

example.blend(test, 2, 2, { mode: "add" });
example.blend(test, 102, 2, { mode: "add" });

for (const [y, data] of Object.entries([
  { color: "#d45f9700" },
  { color: "#d45f9790" },
  { color: "#d45f97cc" },
  { color: "#d45f97" },
])) {
  const filled = test.clone();
  filled.fillBackground(data.color);
  example.blend(filled, 2, 24 + parseInt(y, 10) * 22, {
    mode: "add",
  });
  example.blend(filled, 102, 24 + parseInt(y, 10) * 22, {
    mode: "add",
  });
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

gradient

// set channels to gradient

Parameters
stops
{

// [0..1]

step:number
color:[numbernumbernumbernumber]string
}
[]
type
"linear""radial""angular""box"
start
[numbernumber]
end
[numbernumber]
options?
{
shaper?:number
scaleSpace?:"relative""relativeMin""relativeMax""overflowX""overflowY"
}
Return
void

Examples

shaper
shaper example
Example Code
import { createOpsCanvas, GradientTypeValues } from "@ops/canvas";

const shaperValues = [-1, 0.0, 0.1, 0.5, 1, 2, 4, 8];

const gradientSteps = [
  { step: 0, color: "#e5f392" },
  { step: 0.5, color: "#e49e71" },
  { step: 1, color: "#d45f97" },
];

const example = createOpsCanvas(shaperValues.length * 52 + 2, 200 + 4);

const gradientTest = createOpsCanvas(50, 50);

for (const [x, shaper] of Object.entries(shaperValues)) {
  for (const [y, type] of Object.entries(GradientTypeValues)) {
    gradientTest.gradient(gradientSteps, type, [0.5, 0.5], [0.8, 0.2], {
      shaper,
    });
    example.blend(
      gradientTest,
      2 + parseInt(x, 10) * 52,
      2 + parseInt(y, 10) * 50,
    );
  }
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());
points
points example
Example Code
import { createOpsCanvas, GradientTypeValues } from "@ops/canvas";

const points: [[number, number], [number, number]][] = [
  [
    [0.5, 0.5],
    [0.0, 0],
  ],
  [
    [0.5, 0.5],
    [0.5, 0],
  ],
  [
    [0.5, 0.5],
    [1, 0],
  ],
  [
    [0.5, 0.5],
    [1, 0.5],
  ],
  [
    [0.5, 0.5],
    [1, 1],
  ],
  [
    [0.5, 0.5],
    [0, 1],
  ],
  [
    [0.5, 0.5],
    [0, 0.5],
  ],
  [
    [0.8, 0.1],
    [0.5, 1],
  ],
];
const gradientSteps = [
  { step: 0, color: "#e5f392" },
  { step: 0.5, color: "#e49e71" },
  { step: 1, color: "#d45f97" },
];

const example = createOpsCanvas(points.length * 52 + 2, 200 + 4);

const gradientTest = createOpsCanvas(50, 50);

for (const [x, point] of Object.entries(points)) {
  for (const [y, type] of Object.entries(GradientTypeValues)) {
    gradientTest.gradient(gradientSteps, type, point[0], point[1]);
    example.blend(
      gradientTest,
      2 + parseInt(x, 10) * 52,
      2 + parseInt(y, 10) * 50,
    );
  }
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

gradientRemap

// based on one channel, set the colors with a gradient

Parameters
stops
{

// [0..1]

step:number
color:[numbernumbernumbernumber]string
}
[]
srcChannel
"r""g""b""a""rgb""rgba"
Return
void

blurOps

blur

// Apply a simple blur to the opsCanvas

Parameters
radius
number
mask
"r""g""b""a""rgb""rgba"
Return
void

blurCustom

// Apply a blur with custom weights and offsets to the opsCanvas

Parameters
weights
number[]
offsets
number[]
mask
"r""g""b""a""rgb""rgba"
Return
void

gaussianBlur

// Apply a gaussion blur to the opsCanvas

Parameters
options
{

// default {4}

radius?:number

// default {3}

sigma?:number
mask:"r""g""b""a""rgb""rgba"
}
Return
void

textOps

drawText

Parameters
text
string
options
{
size:number
x:number
y:number
color:[numbernumbernumbernumber]string
mask?:"r""g""b""a""rgb""rgba"
fontFilePath?:string
align?:"left""center""right"
baseline?:"top""middle""bottom"
letterspacing?:number
}
Return
{
textBoxSize:{
width:number
height:number
}
}

Examples

example example
Example Code
import { AlignValues, BaselineValues, createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(
  2 + AlignValues.length * 102,
  2 + BaselineValues.length * 42,
);

for (const [x, align] of Object.entries(AlignValues)) {
  for (const [y, baseline] of Object.entries(BaselineValues)) {
    const test = createOpsCanvas(100, 40);
    const center = [50, 20];

    test.drawFillPath(
      (ctx, { width, height }) => {
        ctx.addRect(0, center[1], width, height);
      },
      { color: "rgba(255, 255, 255, 0.3)" },
    );
    test.drawFillPath(
      (ctx) => {
        ctx.addRect(center[0] - 1, center[1] - 1, 2, 2);
      },
      { color: "white" },
    );
    test.drawText("MOPS", {
      size: 18,
      x: center[0],
      y: center[1],
      color: "#d45f97",
      align,
      baseline,
      mask: "rgba",
    });

    example.blend(test, 2 + parseFloat(x) * 102, 2 + parseFloat(y) * 42);
  }
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

sdfOps

sdf

// generates an sdf with threshold based on single channel you can manipulate the sdf with the callback and its helpers after the callback is run, the values are clamped to [0, 255] and alpha is set to 255

Parameters
threshold
number
srcChannel
"r""g""b""a"
func
(utils:{

// run mod on the sdf

mod:(v:number) => void

// set sdf to remainder with value

rem:(v:number) => void

// set all value signs to positive

abs:() => void
add:(v:number) => void
sub:(v:number) => void
mul:(v:number) => void
div:(v:number) => void

// map range [inMin, inMax] to [outMin, outMax]

map:(inMin:numberinMax:numberoutMin:numberoutMax:number) => void

// map range [inMin, inMax] to [outMin, outMax] remapped values are clamped to range [outMin, outMax]

mapClamped:(inMin:numberinMax:numberoutMin:numberoutMax:number) => void

// clamp larger values to min

min:(v:number) => void

// clamp smaller values to max

max:(v:number) => void
clamp:(min:numbermax:number) => void
equals:(edge:numberyes:numberno:number) => void
isLess:(edge:numberyes:numberno:number) => void
isLessEquals:(edge:numberyes:numberno:number) => void
isGreater:(edge:numberyes:numberno:number) => void
isGreaterEquals:(edge:numberyes:numberno:number) => void

// remap range [inMin, inMax] the values at both inMin and inMax will be outMin the center will be outMax you can shape the parabola with parameter k

parabola:(inMin:numberinMax:numberoutMin:numberoutMax:numberk:number) => void

// at center map value to outMax smoothly blend to outMin at center +- width

cubicPulse:(center:numberwidth:numberoutMin:numberoutMax:number) => void

// get raw integer array of sdf values

getRawValues:() => Int16Array

// edit values with callback

applyCustom:(func:(v:number) => number) => void
}
) => void
Return
void

extrudeColors

Parameters
threshold?
number
undoPremultiply?
boolean
Return
void

vectorOps

// utilizites to render vector graphics

drawStrokePath

Parameters
callback
(ctx:{
moveTo:(x:numbery:number) => void
lineTo:(x:numbery:number) => void
quadCurveTo:(x1:numbery1:numberx:numbery:number) => void
cubicCurveTo:(x1:numbery1:numberx2:numbery2:numberx:numbery:number) => void
close:() => void
addRect:(x:numbery:numberw:numberh:number) => void
addOval:(x:numbery:numberw:numberh:number) => void
addCircle:(x:numbery:numberr:number) => void
}
canvasInfo:{
width:number
height:number
}
) => void
options
{
color:[numbernumbernumbernumber]string

// default {true}

antiAlias?:boolean
transform?:{
type:"translate"
x:number
y:number
}
{
type:"scale"
scale:number
}
{
type:"scaleXY"
x:number
y:number
}
{
type:"rotate"
angle:number
}
{
type:"rotateAround"
angle:number
centerX:number
centerY:number
}
[]
}
{
lineWeight:number
lineCap?:"butt""square""round"
lineJoin?:"round""bevel""miter"
miterLimit?:number
dash?:number[]
dashStartOffset?:number
}
mask?
"r""g""b""a""rgb""rgba"
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(126, 60);
example.drawStrokePath(
  (ctx, { width, height }) => {
    ctx.moveTo(2, 2);
    ctx.lineTo(8, 12);
    ctx.lineTo(2, 58);
    ctx.lineTo(8, 58);
    ctx.lineTo(8, 40);

    ctx.addCircle(40, 30, 24);

    ctx.addRect(74, 4, 20, 50);

    ctx.addOval(102, 4, 20, 50);
  },
  { color: "#e5f392", lineWeight: 4 }
);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

drawFillPath

Parameters
callback
(ctx:{
moveTo:(x:numbery:number) => void
lineTo:(x:numbery:number) => void
quadCurveTo:(x1:numbery1:numberx:numbery:number) => void
cubicCurveTo:(x1:numbery1:numberx2:numbery2:numberx:numbery:number) => void
close:() => void
addRect:(x:numbery:numberw:numberh:number) => void
addOval:(x:numbery:numberw:numberh:number) => void
addCircle:(x:numbery:numberr:number) => void
}
canvasInfo:{
width:number
height:number
}
) => void
options
{
color:[numbernumbernumbernumber]string

// default {true}

antiAlias?:boolean
transform?:{
type:"translate"
x:number
y:number
}
{
type:"scale"
scale:number
}
{
type:"scaleXY"
x:number
y:number
}
{
type:"rotate"
angle:number
}
{
type:"rotateAround"
angle:number
centerX:number
centerY:number
}
[]
}
mask?
"r""g""b""a""rgb""rgba"
Return
void

Examples

mask
mask example
Example Code
import { createOpsCanvas, type Mask } from "@ops/canvas";

const channels: Mask[] = ["r", "g", "b", "a", "rgb", "rgba"];

const example = createOpsCanvas(4 + channels.length * 32, 34);

// draw base grey
// since we're changing single channels later,
// we need to put something into the al[ha channel for them to show up
example.drawFillPath(
  (ctx, { width, height }) => {
    ctx.addRect(0, 0, width, Math.floor(height * 0.5));
  },
  { color: "black" },
);

for (const [index, mask] of Object.entries(channels)) {
  example.drawFillPath(
    (ctx) => {
      ctx.addRect(2 + 32 * parseInt(index, 10), 2, 30, 30);
    },
    { color: "white" },
    mask as Mask,
  );
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());
example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(130, 60);
example.drawFillPath(
  (ctx, { width, height }) => {
    ctx.moveTo(2, 2);
    ctx.lineTo(8, 12);
    ctx.lineTo(2, 58);
    ctx.lineTo(8, 58);
    ctx.lineTo(8, 40);
    ctx.close();

    ctx.addCircle(45, 30, 28);

    ctx.addRect(80, 2, 20, 56);

    ctx.addOval(104, 2, 20, 56);
  },
  { color: "#e5f392" }
);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

drawSvg

Parameters
svg
string
x
number
y
number
size
{
width?:number
height?:number
}
mask?
"r""g""b""a""rgb""rgba"
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(60, 60);
example.drawSvg(
  `
<svg
  viewBox="0 0 300, 300"
  xmlns="http://www.w3.org/2000/svg"
>
  <rect width="100%" height="100%" fill="#d45f97" />
  <circle cx="150" cy="100" r="80" fill="#e5f392" />
</svg>
`,
  2,
  2,
  { width: 56 }
);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

mask

// Mask out parts of the opsCanvas

Parameters
options
{ stroke: PathCallback; } & MaskStrokeOptions | { fill: PathCallback; }{

// default {true}

antiAlias?:boolean
transform?:{
type:"translate"
x:number
y:number
}
{
type:"scale"
scale:number
}
{
type:"scaleXY"
x:number
y:number
}
{
type:"rotate"
angle:number
}
{
type:"rotateAround"
angle:number
centerX:number
centerY:number
}
[]
}
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(104, 54);

const test = createOpsCanvas(50, 50);
test.setColor("#e5f392", "rgba");
example.blend(test, 2, 2);

test.mask({
  fill: (ctx, { width, height }) => {
    ctx.moveTo(width * 0.2, height * 0.2);
    ctx.lineTo(width * 0.8, height * 0.5);
    ctx.lineTo(width * 0.2, height * 0.8);
    ctx.close();
  },
});
example.blend(test, 54, 2);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

utilsOps

swizzle

// draw into the opsCanvas with a provided `CanvasRenderingContext2D`

Parameters
swizzle
string
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(2 + 4 * 52, 54);

const test = createOpsCanvas(50, 50);
test.setColor("#fff392", "rgba");
test.mask({
  fill: (ctx, { width, height }) => {
    ctx.moveTo(0, 0);
    ctx.lineTo(width, height);
    ctx.lineTo(0, height);
  },
});

example.blend(test, 2, 2);

test.swizzle("agbr");
example.blend(test, 54, 2);

test.swizzle("brga");
example.blend(test, 106, 2);

test.swizzle("ggga");
example.blend(test, 158, 2);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

resize

// Change opsCanvas size

Parameters
width
number
height
number
mode
"nearest""linear""cubic""lanczos3"
Return
void

Examples

downscale
downscale example
Example Code
import { createOpsCanvas, FilterModeValues } from "@ops/canvas";

const example = createOpsCanvas(FilterModeValues.length * 104 + 2, 286);

for (const [i, mode] of Object.entries(FilterModeValues)) {
  const index = parseInt(i, 10);

  const test = createOpsCanvas(100, 200);
  test.set(255, "a");

  test.addNoise(
    { min: 0, max: 255 },
    { value: 5.0, space: "relativeMin" },
    "perlin",
    { seed: "a", mask: "rgb" },
  );
  test.gradientRemap(
    [
      { step: 0, color: "#e5f392" },
      { step: 0.5, color: "#e49e71" },
      { step: 1, color: "#d45f97" },
    ],
    "r",
  );
  test.drawStrokePath(
    (ctx, { width, height }) => {
      ctx.addRect(0, 0, width, height);
    },
    { color: "white", lineWeight: 2 },
  );

  example.blend(test, 2 + index * 104, 2);

  test.resize(40, 80, mode);

  example.blend(test, 2 + index * 104, 203);
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());
upscale
upscale example
Example Code
import { createOpsCanvas, FilterModeValues } from "@ops/canvas";

const example = createOpsCanvas(FilterModeValues.length * 104 + 2, 246);

for (const [i, mode] of Object.entries(FilterModeValues)) {
  const index = parseInt(i, 10);

  const test = createOpsCanvas(18, 38);
  test.set(255, "a");

  test.addNoise(
    { min: 0, max: 255 },
    { value: 5.0, space: "relativeMin" },
    "perlin",
    { seed: "a", mask: "rgb" },
  );
  test.gradientRemap(
    [
      { step: 0, color: "#e5f392" },
      { step: 0.5, color: "#e49e71" },
      { step: 1, color: "#d45f97" },
    ],
    "r",
  );
  test.drawStrokePath(
    (ctx, { width, height }) => {
      ctx.addRect(0, 0, width, height);
    },
    { color: "white", lineWeight: 2 },
  );

  example.blend(test, 2 + index * 104, 2);

  test.resize(100, 200, mode);

  example.blend(test, 2 + index * 104, 42);
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

sample

// Get sampled pixel

Parameters
relativeX
number
relativeY
number
result
options?
{
wrapping?:"once""repeat""mirror""clamp"
}
{ filter: Extract<FilterMode, "lanczos3">; lanczosSamplesResolution: { width: number; height: number; }; } | { filter?: Exclude<FilterMode, "lanczos3">; }
Return
void

copyChannelsFromOtherCanvas

// Sample other canvas channel, and set channels to the sampled values

Parameters
otherCanvas
{
imageData:{
height:number
width:number
}
}
srcChannel
"r""g""b""a"
mask
"r""g""b""a""rgb""rgba"
filter?
"nearest""linear""cubic""lanczos3"
Return
void

Examples

example example
Example Code
import { createOpsCanvas, FilterModeValues } from "@ops/canvas";

const example = createOpsCanvas(400, 54);

let x = 2;

const srcCanvas = createOpsCanvas(10, 10);
srcCanvas.setColor("black");
srcCanvas.addNoise(
  { min: 50, max: 255 },
  { value: 5.0, space: "relativeMin" },
  "random",
  { monochrome: true },
);
example.blend(srcCanvas, 2, 2);
x += srcCanvas.getWidth() + 2;

for (const filterMode of FilterModeValues) {
  const targetCanvas = createOpsCanvas(50, 50);
  targetCanvas.setColor("#fff392");
  targetCanvas.copyChannelsFromOtherCanvas(srcCanvas, "r", "a", filterMode);
  example.blend(targetCanvas, x, 2);
  x += targetCanvas.getWidth() + 2;
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

grow

// Grow opsCanvas size

Parameters
width
number
height
number
mode
"once""repeat""mirror""clamp"
options?
{
offsetX?:number
offsetY?:number
}
{
center?:boolean
}
Return
void

Examples

example example
Example Code
import { createOpsCanvas, WrapModeValues } from "@ops/canvas";

const gradientSteps = [
  { step: 0, color: "#e5f392" },
  { step: 0.5, color: "#e49e71" },
  { step: 1, color: "#d45f97" },
];

const example = createOpsCanvas(WrapModeValues.length * 150 + 2, 206);

for (const [i, mode] of Object.entries(WrapModeValues)) {
  const growExample = createOpsCanvas(50, 50);
  growExample.gradient(gradientSteps, "linear", [0, 0], [1, 1]);
  const x = 2 + parseInt(i, 10) * 152;
  example.blend(growExample, x, 2);

  growExample.grow(150, 150, mode);
  example.blend(growExample, x, 54);
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());
offset
offset example
Example Code
import { createOpsCanvas, WrapModeValues } from "@ops/canvas";

const gradientSteps = [
  { step: 0, color: "#e5f392" },
  { step: 0.5, color: "#e49e71" },
  { step: 1, color: "#d45f97" },
];

const example = createOpsCanvas(WrapModeValues.length * 150 + 2, 206);

for (const [i, mode] of Object.entries(WrapModeValues)) {
  const growExample = createOpsCanvas(50, 50);
  growExample.gradient(gradientSteps, "linear", [0, 0], [1, 1]);
  const x = 2 + parseInt(i, 10) * 152;
  example.blend(growExample, x, 2);

  growExample.grow(150, 150, mode, { offsetX: 20, offsetY: -20 });
  example.blend(growExample, x, 54);
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

crop

// Crop opsCanvas

Parameters
options
{
size:number
}
{
width:number
height:number
}
{
x:number
y:number
width:number
height:number
}
{
top:number
left:number
right:number
bottom:number
}
{
top:number
sides:number
bottom:number
}
{
vertical:number
horizontal:number
}
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const gradientSteps = [
  { step: 0, color: "#e5f392" },
  { step: 0.5, color: "#e49e71" },
  { step: 1, color: "#d45f97" },
];

const example = createOpsCanvas(200, 166);

const test = createOpsCanvas(50, 80);
test.gradient(gradientSteps, "linear", [0, 0], [1, 1]);
test.fills.linesGrid({
  spacing: 10,
  lineWidth: 2,
  mask: "r",
  repeatType: "repeat",
  color: "purple",
});

example.blend(test, 2, 2);

let cropped = test.clone();
cropped.crop({ x: 20, y: 40, width: 30, height: 30 });
example.blend(cropped, 2, 90);

cropped = test.clone();
cropped.crop({ top: 10, left: 2, right: 30, bottom: 5 });
example.blend(cropped, 50, 90);

cropped = test.clone();
cropped.crop({ top: 2, sides: 5, bottom: 35 });
example.blend(cropped, 100, 90);

cropped = test.clone();
cropped.crop({ vertical: 5, horizontal: 20 });
example.blend(cropped, 150, 90);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

pad

// Pad opsCanvas

Parameters
options
Size | TopLeftRightBottom | TopSidesBottom | VerticalHorizontal | TargetWidthTargetHeight{ color?: string | RGBA; } | { repeatEdges: true; }
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const gradientSteps = [
  { step: 0, color: "#e5f392" },
  { step: 0.5, color: "#e49e71" },
  { step: 1, color: "#d45f97" },
];

const example = createOpsCanvas(302, 102);

const test = createOpsCanvas(50, 60);
test.gradient(gradientSteps, "linear", [0, 0], [1, 1]);
test.fills.linesGrid({
  spacing: 10,
  lineWidth: 2,
  mask: "r",
  repeatType: "repeat",
  color: "purple",
});

example.blend(test, 2, 2, { showDebugBounds: true });

// default transparend border
{
  const padded = test.clone();
  padded.pad({ top: 20, sides: 10, bottom: 15 });
  example.blend(padded, 60, 2, { showDebugBounds: true });
}

// colored border
{
  const padded = test.clone();
  padded.pad({ top: 20, sides: 10, bottom: 15, color: "red" });
  example.blend(padded, 140, 2, { showDebugBounds: true });
}

// repeat edge colors
{
  const padded = test.clone();
  padded.pad({
    top: 20,
    sides: 10,
    bottom: 15,
    repeatEdges: true,
    color: "red",
  });
  example.blend(padded, 220, 2, { showDebugBounds: true });
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

trim

// Trim surrounding empty space in opsCanvas

Parameters
options?
{

// default {a}

channel?:"r""g""b""a"

// default {127}

threshold?:number

// default {0}

padding?:number

// default {true}

trimX?:boolean

// default {true}

trimY?:boolean
}
Return
void

Examples

trim-x-only
trim-x-only example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(80, 264);

const test = createOpsCanvas(50, 80);
test.drawFillPath(
  (ctx, { width, height }) => {
    ctx.addRect(5, 5, width * 0.5, height * 0.5);
  },
  { color: "#d45f97" }
);
test.fillBackground("#0f0f");

example.blend(test, 2, 2, { mode: "add", showDebugBounds: true });

const trimmed = test.clone();
trimmed.trim({ padding: 0, channel: "r", trimY: false });
example.blend(trimmed, 2, 90, { mode: "add", showDebugBounds: true });

const trimmedPadded = test.clone();
trimmedPadded.trim({ padding: 8, channel: "r", trimY: false });
example.blend(trimmedPadded, 2, 178, { mode: "add", showDebugBounds: true });

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());
trim-y-only
trim-y-only example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(80, 200);

const test = createOpsCanvas(50, 80);
test.drawFillPath(
  (ctx, { width, height }) => {
    ctx.addRect(5, 5, width * 0.5, height * 0.5);
  },
  { color: "#d45f97" }
);
test.fillBackground("#0f0f");

example.blend(test, 2, 2, { mode: "add", showDebugBounds: true });

const trimmed = test.clone();
trimmed.trim({ padding: 0, channel: "r", trimX: false });
example.blend(trimmed, 2, 90, { mode: "add", showDebugBounds: true });

const trimmedPadded = test.clone();
trimmedPadded.trim({ padding: 8, channel: "r", trimX: false });
example.blend(trimmedPadded, 2, 138, { mode: "add", showDebugBounds: true });

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());
example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(80, 200);

const test = createOpsCanvas(50, 80);
test.drawFillPath(
  (ctx, { width, height }) => {
    ctx.addRect(5, 5, width * 0.5, height * 0.5);
  },
  { color: "#d45f97" }
);
test.fillBackground("#0f0f");

example.blend(test, 2, 2, { mode: "add", showDebugBounds: true });

const trimmed = test.clone();
trimmed.trim({ padding: 0, channel: "r" });
example.blend(trimmed, 2, 90, { mode: "add", showDebugBounds: true });

const trimmedPadded = test.clone();
trimmedPadded.trim({ padding: 8, channel: "r" });
example.blend(trimmedPadded, 2, 138, { mode: "add", showDebugBounds: true });

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

blend

// Put another opsCanvas data into this one

Parameters
opsCanvas
{
imageData:{
height:number
width:number
}
}
x
number
y
number
options?
{
mode?:"put""add"
mask?:"r""g""b""a""rgb""rgba"
showDebugBounds?:boolean
}
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const gradientSteps = [
  { step: 0, color: "#e5f392" },
  { step: 0.5, color: "#e49e71" },
  { step: 1, color: "#d45f97" },
];

const example = createOpsCanvas(150, 150);

const otherOpsCanvas = createOpsCanvas(50, 50);
otherOpsCanvas.gradient(gradientSteps, "linear", [0, 0], [1, 1]);
otherOpsCanvas.drawStrokePath(
  (ctx, { width, height }) => {
    ctx.addRect(0, 0, width, height);
  },
  { color: "black", lineWeight: 1 }
);

for (let i = 2; i < 100; i += 8) {
  example.blend(otherOpsCanvas, i, i);
}

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

rotateCW

// Rotate opsCanvas clockwise

Parameters
none
Return
void

rotateCCW

// Rotate opsCanvas counter-clockwise

Parameters
none
Return
void

flipX

// Flip opsCanvas in the x axis

Parameters
none
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(170, 84);

const test = createOpsCanvas(80, 80);
test.setColor("#d45f97");
test.drawText(":)", {
  x: 2,
  y: 2,
  size: 40,
  color: "white",
  align: "left",
  baseline: "top",
});

example.blend(test, 0, 2);

test.flipX();

example.blend(test, 82, 2);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

flipY

// Flip opsCanvas in the y axis

Parameters
none
Return
void

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(170, 84);

const test = createOpsCanvas(80, 80);
test.setColor("#d45f97");
test.drawText(":)", {
  x: 2,
  y: 2,
  size: 40,
  color: "white",
  align: "left",
  baseline: "top",
});

example.blend(test, 0, 2);

test.flipY();

example.blend(test, 82, 2);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());

invert

// Invert colors

Parameters
mask?
"r""g""b""a""rgb""rgba"
Return
void

clone

// Returns a clone of the opsCanvas

Parameters
none
Return
opsCanvas

Examples

example example
Example Code
import { createOpsCanvas } from "@ops/canvas";

const example = createOpsCanvas(158, 54);

const test = createOpsCanvas(50, 50);
test.setColor("#e5f392", "rgba");

example.blend(test, 2, 2);

const clone = test.clone();
test.setColor("#e49e71", "rgba");

// test now has a different color
example.blend(test, 54, 2);

// clone still has original color
example.blend(clone, 106, 2);

Deno.writeFileSync(Deno.args[0], example.toPngBuffer());