Skip to content

Commit

Permalink
2.10.2
Browse files Browse the repository at this point in the history
  • Loading branch information
quinton-ashley committed Nov 23, 2024
1 parent ec62afe commit 902f84f
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 49 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "q5",
"version": "2.10.1",
"version": "2.10.2",
"description": "A sequel to p5.js that's optimized for interactive art",
"author": "quinton-ashley",
"contributors": [
Expand Down
12 changes: 11 additions & 1 deletion q5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,17 @@ function setup() {
* strength of the tint. To change an image's opacity,
* use the `opacity` function.
*
* Tinting affects all subsequent images drawn.
* Tinting affects all subsequent images drawn. The tint
* color is applied to images using the "multiply" blend mode.
*
* Since the tinting process is performance intensive, each time
* an image is tinted, q5 caches the result. `image` will draw the
* cached tinted image unless the tint color has changed or the
* image being tinted was edited.
*
* If you need to draw an image multiple times each frame with
* different tints, consider making copies of the image and tinting
* each copy separately.
* @param {string | number} color - tint color
* @example
createCanvas(200, 200);
Expand Down
55 changes: 32 additions & 23 deletions q5.js
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,10 @@ Q5.renderers.q2d.image = ($, q) => {
}
q._preloadCount++;
let last = [...arguments].at(-1);
opt = typeof last == 'object' ? last : null;
if (typeof last == 'object') {
opt = last;
cb = null;
} else opt = null;

let g = $.createImage(1, 1, opt);
let pd = (g._pixelDensity = opt?.pixelDensity || 1);
Expand Down Expand Up @@ -1358,41 +1361,36 @@ Q5.renderers.q2d.image = ($, q) => {
if (!sh) {
sh = drawable.height || drawable.videoHeight;
} else sh *= pd;
sx *= pd;
sy *= pd;
$.ctx.drawImage(drawable, sx, sy, sw, sh, dx, dy, dw, dh);

if ($._tint) {
$.ctx.save();
if (img._tint != $._tint || img._retint) {
img._tintImg ??= $.createImage(img.w, img.h, { pixelDensity: pd });

$.ctx.shadowOffsetX = 0;
$.ctx.shadowOffsetY = 0;
$.ctx.shadowBlur = 0;

if (img.canvas.alpha) {
img.tintImg ??= $.createImage(img.w, img.h, { pixelDensity: pd });
if (img.tintImg.width != img.width || img.tintImg.height != img.height) {
img.tintImg.resize(img.w, img.h);
if (img._tintImg.width != img.width || img._tintImg.height != img.height) {
img._tintImg.resize(img.w, img.h);
}

let tnt = img.tintImg.ctx;
let tnt = img._tintImg.ctx;
tnt.globalCompositeOperation = 'copy';
tnt.fillStyle = $._tint;
tnt.fillRect(0, 0, img.width, img.height);

tnt.globalCompositeOperation = 'destination-in';
if (img.canvas.alpha) {
tnt.globalCompositeOperation = 'destination-in';
tnt.drawImage(drawable, 0, 0, img.width, img.height);
}

tnt.globalCompositeOperation = 'multiply';
tnt.drawImage(drawable, 0, 0, img.width, img.height);

$.ctx.globalCompositeOperation = 'multiply';
$.ctx.drawImage(img.tintImg.canvas, sx, sy, sw, sh, dx, dy, dw, dh);
} else {
$.ctx.globalCompositeOperation = 'multiply';
$.ctx.fillStyle = $._tint;
$.ctx.fillRect(dx, dy, dw, dh);
img._tint = $._tint;
img._retint = false;
}

$.ctx.restore();
drawable = img._tintImg.canvas;
}

$.ctx.drawImage(drawable, sx * pd, sy * pd, sw, sh, dx, dy, dw, dh);
};

$._tint = null;
Expand Down Expand Up @@ -1420,6 +1418,7 @@ Q5.renderers.q2d.image = ($, q) => {
$.ctx.filter = f;
$.ctx.drawImage($.canvas, 0, 0, $.canvas.w, $.canvas.h);
$.ctx.filter = 'none';
$._retint = true;
};

if ($._scope == 'image') {
Expand All @@ -1436,6 +1435,8 @@ Q5.renderers.q2d.image = ($, q) => {

$.ctx.clearRect(0, 0, c.width, c.height);
$.ctx.drawImage(o, 0, 0, c.width, c.height);

$._retint = true;
};
}

Expand Down Expand Up @@ -1481,11 +1482,15 @@ Q5.renderers.q2d.image = ($, q) => {
$.ctx.drawImage(img.canvas, 0, 0);
$.ctx.globalCompositeOperation = old;
$.ctx.restore();

$._retint = true;
};

$.inset = (x, y, w, h, dx, dy, dw, dh) => {
let pd = $._pixelDensity || 1;
$.ctx.drawImage($.canvas, x * pd, y * pd, w * pd, h * pd, dx, dy, dw, dh);

$._retint = true;
};

$.copy = () => $.get();
Expand Down Expand Up @@ -1513,6 +1518,7 @@ Q5.renderers.q2d.image = ($, q) => {
$.set = (x, y, c) => {
x = Math.floor(x);
y = Math.floor(y);
$._retint = true;
if (c.canvas) {
let old = $._tint;
$._tint = null;
Expand All @@ -1538,7 +1544,10 @@ Q5.renderers.q2d.image = ($, q) => {
q.pixels = imgData.data;
};
$.updatePixels = () => {
if (imgData != null) $.ctx.putImageData(imgData, 0, 0);
if (imgData != null) {
$.ctx.putImageData(imgData, 0, 0);
$._retint = true;
}
};

$.smooth = () => ($.ctx.imageSmoothingEnabled = true);
Expand Down
2 changes: 1 addition & 1 deletion q5.min.js

Large diffs are not rendered by default.

55 changes: 32 additions & 23 deletions src/q5-2d-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ Q5.renderers.q2d.image = ($, q) => {
}
q._preloadCount++;
let last = [...arguments].at(-1);
opt = typeof last == 'object' ? last : null;
if (typeof last == 'object') {
opt = last;
cb = null;
} else opt = null;

let g = $.createImage(1, 1, opt);
let pd = (g._pixelDensity = opt?.pixelDensity || 1);
Expand Down Expand Up @@ -114,41 +117,36 @@ Q5.renderers.q2d.image = ($, q) => {
if (!sh) {
sh = drawable.height || drawable.videoHeight;
} else sh *= pd;
sx *= pd;
sy *= pd;
$.ctx.drawImage(drawable, sx, sy, sw, sh, dx, dy, dw, dh);

if ($._tint) {
$.ctx.save();
if (img._tint != $._tint || img._retint) {
img._tintImg ??= $.createImage(img.w, img.h, { pixelDensity: pd });

$.ctx.shadowOffsetX = 0;
$.ctx.shadowOffsetY = 0;
$.ctx.shadowBlur = 0;

if (img.canvas.alpha) {
img.tintImg ??= $.createImage(img.w, img.h, { pixelDensity: pd });
if (img.tintImg.width != img.width || img.tintImg.height != img.height) {
img.tintImg.resize(img.w, img.h);
if (img._tintImg.width != img.width || img._tintImg.height != img.height) {
img._tintImg.resize(img.w, img.h);
}

let tnt = img.tintImg.ctx;
let tnt = img._tintImg.ctx;
tnt.globalCompositeOperation = 'copy';
tnt.fillStyle = $._tint;
tnt.fillRect(0, 0, img.width, img.height);

tnt.globalCompositeOperation = 'destination-in';
if (img.canvas.alpha) {
tnt.globalCompositeOperation = 'destination-in';
tnt.drawImage(drawable, 0, 0, img.width, img.height);
}

tnt.globalCompositeOperation = 'multiply';
tnt.drawImage(drawable, 0, 0, img.width, img.height);

$.ctx.globalCompositeOperation = 'multiply';
$.ctx.drawImage(img.tintImg.canvas, sx, sy, sw, sh, dx, dy, dw, dh);
} else {
$.ctx.globalCompositeOperation = 'multiply';
$.ctx.fillStyle = $._tint;
$.ctx.fillRect(dx, dy, dw, dh);
img._tint = $._tint;
img._retint = false;
}

$.ctx.restore();
drawable = img._tintImg.canvas;
}

$.ctx.drawImage(drawable, sx * pd, sy * pd, sw, sh, dx, dy, dw, dh);
};

$._tint = null;
Expand Down Expand Up @@ -176,6 +174,7 @@ Q5.renderers.q2d.image = ($, q) => {
$.ctx.filter = f;
$.ctx.drawImage($.canvas, 0, 0, $.canvas.w, $.canvas.h);
$.ctx.filter = 'none';
$._retint = true;
};

if ($._scope == 'image') {
Expand All @@ -192,6 +191,8 @@ Q5.renderers.q2d.image = ($, q) => {

$.ctx.clearRect(0, 0, c.width, c.height);
$.ctx.drawImage(o, 0, 0, c.width, c.height);

$._retint = true;
};
}

Expand Down Expand Up @@ -237,11 +238,15 @@ Q5.renderers.q2d.image = ($, q) => {
$.ctx.drawImage(img.canvas, 0, 0);
$.ctx.globalCompositeOperation = old;
$.ctx.restore();

$._retint = true;
};

$.inset = (x, y, w, h, dx, dy, dw, dh) => {
let pd = $._pixelDensity || 1;
$.ctx.drawImage($.canvas, x * pd, y * pd, w * pd, h * pd, dx, dy, dw, dh);

$._retint = true;
};

$.copy = () => $.get();
Expand Down Expand Up @@ -269,6 +274,7 @@ Q5.renderers.q2d.image = ($, q) => {
$.set = (x, y, c) => {
x = Math.floor(x);
y = Math.floor(y);
$._retint = true;
if (c.canvas) {
let old = $._tint;
$._tint = null;
Expand All @@ -294,7 +300,10 @@ Q5.renderers.q2d.image = ($, q) => {
q.pixels = imgData.data;
};
$.updatePixels = () => {
if (imgData != null) $.ctx.putImageData(imgData, 0, 0);
if (imgData != null) {
$.ctx.putImageData(imgData, 0, 0);
$._retint = true;
}
};

$.smooth = () => ($.ctx.imageSmoothingEnabled = true);
Expand Down

0 comments on commit 902f84f

Please sign in to comment.