diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/index.js b/packages/canvas/canvas-renderer/src/index.js
index 80987c3..71bc5ee 100644
--- a/packages/canvas/canvas-renderer/src/index.js
+++ b/packages/canvas/canvas-renderer/src/index.js
@@ -1,6 +1,6 @@
export * from './CanvasRenderer';
export * from './utils/canUseNewCanvasBlendModes';
-export * from './CanvasTinter';
+export * from './canvasUtils';
import './Renderer';
import './BaseTexture';
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/index.js b/packages/canvas/canvas-renderer/src/index.js
index 80987c3..71bc5ee 100644
--- a/packages/canvas/canvas-renderer/src/index.js
+++ b/packages/canvas/canvas-renderer/src/index.js
@@ -1,6 +1,6 @@
export * from './CanvasRenderer';
export * from './utils/canUseNewCanvasBlendModes';
-export * from './CanvasTinter';
+export * from './canvasUtils';
import './Renderer';
import './BaseTexture';
diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
index 4eac1d7..fd8857f 100644
--- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
+++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
@@ -1,5 +1,5 @@
import { TilingSprite } from '@pixi/sprite-tiling';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { CanvasRenderTarget } from '@pixi/utils';
/**
@@ -40,7 +40,7 @@
// Tint the tiling sprite
if (this.tint !== 0xFFFFFF)
{
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
tempCanvas.context.drawImage(this._tintedCanvas, 0, 0);
}
else
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/index.js b/packages/canvas/canvas-renderer/src/index.js
index 80987c3..71bc5ee 100644
--- a/packages/canvas/canvas-renderer/src/index.js
+++ b/packages/canvas/canvas-renderer/src/index.js
@@ -1,6 +1,6 @@
export * from './CanvasRenderer';
export * from './utils/canUseNewCanvasBlendModes';
-export * from './CanvasTinter';
+export * from './canvasUtils';
import './Renderer';
import './BaseTexture';
diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
index 4eac1d7..fd8857f 100644
--- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
+++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
@@ -1,5 +1,5 @@
import { TilingSprite } from '@pixi/sprite-tiling';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { CanvasRenderTarget } from '@pixi/utils';
/**
@@ -40,7 +40,7 @@
// Tint the tiling sprite
if (this.tint !== 0xFFFFFF)
{
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
tempCanvas.context.drawImage(this._tintedCanvas, 0, 0);
}
else
diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
index 507571c..3cdea2a 100644
--- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
+++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
@@ -1,6 +1,6 @@
import { SCALE_MODES, BLEND_MODES } from '@pixi/constants';
-import { Matrix, GroupD8 } from '@pixi/math';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { Matrix, groupD8 } from '@pixi/math';
+import { canvasUtils } from '@pixi/canvas-renderer';
const canvasRenderWorldTransform = new Matrix();
@@ -96,7 +96,7 @@
{
wt.copyTo(canvasRenderWorldTransform);
wt = canvasRenderWorldTransform;
- GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
+ groupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
// the anchor has already been applied above, so lets set it to zero
dx = 0;
dy = 0;
@@ -155,7 +155,7 @@
sprite._cachedTint = sprite.tint;
// TODO clean up caching - how to clean up the caches?
- sprite._tintedCanvas = CanvasTinter.getTintedCanvas(sprite, sprite.tint);
+ sprite._tintedCanvas = canvasUtils.getTintedCanvas(sprite, sprite.tint);
}
context.drawImage(
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/index.js b/packages/canvas/canvas-renderer/src/index.js
index 80987c3..71bc5ee 100644
--- a/packages/canvas/canvas-renderer/src/index.js
+++ b/packages/canvas/canvas-renderer/src/index.js
@@ -1,6 +1,6 @@
export * from './CanvasRenderer';
export * from './utils/canUseNewCanvasBlendModes';
-export * from './CanvasTinter';
+export * from './canvasUtils';
import './Renderer';
import './BaseTexture';
diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
index 4eac1d7..fd8857f 100644
--- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
+++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
@@ -1,5 +1,5 @@
import { TilingSprite } from '@pixi/sprite-tiling';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { CanvasRenderTarget } from '@pixi/utils';
/**
@@ -40,7 +40,7 @@
// Tint the tiling sprite
if (this.tint !== 0xFFFFFF)
{
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
tempCanvas.context.drawImage(this._tintedCanvas, 0, 0);
}
else
diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
index 507571c..3cdea2a 100644
--- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
+++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
@@ -1,6 +1,6 @@
import { SCALE_MODES, BLEND_MODES } from '@pixi/constants';
-import { Matrix, GroupD8 } from '@pixi/math';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { Matrix, groupD8 } from '@pixi/math';
+import { canvasUtils } from '@pixi/canvas-renderer';
const canvasRenderWorldTransform = new Matrix();
@@ -96,7 +96,7 @@
{
wt.copyTo(canvasRenderWorldTransform);
wt = canvasRenderWorldTransform;
- GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
+ groupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
// the anchor has already been applied above, so lets set it to zero
dx = 0;
dy = 0;
@@ -155,7 +155,7 @@
sprite._cachedTint = sprite.tint;
// TODO clean up caching - how to clean up the caches?
- sprite._tintedCanvas = CanvasTinter.getTintedCanvas(sprite, sprite.tint);
+ sprite._tintedCanvas = canvasUtils.getTintedCanvas(sprite, sprite.tint);
}
context.drawImage(
diff --git a/packages/core/src/textures/Texture.js b/packages/core/src/textures/Texture.js
index ea5c843..107b61e 100644
--- a/packages/core/src/textures/Texture.js
+++ b/packages/core/src/textures/Texture.js
@@ -45,7 +45,7 @@
* @param {PIXI.Rectangle} [frame] - The rectangle frame of the texture to show
* @param {PIXI.Rectangle} [orig] - The area of original texture
* @param {PIXI.Rectangle} [trim] - Trimmed rectangle of original texture
- * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.GroupD8}
+ * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.groupD8}
* @param {PIXI.Point} [anchor] - Default anchor point used for sprite placement / rotation
*/
constructor(baseTexture, frame, orig, trim, rotate, anchor)
@@ -563,7 +563,7 @@
* set to 2 to compensate for texture packer rotation
* set to 6 to compensate for spine packer rotation
* can be used to rotate or mirror sprites
- * See {@link PIXI.GroupD8} for explanation
+ * See {@link PIXI.groupD8} for explanation
*
* @member {number}
*/
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/index.js b/packages/canvas/canvas-renderer/src/index.js
index 80987c3..71bc5ee 100644
--- a/packages/canvas/canvas-renderer/src/index.js
+++ b/packages/canvas/canvas-renderer/src/index.js
@@ -1,6 +1,6 @@
export * from './CanvasRenderer';
export * from './utils/canUseNewCanvasBlendModes';
-export * from './CanvasTinter';
+export * from './canvasUtils';
import './Renderer';
import './BaseTexture';
diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
index 4eac1d7..fd8857f 100644
--- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
+++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
@@ -1,5 +1,5 @@
import { TilingSprite } from '@pixi/sprite-tiling';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { CanvasRenderTarget } from '@pixi/utils';
/**
@@ -40,7 +40,7 @@
// Tint the tiling sprite
if (this.tint !== 0xFFFFFF)
{
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
tempCanvas.context.drawImage(this._tintedCanvas, 0, 0);
}
else
diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
index 507571c..3cdea2a 100644
--- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
+++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
@@ -1,6 +1,6 @@
import { SCALE_MODES, BLEND_MODES } from '@pixi/constants';
-import { Matrix, GroupD8 } from '@pixi/math';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { Matrix, groupD8 } from '@pixi/math';
+import { canvasUtils } from '@pixi/canvas-renderer';
const canvasRenderWorldTransform = new Matrix();
@@ -96,7 +96,7 @@
{
wt.copyTo(canvasRenderWorldTransform);
wt = canvasRenderWorldTransform;
- GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
+ groupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
// the anchor has already been applied above, so lets set it to zero
dx = 0;
dy = 0;
@@ -155,7 +155,7 @@
sprite._cachedTint = sprite.tint;
// TODO clean up caching - how to clean up the caches?
- sprite._tintedCanvas = CanvasTinter.getTintedCanvas(sprite, sprite.tint);
+ sprite._tintedCanvas = canvasUtils.getTintedCanvas(sprite, sprite.tint);
}
context.drawImage(
diff --git a/packages/core/src/textures/Texture.js b/packages/core/src/textures/Texture.js
index ea5c843..107b61e 100644
--- a/packages/core/src/textures/Texture.js
+++ b/packages/core/src/textures/Texture.js
@@ -45,7 +45,7 @@
* @param {PIXI.Rectangle} [frame] - The rectangle frame of the texture to show
* @param {PIXI.Rectangle} [orig] - The area of original texture
* @param {PIXI.Rectangle} [trim] - Trimmed rectangle of original texture
- * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.GroupD8}
+ * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.groupD8}
* @param {PIXI.Point} [anchor] - Default anchor point used for sprite placement / rotation
*/
constructor(baseTexture, frame, orig, trim, rotate, anchor)
@@ -563,7 +563,7 @@
* set to 2 to compensate for texture packer rotation
* set to 6 to compensate for spine packer rotation
* can be used to rotate or mirror sprites
- * See {@link PIXI.GroupD8} for explanation
+ * See {@link PIXI.groupD8} for explanation
*
* @member {number}
*/
diff --git a/packages/core/src/textures/TextureUvs.js b/packages/core/src/textures/TextureUvs.js
index 322e973..735d928 100644
--- a/packages/core/src/textures/TextureUvs.js
+++ b/packages/core/src/textures/TextureUvs.js
@@ -1,4 +1,4 @@
-import { GroupD8 } from '@pixi/math';
+import { groupD8 } from '@pixi/math';
/**
* Stores a texture's frame in UV coordinates, in
@@ -85,7 +85,7 @@
* @protected
* @param {PIXI.Rectangle} frame - The frame of the texture
* @param {PIXI.Rectangle} baseFrame - The base frame of the texture
- * @param {number} rotate - Rotation of frame, see {@link PIXI.GroupD8}
+ * @param {number} rotate - Rotation of frame, see {@link PIXI.groupD8}
*/
set(frame, baseFrame, rotate)
{
@@ -102,21 +102,21 @@
const cX = (frame.x / tw) + w2;
const cY = (frame.y / th) + h2;
- rotate = GroupD8.add(rotate, GroupD8.NW); // NW is top-left corner
- this.x0 = cX + (w2 * GroupD8.uX(rotate));
- this.y0 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, groupD8.NW); // NW is top-left corner
+ this.x0 = cX + (w2 * groupD8.uX(rotate));
+ this.y0 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2); // rotate 90 degrees clockwise
- this.x1 = cX + (w2 * GroupD8.uX(rotate));
- this.y1 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2); // rotate 90 degrees clockwise
+ this.x1 = cX + (w2 * groupD8.uX(rotate));
+ this.y1 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2);
- this.x2 = cX + (w2 * GroupD8.uX(rotate));
- this.y2 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2);
+ this.x2 = cX + (w2 * groupD8.uX(rotate));
+ this.y2 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2);
- this.x3 = cX + (w2 * GroupD8.uX(rotate));
- this.y3 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2);
+ this.x3 = cX + (w2 * groupD8.uX(rotate));
+ this.y3 = cY + (h2 * groupD8.uY(rotate));
}
else
{
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/index.js b/packages/canvas/canvas-renderer/src/index.js
index 80987c3..71bc5ee 100644
--- a/packages/canvas/canvas-renderer/src/index.js
+++ b/packages/canvas/canvas-renderer/src/index.js
@@ -1,6 +1,6 @@
export * from './CanvasRenderer';
export * from './utils/canUseNewCanvasBlendModes';
-export * from './CanvasTinter';
+export * from './canvasUtils';
import './Renderer';
import './BaseTexture';
diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
index 4eac1d7..fd8857f 100644
--- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
+++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
@@ -1,5 +1,5 @@
import { TilingSprite } from '@pixi/sprite-tiling';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { CanvasRenderTarget } from '@pixi/utils';
/**
@@ -40,7 +40,7 @@
// Tint the tiling sprite
if (this.tint !== 0xFFFFFF)
{
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
tempCanvas.context.drawImage(this._tintedCanvas, 0, 0);
}
else
diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
index 507571c..3cdea2a 100644
--- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
+++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
@@ -1,6 +1,6 @@
import { SCALE_MODES, BLEND_MODES } from '@pixi/constants';
-import { Matrix, GroupD8 } from '@pixi/math';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { Matrix, groupD8 } from '@pixi/math';
+import { canvasUtils } from '@pixi/canvas-renderer';
const canvasRenderWorldTransform = new Matrix();
@@ -96,7 +96,7 @@
{
wt.copyTo(canvasRenderWorldTransform);
wt = canvasRenderWorldTransform;
- GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
+ groupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
// the anchor has already been applied above, so lets set it to zero
dx = 0;
dy = 0;
@@ -155,7 +155,7 @@
sprite._cachedTint = sprite.tint;
// TODO clean up caching - how to clean up the caches?
- sprite._tintedCanvas = CanvasTinter.getTintedCanvas(sprite, sprite.tint);
+ sprite._tintedCanvas = canvasUtils.getTintedCanvas(sprite, sprite.tint);
}
context.drawImage(
diff --git a/packages/core/src/textures/Texture.js b/packages/core/src/textures/Texture.js
index ea5c843..107b61e 100644
--- a/packages/core/src/textures/Texture.js
+++ b/packages/core/src/textures/Texture.js
@@ -45,7 +45,7 @@
* @param {PIXI.Rectangle} [frame] - The rectangle frame of the texture to show
* @param {PIXI.Rectangle} [orig] - The area of original texture
* @param {PIXI.Rectangle} [trim] - Trimmed rectangle of original texture
- * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.GroupD8}
+ * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.groupD8}
* @param {PIXI.Point} [anchor] - Default anchor point used for sprite placement / rotation
*/
constructor(baseTexture, frame, orig, trim, rotate, anchor)
@@ -563,7 +563,7 @@
* set to 2 to compensate for texture packer rotation
* set to 6 to compensate for spine packer rotation
* can be used to rotate or mirror sprites
- * See {@link PIXI.GroupD8} for explanation
+ * See {@link PIXI.groupD8} for explanation
*
* @member {number}
*/
diff --git a/packages/core/src/textures/TextureUvs.js b/packages/core/src/textures/TextureUvs.js
index 322e973..735d928 100644
--- a/packages/core/src/textures/TextureUvs.js
+++ b/packages/core/src/textures/TextureUvs.js
@@ -1,4 +1,4 @@
-import { GroupD8 } from '@pixi/math';
+import { groupD8 } from '@pixi/math';
/**
* Stores a texture's frame in UV coordinates, in
@@ -85,7 +85,7 @@
* @protected
* @param {PIXI.Rectangle} frame - The frame of the texture
* @param {PIXI.Rectangle} baseFrame - The base frame of the texture
- * @param {number} rotate - Rotation of frame, see {@link PIXI.GroupD8}
+ * @param {number} rotate - Rotation of frame, see {@link PIXI.groupD8}
*/
set(frame, baseFrame, rotate)
{
@@ -102,21 +102,21 @@
const cX = (frame.x / tw) + w2;
const cY = (frame.y / th) + h2;
- rotate = GroupD8.add(rotate, GroupD8.NW); // NW is top-left corner
- this.x0 = cX + (w2 * GroupD8.uX(rotate));
- this.y0 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, groupD8.NW); // NW is top-left corner
+ this.x0 = cX + (w2 * groupD8.uX(rotate));
+ this.y0 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2); // rotate 90 degrees clockwise
- this.x1 = cX + (w2 * GroupD8.uX(rotate));
- this.y1 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2); // rotate 90 degrees clockwise
+ this.x1 = cX + (w2 * groupD8.uX(rotate));
+ this.y1 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2);
- this.x2 = cX + (w2 * GroupD8.uX(rotate));
- this.y2 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2);
+ this.x2 = cX + (w2 * groupD8.uX(rotate));
+ this.y2 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2);
- this.x3 = cX + (w2 * GroupD8.uX(rotate));
- this.y3 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2);
+ this.x3 = cX + (w2 * groupD8.uX(rotate));
+ this.y3 = cY + (h2 * groupD8.uY(rotate));
}
else
{
diff --git a/packages/math/src/GroupD8.js b/packages/math/src/GroupD8.js
deleted file mode 100644
index 513cea8..0000000
--- a/packages/math/src/GroupD8.js
+++ /dev/null
@@ -1,403 +0,0 @@
-// Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group
-//
-// This file implements the dihedral group of order 16, also called
-// of degree 8. That's why its called GroupD8.
-
-import { Matrix } from './Matrix';
-
-/*
- * Transform matrix for operation n is:
- * | ux | vx |
- * | uy | vy |
- */
-
-const ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1];
-const uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1];
-const vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1];
-const vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1];
-
-/**
- * [Cayley Table]{@link https://en.wikipedia.org/wiki/Cayley_table}
- * for the composition of each rotation in the dihederal group D8.
- *
- * @type number[][]
- * @private
- */
-const rotationCayley = [];
-
-/**
- * Matrices for each `GD8Symmetry` rotation.
- *
- * @type Matrix[]
- * @private
- */
-const rotationMatrices = [];
-
-/*
- * Alias for {@code Math.sign}.
- */
-const signum = Math.sign;
-
-/*
- * Initializes `rotationCayley` and `rotationMatrices`. It is called
- * only once below.
- */
-function init()
-{
- for (let i = 0; i < 16; i++)
- {
- const row = [];
-
- rotationCayley.push(row);
-
- for (let j = 0; j < 16; j++)
- {
- /* Multiplies rotation matrices i and j. */
- const _ux = signum((ux[i] * ux[j]) + (vx[i] * uy[j]));
- const _uy = signum((uy[i] * ux[j]) + (vy[i] * uy[j]));
- const _vx = signum((ux[i] * vx[j]) + (vx[i] * vy[j]));
- const _vy = signum((uy[i] * vx[j]) + (vy[i] * vy[j]));
-
- /* Finds rotation matrix matching the product and pushes it. */
- for (let k = 0; k < 16; k++)
- {
- if (ux[k] === _ux && uy[k] === _uy
- && vx[k] === _vx && vy[k] === _vy)
- {
- row.push(k);
- break;
- }
- }
- }
- }
-
- for (let i = 0; i < 16; i++)
- {
- const mat = new Matrix();
-
- mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0);
- rotationMatrices.push(mat);
- }
-}
-
-init();
-
-/**
- * @memberof PIXI
- * @typedef {number} GD8Symmetry
- * @see PIXI.GroupD8
- */
-
-/**
- * Implements the dihedral group D8, which is similar to
- * [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html};
- * D8 is the same but with diagonals, and it is used for texture
- * rotations.
- *
- * The directions the U- and V- axes after rotation
- * of an angle of `a: GD8Constant` are the vectors `(uX(a), uY(a))`
- * and `(vX(a), vY(a))`. These aren't necessarily unit vectors.
- *
- * **Origin:**
- * This is the small part of gameofbombs.com portal system. It works.
- *
- * @see PIXI.GroupD8.E
- * @see PIXI.GroupD8.SE
- * @see PIXI.GroupD8.S
- * @see PIXI.GroupD8.SW
- * @see PIXI.GroupD8.W
- * @see PIXI.GroupD8.NW
- * @see PIXI.GroupD8.N
- * @see PIXI.GroupD8.NE
- * @author Ivan @ivanpopelyshev
- * @namespace PIXI.GroupD8
- * @memberof PIXI
- */
-export const GroupD8 = {
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 0° | East |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- E: 0,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 45°↻ | Southeast |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- SE: 1,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 90°↻ | South |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- S: 2,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 135°↻ | Southwest |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- SW: 3,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 180° | West |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- W: 4,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -135°/225°↻ | Northwest |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- NW: 5,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -90°/270°↻ | North |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- N: 6,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -45°/315°↻ | Northeast |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- NE: 7,
-
- /**
- * Reflection about Y-axis.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MIRROR_VERTICAL: 8,
-
- /**
- * Reflection about the main diagonal.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MAIN_DIAGONAL: 10,
-
- /**
- * Reflection about X-axis.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MIRROR_HORIZONTAL: 12,
-
- /**
- * Reflection about reverse diagonal.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- REVERSE_DIAGONAL: 14,
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The X-component of the U-axis
- * after rotating the axes.
- */
- uX: (ind) => ux[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The Y-component of the U-axis
- * after rotating the axes.
- */
- uY: (ind) => uy[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The X-component of the V-axis
- * after rotating the axes.
- */
- vX: (ind) => vx[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The Y-component of the V-axis
- * after rotating the axes.
- */
- vY: (ind) => vy[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotation - symmetry whose opposite
- * is needed. Only rotations have opposite symmetries while
- * reflections don't.
- * @return {PIXI.GD8Symmetry} The opposite symmetry of `rotation`
- */
- inv: (rotation) =>
- {
- if (rotation & 8)// true only if between 8 & 15 (reflections)
- {
- return rotation & 15;// or rotation % 16
- }
-
- return (-rotation) & 7;// or (8 - rotation) % 8
- },
-
- /**
- * Composes the two D8 operations.
- *
- * Taking `^` as reflection:
- *
- * | | E=0 | S=2 | W=4 | N=6 | E^=8 | S^=10 | W^=12 | N^=14 |
- * |-------|-----|-----|-----|-----|------|-------|-------|-------|
- * | E=0 | E | S | W | N | E^ | S^ | W^ | N^ |
- * | S=2 | S | W | N | E | S^ | W^ | N^ | E^ |
- * | W=4 | W | N | E | S | W^ | N^ | E^ | S^ |
- * | N=6 | N | E | S | W | N^ | E^ | S^ | W^ |
- * | E^=8 | E^ | N^ | W^ | S^ | E | N | W | S |
- * | S^=10 | S^ | E^ | N^ | W^ | S | E | N | W |
- * | W^=12 | W^ | S^ | E^ | N^ | W | S | E | N |
- * | N^=14 | N^ | W^ | S^ | E^ | N | W | S | E |
- *
- * [This is a Cayley table]{@link https://en.wikipedia.org/wiki/Cayley_table}
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotationSecond - Second operation, which
- * is the row in the above cayley table.
- * @param {PIXI.GD8Symmetry} rotationFirst - First operation, which
- * is the column in the above cayley table.
- * @return {PIXI.GD8Symmetry} Composed operation
- */
- add: (rotationSecond, rotationFirst) => (
- rotationCayley[rotationSecond][rotationFirst]
- ),
-
- /**
- * Reverse of `add`.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotationSecond - Second operation
- * @param {PIXI.GD8Symmetry} rotationFirst - First operation
- * @return {PIXI.GD8Symmetry} Result
- */
- sub: (rotationSecond, rotationFirst) => (
- rotationCayley[rotationSecond][GroupD8.inv(rotationFirst)]
- ),
-
- /**
- * Adds 180 degrees to rotation, which is a commutative
- * operation.
- *
- * @memberof PIXI.GroupD8
- * @param {number} rotation - The number to rotate.
- * @returns {number} Rotated number
- */
- rotate180: (rotation) => rotation ^ 4,
-
- /**
- * Checks if the rotation angle is vertical, i.e. south
- * or north. It doesn't work for reflections.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotation - The number to check.
- * @returns {boolean} Whether or not the direction is vertical
- */
- isVertical: (rotation) => (rotation & 3) === 2, // rotation % 4 === 2
-
- /**
- * Approximates the vector `V(dx,dy)` into one of the
- * eight directions provided by `GroupD8`.
- *
- * @memberof PIXI.GroupD8
- * @param {number} dx - X-component of the vector
- * @param {number} dy - Y-component of the vector
- * @return {PIXI.GD8Symmetry} Approximation of the vector into
- * one of the eight symmetries.
- */
- byDirection: (dx, dy) =>
- {
- if (Math.abs(dx) * 2 <= Math.abs(dy))
- {
- if (dy >= 0)
- {
- return GroupD8.S;
- }
-
- return GroupD8.N;
- }
- else if (Math.abs(dy) * 2 <= Math.abs(dx))
- {
- if (dx > 0)
- {
- return GroupD8.E;
- }
-
- return GroupD8.W;
- }
- else if (dy > 0)
- {
- if (dx > 0)
- {
- return GroupD8.SE;
- }
-
- return GroupD8.SW;
- }
- else if (dx > 0)
- {
- return GroupD8.NE;
- }
-
- return GroupD8.NW;
- },
-
- /**
- * Helps sprite to compensate texture packer rotation.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.Matrix} matrix - sprite world matrix
- * @param {PIXI.GD8Symmetry} rotation - The rotation factor to use.
- * @param {number} tx - sprite anchoring
- * @param {number} ty - sprite anchoring
- */
- matrixAppendRotationInv: (matrix, rotation, tx = 0, ty = 0) =>
- {
- // Packer used "rotation", we use "inv(rotation)"
- const mat = rotationMatrices[GroupD8.inv(rotation)];
-
- mat.tx = tx;
- mat.ty = ty;
- matrix.append(mat);
- },
-};
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/index.js b/packages/canvas/canvas-renderer/src/index.js
index 80987c3..71bc5ee 100644
--- a/packages/canvas/canvas-renderer/src/index.js
+++ b/packages/canvas/canvas-renderer/src/index.js
@@ -1,6 +1,6 @@
export * from './CanvasRenderer';
export * from './utils/canUseNewCanvasBlendModes';
-export * from './CanvasTinter';
+export * from './canvasUtils';
import './Renderer';
import './BaseTexture';
diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
index 4eac1d7..fd8857f 100644
--- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
+++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
@@ -1,5 +1,5 @@
import { TilingSprite } from '@pixi/sprite-tiling';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { CanvasRenderTarget } from '@pixi/utils';
/**
@@ -40,7 +40,7 @@
// Tint the tiling sprite
if (this.tint !== 0xFFFFFF)
{
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
tempCanvas.context.drawImage(this._tintedCanvas, 0, 0);
}
else
diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
index 507571c..3cdea2a 100644
--- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
+++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
@@ -1,6 +1,6 @@
import { SCALE_MODES, BLEND_MODES } from '@pixi/constants';
-import { Matrix, GroupD8 } from '@pixi/math';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { Matrix, groupD8 } from '@pixi/math';
+import { canvasUtils } from '@pixi/canvas-renderer';
const canvasRenderWorldTransform = new Matrix();
@@ -96,7 +96,7 @@
{
wt.copyTo(canvasRenderWorldTransform);
wt = canvasRenderWorldTransform;
- GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
+ groupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
// the anchor has already been applied above, so lets set it to zero
dx = 0;
dy = 0;
@@ -155,7 +155,7 @@
sprite._cachedTint = sprite.tint;
// TODO clean up caching - how to clean up the caches?
- sprite._tintedCanvas = CanvasTinter.getTintedCanvas(sprite, sprite.tint);
+ sprite._tintedCanvas = canvasUtils.getTintedCanvas(sprite, sprite.tint);
}
context.drawImage(
diff --git a/packages/core/src/textures/Texture.js b/packages/core/src/textures/Texture.js
index ea5c843..107b61e 100644
--- a/packages/core/src/textures/Texture.js
+++ b/packages/core/src/textures/Texture.js
@@ -45,7 +45,7 @@
* @param {PIXI.Rectangle} [frame] - The rectangle frame of the texture to show
* @param {PIXI.Rectangle} [orig] - The area of original texture
* @param {PIXI.Rectangle} [trim] - Trimmed rectangle of original texture
- * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.GroupD8}
+ * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.groupD8}
* @param {PIXI.Point} [anchor] - Default anchor point used for sprite placement / rotation
*/
constructor(baseTexture, frame, orig, trim, rotate, anchor)
@@ -563,7 +563,7 @@
* set to 2 to compensate for texture packer rotation
* set to 6 to compensate for spine packer rotation
* can be used to rotate or mirror sprites
- * See {@link PIXI.GroupD8} for explanation
+ * See {@link PIXI.groupD8} for explanation
*
* @member {number}
*/
diff --git a/packages/core/src/textures/TextureUvs.js b/packages/core/src/textures/TextureUvs.js
index 322e973..735d928 100644
--- a/packages/core/src/textures/TextureUvs.js
+++ b/packages/core/src/textures/TextureUvs.js
@@ -1,4 +1,4 @@
-import { GroupD8 } from '@pixi/math';
+import { groupD8 } from '@pixi/math';
/**
* Stores a texture's frame in UV coordinates, in
@@ -85,7 +85,7 @@
* @protected
* @param {PIXI.Rectangle} frame - The frame of the texture
* @param {PIXI.Rectangle} baseFrame - The base frame of the texture
- * @param {number} rotate - Rotation of frame, see {@link PIXI.GroupD8}
+ * @param {number} rotate - Rotation of frame, see {@link PIXI.groupD8}
*/
set(frame, baseFrame, rotate)
{
@@ -102,21 +102,21 @@
const cX = (frame.x / tw) + w2;
const cY = (frame.y / th) + h2;
- rotate = GroupD8.add(rotate, GroupD8.NW); // NW is top-left corner
- this.x0 = cX + (w2 * GroupD8.uX(rotate));
- this.y0 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, groupD8.NW); // NW is top-left corner
+ this.x0 = cX + (w2 * groupD8.uX(rotate));
+ this.y0 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2); // rotate 90 degrees clockwise
- this.x1 = cX + (w2 * GroupD8.uX(rotate));
- this.y1 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2); // rotate 90 degrees clockwise
+ this.x1 = cX + (w2 * groupD8.uX(rotate));
+ this.y1 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2);
- this.x2 = cX + (w2 * GroupD8.uX(rotate));
- this.y2 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2);
+ this.x2 = cX + (w2 * groupD8.uX(rotate));
+ this.y2 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2);
- this.x3 = cX + (w2 * GroupD8.uX(rotate));
- this.y3 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2);
+ this.x3 = cX + (w2 * groupD8.uX(rotate));
+ this.y3 = cY + (h2 * groupD8.uY(rotate));
}
else
{
diff --git a/packages/math/src/GroupD8.js b/packages/math/src/GroupD8.js
deleted file mode 100644
index 513cea8..0000000
--- a/packages/math/src/GroupD8.js
+++ /dev/null
@@ -1,403 +0,0 @@
-// Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group
-//
-// This file implements the dihedral group of order 16, also called
-// of degree 8. That's why its called GroupD8.
-
-import { Matrix } from './Matrix';
-
-/*
- * Transform matrix for operation n is:
- * | ux | vx |
- * | uy | vy |
- */
-
-const ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1];
-const uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1];
-const vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1];
-const vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1];
-
-/**
- * [Cayley Table]{@link https://en.wikipedia.org/wiki/Cayley_table}
- * for the composition of each rotation in the dihederal group D8.
- *
- * @type number[][]
- * @private
- */
-const rotationCayley = [];
-
-/**
- * Matrices for each `GD8Symmetry` rotation.
- *
- * @type Matrix[]
- * @private
- */
-const rotationMatrices = [];
-
-/*
- * Alias for {@code Math.sign}.
- */
-const signum = Math.sign;
-
-/*
- * Initializes `rotationCayley` and `rotationMatrices`. It is called
- * only once below.
- */
-function init()
-{
- for (let i = 0; i < 16; i++)
- {
- const row = [];
-
- rotationCayley.push(row);
-
- for (let j = 0; j < 16; j++)
- {
- /* Multiplies rotation matrices i and j. */
- const _ux = signum((ux[i] * ux[j]) + (vx[i] * uy[j]));
- const _uy = signum((uy[i] * ux[j]) + (vy[i] * uy[j]));
- const _vx = signum((ux[i] * vx[j]) + (vx[i] * vy[j]));
- const _vy = signum((uy[i] * vx[j]) + (vy[i] * vy[j]));
-
- /* Finds rotation matrix matching the product and pushes it. */
- for (let k = 0; k < 16; k++)
- {
- if (ux[k] === _ux && uy[k] === _uy
- && vx[k] === _vx && vy[k] === _vy)
- {
- row.push(k);
- break;
- }
- }
- }
- }
-
- for (let i = 0; i < 16; i++)
- {
- const mat = new Matrix();
-
- mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0);
- rotationMatrices.push(mat);
- }
-}
-
-init();
-
-/**
- * @memberof PIXI
- * @typedef {number} GD8Symmetry
- * @see PIXI.GroupD8
- */
-
-/**
- * Implements the dihedral group D8, which is similar to
- * [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html};
- * D8 is the same but with diagonals, and it is used for texture
- * rotations.
- *
- * The directions the U- and V- axes after rotation
- * of an angle of `a: GD8Constant` are the vectors `(uX(a), uY(a))`
- * and `(vX(a), vY(a))`. These aren't necessarily unit vectors.
- *
- * **Origin:**
- * This is the small part of gameofbombs.com portal system. It works.
- *
- * @see PIXI.GroupD8.E
- * @see PIXI.GroupD8.SE
- * @see PIXI.GroupD8.S
- * @see PIXI.GroupD8.SW
- * @see PIXI.GroupD8.W
- * @see PIXI.GroupD8.NW
- * @see PIXI.GroupD8.N
- * @see PIXI.GroupD8.NE
- * @author Ivan @ivanpopelyshev
- * @namespace PIXI.GroupD8
- * @memberof PIXI
- */
-export const GroupD8 = {
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 0° | East |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- E: 0,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 45°↻ | Southeast |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- SE: 1,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 90°↻ | South |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- S: 2,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 135°↻ | Southwest |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- SW: 3,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 180° | West |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- W: 4,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -135°/225°↻ | Northwest |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- NW: 5,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -90°/270°↻ | North |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- N: 6,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -45°/315°↻ | Northeast |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- NE: 7,
-
- /**
- * Reflection about Y-axis.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MIRROR_VERTICAL: 8,
-
- /**
- * Reflection about the main diagonal.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MAIN_DIAGONAL: 10,
-
- /**
- * Reflection about X-axis.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MIRROR_HORIZONTAL: 12,
-
- /**
- * Reflection about reverse diagonal.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- REVERSE_DIAGONAL: 14,
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The X-component of the U-axis
- * after rotating the axes.
- */
- uX: (ind) => ux[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The Y-component of the U-axis
- * after rotating the axes.
- */
- uY: (ind) => uy[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The X-component of the V-axis
- * after rotating the axes.
- */
- vX: (ind) => vx[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The Y-component of the V-axis
- * after rotating the axes.
- */
- vY: (ind) => vy[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotation - symmetry whose opposite
- * is needed. Only rotations have opposite symmetries while
- * reflections don't.
- * @return {PIXI.GD8Symmetry} The opposite symmetry of `rotation`
- */
- inv: (rotation) =>
- {
- if (rotation & 8)// true only if between 8 & 15 (reflections)
- {
- return rotation & 15;// or rotation % 16
- }
-
- return (-rotation) & 7;// or (8 - rotation) % 8
- },
-
- /**
- * Composes the two D8 operations.
- *
- * Taking `^` as reflection:
- *
- * | | E=0 | S=2 | W=4 | N=6 | E^=8 | S^=10 | W^=12 | N^=14 |
- * |-------|-----|-----|-----|-----|------|-------|-------|-------|
- * | E=0 | E | S | W | N | E^ | S^ | W^ | N^ |
- * | S=2 | S | W | N | E | S^ | W^ | N^ | E^ |
- * | W=4 | W | N | E | S | W^ | N^ | E^ | S^ |
- * | N=6 | N | E | S | W | N^ | E^ | S^ | W^ |
- * | E^=8 | E^ | N^ | W^ | S^ | E | N | W | S |
- * | S^=10 | S^ | E^ | N^ | W^ | S | E | N | W |
- * | W^=12 | W^ | S^ | E^ | N^ | W | S | E | N |
- * | N^=14 | N^ | W^ | S^ | E^ | N | W | S | E |
- *
- * [This is a Cayley table]{@link https://en.wikipedia.org/wiki/Cayley_table}
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotationSecond - Second operation, which
- * is the row in the above cayley table.
- * @param {PIXI.GD8Symmetry} rotationFirst - First operation, which
- * is the column in the above cayley table.
- * @return {PIXI.GD8Symmetry} Composed operation
- */
- add: (rotationSecond, rotationFirst) => (
- rotationCayley[rotationSecond][rotationFirst]
- ),
-
- /**
- * Reverse of `add`.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotationSecond - Second operation
- * @param {PIXI.GD8Symmetry} rotationFirst - First operation
- * @return {PIXI.GD8Symmetry} Result
- */
- sub: (rotationSecond, rotationFirst) => (
- rotationCayley[rotationSecond][GroupD8.inv(rotationFirst)]
- ),
-
- /**
- * Adds 180 degrees to rotation, which is a commutative
- * operation.
- *
- * @memberof PIXI.GroupD8
- * @param {number} rotation - The number to rotate.
- * @returns {number} Rotated number
- */
- rotate180: (rotation) => rotation ^ 4,
-
- /**
- * Checks if the rotation angle is vertical, i.e. south
- * or north. It doesn't work for reflections.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotation - The number to check.
- * @returns {boolean} Whether or not the direction is vertical
- */
- isVertical: (rotation) => (rotation & 3) === 2, // rotation % 4 === 2
-
- /**
- * Approximates the vector `V(dx,dy)` into one of the
- * eight directions provided by `GroupD8`.
- *
- * @memberof PIXI.GroupD8
- * @param {number} dx - X-component of the vector
- * @param {number} dy - Y-component of the vector
- * @return {PIXI.GD8Symmetry} Approximation of the vector into
- * one of the eight symmetries.
- */
- byDirection: (dx, dy) =>
- {
- if (Math.abs(dx) * 2 <= Math.abs(dy))
- {
- if (dy >= 0)
- {
- return GroupD8.S;
- }
-
- return GroupD8.N;
- }
- else if (Math.abs(dy) * 2 <= Math.abs(dx))
- {
- if (dx > 0)
- {
- return GroupD8.E;
- }
-
- return GroupD8.W;
- }
- else if (dy > 0)
- {
- if (dx > 0)
- {
- return GroupD8.SE;
- }
-
- return GroupD8.SW;
- }
- else if (dx > 0)
- {
- return GroupD8.NE;
- }
-
- return GroupD8.NW;
- },
-
- /**
- * Helps sprite to compensate texture packer rotation.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.Matrix} matrix - sprite world matrix
- * @param {PIXI.GD8Symmetry} rotation - The rotation factor to use.
- * @param {number} tx - sprite anchoring
- * @param {number} ty - sprite anchoring
- */
- matrixAppendRotationInv: (matrix, rotation, tx = 0, ty = 0) =>
- {
- // Packer used "rotation", we use "inv(rotation)"
- const mat = rotationMatrices[GroupD8.inv(rotation)];
-
- mat.tx = tx;
- mat.ty = ty;
- matrix.append(mat);
- },
-};
diff --git a/packages/math/src/groupD8.js b/packages/math/src/groupD8.js
new file mode 100644
index 0000000..8b9f542
--- /dev/null
+++ b/packages/math/src/groupD8.js
@@ -0,0 +1,403 @@
+// Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group
+//
+// This file implements the dihedral group of order 16, also called
+// of degree 8. That's why its called groupD8.
+
+import { Matrix } from './Matrix';
+
+/*
+ * Transform matrix for operation n is:
+ * | ux | vx |
+ * | uy | vy |
+ */
+
+const ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1];
+const uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1];
+const vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1];
+const vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1];
+
+/**
+ * [Cayley Table]{@link https://en.wikipedia.org/wiki/Cayley_table}
+ * for the composition of each rotation in the dihederal group D8.
+ *
+ * @type number[][]
+ * @private
+ */
+const rotationCayley = [];
+
+/**
+ * Matrices for each `GD8Symmetry` rotation.
+ *
+ * @type Matrix[]
+ * @private
+ */
+const rotationMatrices = [];
+
+/*
+ * Alias for {@code Math.sign}.
+ */
+const signum = Math.sign;
+
+/*
+ * Initializes `rotationCayley` and `rotationMatrices`. It is called
+ * only once below.
+ */
+function init()
+{
+ for (let i = 0; i < 16; i++)
+ {
+ const row = [];
+
+ rotationCayley.push(row);
+
+ for (let j = 0; j < 16; j++)
+ {
+ /* Multiplies rotation matrices i and j. */
+ const _ux = signum((ux[i] * ux[j]) + (vx[i] * uy[j]));
+ const _uy = signum((uy[i] * ux[j]) + (vy[i] * uy[j]));
+ const _vx = signum((ux[i] * vx[j]) + (vx[i] * vy[j]));
+ const _vy = signum((uy[i] * vx[j]) + (vy[i] * vy[j]));
+
+ /* Finds rotation matrix matching the product and pushes it. */
+ for (let k = 0; k < 16; k++)
+ {
+ if (ux[k] === _ux && uy[k] === _uy
+ && vx[k] === _vx && vy[k] === _vy)
+ {
+ row.push(k);
+ break;
+ }
+ }
+ }
+ }
+
+ for (let i = 0; i < 16; i++)
+ {
+ const mat = new Matrix();
+
+ mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0);
+ rotationMatrices.push(mat);
+ }
+}
+
+init();
+
+/**
+ * @memberof PIXI
+ * @typedef {number} GD8Symmetry
+ * @see PIXI.groupD8
+ */
+
+/**
+ * Implements the dihedral group D8, which is similar to
+ * [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html};
+ * D8 is the same but with diagonals, and it is used for texture
+ * rotations.
+ *
+ * The directions the U- and V- axes after rotation
+ * of an angle of `a: GD8Constant` are the vectors `(uX(a), uY(a))`
+ * and `(vX(a), vY(a))`. These aren't necessarily unit vectors.
+ *
+ * **Origin:**
+ * This is the small part of gameofbombs.com portal system. It works.
+ *
+ * @see PIXI.groupD8.E
+ * @see PIXI.groupD8.SE
+ * @see PIXI.groupD8.S
+ * @see PIXI.groupD8.SW
+ * @see PIXI.groupD8.W
+ * @see PIXI.groupD8.NW
+ * @see PIXI.groupD8.N
+ * @see PIXI.groupD8.NE
+ * @author Ivan @ivanpopelyshev
+ * @namespace PIXI.groupD8
+ * @memberof PIXI
+ */
+export const groupD8 = {
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 0° | East |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ E: 0,
+
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 45°↻ | Southeast |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ SE: 1,
+
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 90°↻ | South |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ S: 2,
+
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 135°↻ | Southwest |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ SW: 3,
+
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 180° | West |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ W: 4,
+
+ /**
+ * | Rotation | Direction |
+ * |-------------|--------------|
+ * | -135°/225°↻ | Northwest |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ NW: 5,
+
+ /**
+ * | Rotation | Direction |
+ * |-------------|--------------|
+ * | -90°/270°↻ | North |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ N: 6,
+
+ /**
+ * | Rotation | Direction |
+ * |-------------|--------------|
+ * | -45°/315°↻ | Northeast |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ NE: 7,
+
+ /**
+ * Reflection about Y-axis.
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ MIRROR_VERTICAL: 8,
+
+ /**
+ * Reflection about the main diagonal.
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ MAIN_DIAGONAL: 10,
+
+ /**
+ * Reflection about X-axis.
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ MIRROR_HORIZONTAL: 12,
+
+ /**
+ * Reflection about reverse diagonal.
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ REVERSE_DIAGONAL: 14,
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
+ * @return {PIXI.GD8Symmetry} The X-component of the U-axis
+ * after rotating the axes.
+ */
+ uX: (ind) => ux[ind],
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
+ * @return {PIXI.GD8Symmetry} The Y-component of the U-axis
+ * after rotating the axes.
+ */
+ uY: (ind) => uy[ind],
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
+ * @return {PIXI.GD8Symmetry} The X-component of the V-axis
+ * after rotating the axes.
+ */
+ vX: (ind) => vx[ind],
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
+ * @return {PIXI.GD8Symmetry} The Y-component of the V-axis
+ * after rotating the axes.
+ */
+ vY: (ind) => vy[ind],
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} rotation - symmetry whose opposite
+ * is needed. Only rotations have opposite symmetries while
+ * reflections don't.
+ * @return {PIXI.GD8Symmetry} The opposite symmetry of `rotation`
+ */
+ inv: (rotation) =>
+ {
+ if (rotation & 8)// true only if between 8 & 15 (reflections)
+ {
+ return rotation & 15;// or rotation % 16
+ }
+
+ return (-rotation) & 7;// or (8 - rotation) % 8
+ },
+
+ /**
+ * Composes the two D8 operations.
+ *
+ * Taking `^` as reflection:
+ *
+ * | | E=0 | S=2 | W=4 | N=6 | E^=8 | S^=10 | W^=12 | N^=14 |
+ * |-------|-----|-----|-----|-----|------|-------|-------|-------|
+ * | E=0 | E | S | W | N | E^ | S^ | W^ | N^ |
+ * | S=2 | S | W | N | E | S^ | W^ | N^ | E^ |
+ * | W=4 | W | N | E | S | W^ | N^ | E^ | S^ |
+ * | N=6 | N | E | S | W | N^ | E^ | S^ | W^ |
+ * | E^=8 | E^ | N^ | W^ | S^ | E | N | W | S |
+ * | S^=10 | S^ | E^ | N^ | W^ | S | E | N | W |
+ * | W^=12 | W^ | S^ | E^ | N^ | W | S | E | N |
+ * | N^=14 | N^ | W^ | S^ | E^ | N | W | S | E |
+ *
+ * [This is a Cayley table]{@link https://en.wikipedia.org/wiki/Cayley_table}
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} rotationSecond - Second operation, which
+ * is the row in the above cayley table.
+ * @param {PIXI.GD8Symmetry} rotationFirst - First operation, which
+ * is the column in the above cayley table.
+ * @return {PIXI.GD8Symmetry} Composed operation
+ */
+ add: (rotationSecond, rotationFirst) => (
+ rotationCayley[rotationSecond][rotationFirst]
+ ),
+
+ /**
+ * Reverse of `add`.
+ *
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} rotationSecond - Second operation
+ * @param {PIXI.GD8Symmetry} rotationFirst - First operation
+ * @return {PIXI.GD8Symmetry} Result
+ */
+ sub: (rotationSecond, rotationFirst) => (
+ rotationCayley[rotationSecond][groupD8.inv(rotationFirst)]
+ ),
+
+ /**
+ * Adds 180 degrees to rotation, which is a commutative
+ * operation.
+ *
+ * @memberof PIXI.groupD8
+ * @param {number} rotation - The number to rotate.
+ * @returns {number} Rotated number
+ */
+ rotate180: (rotation) => rotation ^ 4,
+
+ /**
+ * Checks if the rotation angle is vertical, i.e. south
+ * or north. It doesn't work for reflections.
+ *
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ */
+ isVertical: (rotation) => (rotation & 3) === 2, // rotation % 4 === 2
+
+ /**
+ * Approximates the vector `V(dx,dy)` into one of the
+ * eight directions provided by `groupD8`.
+ *
+ * @memberof PIXI.groupD8
+ * @param {number} dx - X-component of the vector
+ * @param {number} dy - Y-component of the vector
+ * @return {PIXI.GD8Symmetry} Approximation of the vector into
+ * one of the eight symmetries.
+ */
+ byDirection: (dx, dy) =>
+ {
+ if (Math.abs(dx) * 2 <= Math.abs(dy))
+ {
+ if (dy >= 0)
+ {
+ return groupD8.S;
+ }
+
+ return groupD8.N;
+ }
+ else if (Math.abs(dy) * 2 <= Math.abs(dx))
+ {
+ if (dx > 0)
+ {
+ return groupD8.E;
+ }
+
+ return groupD8.W;
+ }
+ else if (dy > 0)
+ {
+ if (dx > 0)
+ {
+ return groupD8.SE;
+ }
+
+ return groupD8.SW;
+ }
+ else if (dx > 0)
+ {
+ return groupD8.NE;
+ }
+
+ return groupD8.NW;
+ },
+
+ /**
+ * Helps sprite to compensate texture packer rotation.
+ *
+ * @memberof PIXI.groupD8
+ * @param {PIXI.Matrix} matrix - sprite world matrix
+ * @param {PIXI.GD8Symmetry} rotation - The rotation factor to use.
+ * @param {number} tx - sprite anchoring
+ * @param {number} ty - sprite anchoring
+ */
+ matrixAppendRotationInv: (matrix, rotation, tx = 0, ty = 0) =>
+ {
+ // Packer used "rotation", we use "inv(rotation)"
+ const mat = rotationMatrices[groupD8.inv(rotation)];
+
+ mat.tx = tx;
+ mat.ty = ty;
+ matrix.append(mat);
+ },
+};
diff --git a/bundles/pixi.js-legacy/src/index.js b/bundles/pixi.js-legacy/src/index.js
index f1598a1..df6b157 100644
--- a/bundles/pixi.js-legacy/src/index.js
+++ b/bundles/pixi.js-legacy/src/index.js
@@ -1,5 +1,5 @@
import { accessibility, interaction, prepare, extract } from 'pixi.js';
-import { CanvasRenderer, CanvasTinter } from '@pixi/canvas-renderer';
+import { CanvasRenderer, canvasUtils } from '@pixi/canvas-renderer';
import { CanvasMeshRenderer } from '@pixi/canvas-mesh';
import { CanvasGraphicsRenderer } from '@pixi/canvas-graphics';
import { CanvasSpriteRenderer } from '@pixi/canvas-sprite';
@@ -29,5 +29,5 @@
CanvasGraphicsRenderer,
CanvasMeshRenderer,
CanvasSpriteRenderer,
- CanvasTinter,
+ canvasUtils,
};
diff --git a/bundles/pixi.js/src/useDeprecated.js b/bundles/pixi.js/src/useDeprecated.js
index 12f00d4..ab88092 100644
--- a/bundles/pixi.js/src/useDeprecated.js
+++ b/bundles/pixi.js/src/useDeprecated.js
@@ -138,6 +138,34 @@
return PIXI.systems.FilterSystem;
},
},
+
+ /**
+ * @namespace PIXI.CanvasTinter
+ * @see PIXI.canvasUtils
+ * @deprecated since 5.2.0
+ */
+ CanvasTinter: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.CanvasTinter namespace has moved to PIXI.canvasUtils');
+
+ return PIXI.canvasUtils;
+ },
+ },
+
+ /**
+ * @namespace PIXI.GroupD8
+ * @see PIXI.groupD8
+ * @deprecated since 5.2.0
+ */
+ GroupD8: {
+ get()
+ {
+ deprecation('5.2.0', 'PIXI.GroupD8 namespace has moved to PIXI.groupD8');
+
+ return PIXI.groupD8;
+ },
+ },
});
/**
diff --git a/packages/canvas/canvas-mesh/src/NineSlicePlane.js b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
index dccfd79..6e2f055 100644
--- a/packages/canvas/canvas-mesh/src/NineSlicePlane.js
+++ b/packages/canvas/canvas-mesh/src/NineSlicePlane.js
@@ -1,4 +1,4 @@
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { NineSlicePlane } from '@pixi/mesh-extras';
/**
@@ -50,7 +50,7 @@
this._cachedTint = this.tint;
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
}
}
diff --git a/packages/canvas/canvas-renderer/src/CanvasTinter.js b/packages/canvas/canvas-renderer/src/CanvasTinter.js
deleted file mode 100644
index bfec51a..0000000
--- a/packages/canvas/canvas-renderer/src/CanvasTinter.js
+++ /dev/null
@@ -1,288 +0,0 @@
-import { hex2rgb, rgb2hex } from '@pixi/utils';
-import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
-
-/**
- * Utility methods for Sprite/Texture tinting.
- *
- * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
- * so be aware of the performance implications.
- *
- * @namespace PIXI.CanvasTinter
- * @memberof PIXI
- */
-export const CanvasTinter = {
- /**
- * Basically this method just needs a sprite and a color and tints the sprite with the given color.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Sprite} sprite - the sprite to tint
- * @param {number} color - the color to use to tint the sprite with
- * @return {HTMLCanvasElement} The tinted canvas
- */
- getTintedCanvas: (sprite, color) =>
- {
- const texture = sprite.texture;
-
- color = CanvasTinter.roundColor(color);
-
- const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- texture.tintCache = texture.tintCache || {};
-
- const cachedCanvas = texture.tintCache[stringColor];
-
- let canvas;
-
- if (cachedCanvas)
- {
- if (cachedCanvas.tintId === texture._updateID)
- {
- return texture.tintCache[stringColor];
- }
-
- canvas = texture.tintCache[stringColor];
- }
- else
- {
- canvas = CanvasTinter.canvas || document.createElement('canvas');
- }
-
- CanvasTinter.tintMethod(texture, color, canvas);
-
- canvas.tintId = texture._updateID;
-
- if (CanvasTinter.convertTintToImage)
- {
- // is this better?
- const tintImage = new Image();
-
- tintImage.src = canvas.toDataURL();
-
- texture.tintCache[stringColor] = tintImage;
- }
- else
- {
- texture.tintCache[stringColor] = canvas;
- // if we are not converting the texture to an image then we need to lose the reference to the canvas
- CanvasTinter.canvas = null;
- }
-
- return canvas;
- },
-
- /**
- * Tint a texture using the 'multiply' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithMultiply: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
-
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'multiply';
-
- const source = texture.baseTexture.getDrawableSource();
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- context.globalCompositeOperation = 'destination-atop';
-
- context.drawImage(
- source,
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
- },
-
- /**
- * Tint a texture using the 'overlay' operation.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithOverlay(texture, color, canvas)
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
- context.fillRect(0, 0, crop.width, crop.height);
-
- context.globalCompositeOperation = 'destination-atop';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
-
- // context.globalCompositeOperation = 'copy';
- context.restore();
- },
-
- /**
- * Tint a texture pixel per pixel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {PIXI.Texture} texture - the texture to tint
- * @param {number} color - the color to use to tint the sprite with
- * @param {HTMLCanvasElement} canvas - the current canvas
- */
- tintWithPerPixel: (texture, color, canvas) =>
- {
- const context = canvas.getContext('2d');
- const crop = texture._frame.clone();
- const resolution = texture.baseTexture.resolution;
-
- crop.x *= resolution;
- crop.y *= resolution;
- crop.width *= resolution;
- crop.height *= resolution;
-
- canvas.width = Math.ceil(crop.width);
- canvas.height = Math.ceil(crop.height);
-
- context.save();
- context.globalCompositeOperation = 'copy';
- context.drawImage(
- texture.baseTexture.getDrawableSource(),
- crop.x,
- crop.y,
- crop.width,
- crop.height,
- 0,
- 0,
- crop.width,
- crop.height
- );
- context.restore();
-
- const rgbValues = hex2rgb(color);
- const r = rgbValues[0];
- const g = rgbValues[1];
- const b = rgbValues[2];
-
- const pixelData = context.getImageData(0, 0, crop.width, crop.height);
-
- const pixels = pixelData.data;
-
- for (let i = 0; i < pixels.length; i += 4)
- {
- pixels[i + 0] *= r;
- pixels[i + 1] *= g;
- pixels[i + 2] *= b;
- }
-
- context.putImageData(pixelData, 0, 0);
- },
-
- /**
- * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
- *
- * @memberof PIXI.CanvasTinter
- * @param {number} color - the color to round, should be a hex color
- * @return {number} The rounded color.
- */
- roundColor: (color) =>
- {
- const step = CanvasTinter.cacheStepsPerColorChannel;
-
- const rgbValues = hex2rgb(color);
-
- rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
- rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
- rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
-
- return rgb2hex(rgbValues);
- },
-
- /**
- * Number of steps which will be used as a cap when rounding colors.
- *
- * @memberof PIXI.CanvasTinter
- * @type {number}
- */
- cacheStepsPerColorChannel: 8,
-
- /**
- * Tint cache boolean flag.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- convertTintToImage: false,
-
- /**
- * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
- *
- * @memberof PIXI.CanvasTinter
- * @type {boolean}
- */
- canUseMultiply: canUseNewCanvasBlendModes(),
-
- /**
- * The tinting method that will be used.
- *
- * @memberof PIXI.CanvasTinter
- * @type {Function}
- */
- tintMethod: () =>
- { // jslint-disable no-empty-function
-
- },
-};
-
-CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/canvasUtils.js b/packages/canvas/canvas-renderer/src/canvasUtils.js
new file mode 100644
index 0000000..62e16d4
--- /dev/null
+++ b/packages/canvas/canvas-renderer/src/canvasUtils.js
@@ -0,0 +1,288 @@
+import { hex2rgb, rgb2hex } from '@pixi/utils';
+import { canUseNewCanvasBlendModes } from './utils/canUseNewCanvasBlendModes';
+
+/**
+ * Utility methods for Sprite/Texture tinting.
+ *
+ * Tinting with the CanvasRenderer involves creating a new canvas to use as a texture,
+ * so be aware of the performance implications.
+ *
+ * @namespace PIXI.canvasUtils
+ * @memberof PIXI
+ */
+export const canvasUtils = {
+ /**
+ * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Sprite} sprite - the sprite to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @return {HTMLCanvasElement} The tinted canvas
+ */
+ getTintedCanvas: (sprite, color) =>
+ {
+ const texture = sprite.texture;
+
+ color = canvasUtils.roundColor(color);
+
+ const stringColor = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ texture.tintCache = texture.tintCache || {};
+
+ const cachedCanvas = texture.tintCache[stringColor];
+
+ let canvas;
+
+ if (cachedCanvas)
+ {
+ if (cachedCanvas.tintId === texture._updateID)
+ {
+ return texture.tintCache[stringColor];
+ }
+
+ canvas = texture.tintCache[stringColor];
+ }
+ else
+ {
+ canvas = canvasUtils.canvas || document.createElement('canvas');
+ }
+
+ canvasUtils.tintMethod(texture, color, canvas);
+
+ canvas.tintId = texture._updateID;
+
+ if (canvasUtils.convertTintToImage)
+ {
+ // is this better?
+ const tintImage = new Image();
+
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ canvasUtils.canvas = null;
+ }
+
+ return canvas;
+ },
+
+ /**
+ * Tint a texture using the 'multiply' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithMultiply: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'multiply';
+
+ const source = texture.baseTexture.getDrawableSource();
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ context.globalCompositeOperation = 'destination-atop';
+
+ context.drawImage(
+ source,
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+ },
+
+ /**
+ * Tint a texture using the 'overlay' operation.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithOverlay(texture, color, canvas)
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.fillStyle = `#${(`00000${(color | 0).toString(16)}`).substr(-6)}`;
+ context.fillRect(0, 0, crop.width, crop.height);
+
+ context.globalCompositeOperation = 'destination-atop';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+
+ // context.globalCompositeOperation = 'copy';
+ context.restore();
+ },
+
+ /**
+ * Tint a texture pixel per pixel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {PIXI.Texture} texture - the texture to tint
+ * @param {number} color - the color to use to tint the sprite with
+ * @param {HTMLCanvasElement} canvas - the current canvas
+ */
+ tintWithPerPixel: (texture, color, canvas) =>
+ {
+ const context = canvas.getContext('2d');
+ const crop = texture._frame.clone();
+ const resolution = texture.baseTexture.resolution;
+
+ crop.x *= resolution;
+ crop.y *= resolution;
+ crop.width *= resolution;
+ crop.height *= resolution;
+
+ canvas.width = Math.ceil(crop.width);
+ canvas.height = Math.ceil(crop.height);
+
+ context.save();
+ context.globalCompositeOperation = 'copy';
+ context.drawImage(
+ texture.baseTexture.getDrawableSource(),
+ crop.x,
+ crop.y,
+ crop.width,
+ crop.height,
+ 0,
+ 0,
+ crop.width,
+ crop.height
+ );
+ context.restore();
+
+ const rgbValues = hex2rgb(color);
+ const r = rgbValues[0];
+ const g = rgbValues[1];
+ const b = rgbValues[2];
+
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+ const pixels = pixelData.data;
+
+ for (let i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i + 0] *= r;
+ pixels[i + 1] *= g;
+ pixels[i + 2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+ },
+
+ /**
+ * Rounds the specified color according to the canvasUtils.cacheStepsPerColorChannel.
+ *
+ * @memberof PIXI.canvasUtils
+ * @param {number} color - the color to round, should be a hex color
+ * @return {number} The rounded color.
+ */
+ roundColor: (color) =>
+ {
+ const step = canvasUtils.cacheStepsPerColorChannel;
+
+ const rgbValues = hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return rgb2hex(rgbValues);
+ },
+
+ /**
+ * Number of steps which will be used as a cap when rounding colors.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {number}
+ */
+ cacheStepsPerColorChannel: 8,
+
+ /**
+ * Tint cache boolean flag.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ convertTintToImage: false,
+
+ /**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {boolean}
+ */
+ canUseMultiply: canUseNewCanvasBlendModes(),
+
+ /**
+ * The tinting method that will be used.
+ *
+ * @memberof PIXI.canvasUtils
+ * @type {Function}
+ */
+ tintMethod: () =>
+ { // jslint-disable no-empty-function
+
+ },
+};
+
+canvasUtils.tintMethod = canvasUtils.canUseMultiply ? canvasUtils.tintWithMultiply : canvasUtils.tintWithPerPixel;
diff --git a/packages/canvas/canvas-renderer/src/index.js b/packages/canvas/canvas-renderer/src/index.js
index 80987c3..71bc5ee 100644
--- a/packages/canvas/canvas-renderer/src/index.js
+++ b/packages/canvas/canvas-renderer/src/index.js
@@ -1,6 +1,6 @@
export * from './CanvasRenderer';
export * from './utils/canUseNewCanvasBlendModes';
-export * from './CanvasTinter';
+export * from './canvasUtils';
import './Renderer';
import './BaseTexture';
diff --git a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
index 4eac1d7..fd8857f 100644
--- a/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
+++ b/packages/canvas/canvas-sprite-tiling/src/TilingSprite.js
@@ -1,5 +1,5 @@
import { TilingSprite } from '@pixi/sprite-tiling';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { canvasUtils } from '@pixi/canvas-renderer';
import { CanvasRenderTarget } from '@pixi/utils';
/**
@@ -40,7 +40,7 @@
// Tint the tiling sprite
if (this.tint !== 0xFFFFFF)
{
- this._tintedCanvas = CanvasTinter.getTintedCanvas(this, this.tint);
+ this._tintedCanvas = canvasUtils.getTintedCanvas(this, this.tint);
tempCanvas.context.drawImage(this._tintedCanvas, 0, 0);
}
else
diff --git a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
index 507571c..3cdea2a 100644
--- a/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
+++ b/packages/canvas/canvas-sprite/src/CanvasSpriteRenderer.js
@@ -1,6 +1,6 @@
import { SCALE_MODES, BLEND_MODES } from '@pixi/constants';
-import { Matrix, GroupD8 } from '@pixi/math';
-import { CanvasTinter } from '@pixi/canvas-renderer';
+import { Matrix, groupD8 } from '@pixi/math';
+import { canvasUtils } from '@pixi/canvas-renderer';
const canvasRenderWorldTransform = new Matrix();
@@ -96,7 +96,7 @@
{
wt.copyTo(canvasRenderWorldTransform);
wt = canvasRenderWorldTransform;
- GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
+ groupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
// the anchor has already been applied above, so lets set it to zero
dx = 0;
dy = 0;
@@ -155,7 +155,7 @@
sprite._cachedTint = sprite.tint;
// TODO clean up caching - how to clean up the caches?
- sprite._tintedCanvas = CanvasTinter.getTintedCanvas(sprite, sprite.tint);
+ sprite._tintedCanvas = canvasUtils.getTintedCanvas(sprite, sprite.tint);
}
context.drawImage(
diff --git a/packages/core/src/textures/Texture.js b/packages/core/src/textures/Texture.js
index ea5c843..107b61e 100644
--- a/packages/core/src/textures/Texture.js
+++ b/packages/core/src/textures/Texture.js
@@ -45,7 +45,7 @@
* @param {PIXI.Rectangle} [frame] - The rectangle frame of the texture to show
* @param {PIXI.Rectangle} [orig] - The area of original texture
* @param {PIXI.Rectangle} [trim] - Trimmed rectangle of original texture
- * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.GroupD8}
+ * @param {number} [rotate] - indicates how the texture was rotated by texture packer. See {@link PIXI.groupD8}
* @param {PIXI.Point} [anchor] - Default anchor point used for sprite placement / rotation
*/
constructor(baseTexture, frame, orig, trim, rotate, anchor)
@@ -563,7 +563,7 @@
* set to 2 to compensate for texture packer rotation
* set to 6 to compensate for spine packer rotation
* can be used to rotate or mirror sprites
- * See {@link PIXI.GroupD8} for explanation
+ * See {@link PIXI.groupD8} for explanation
*
* @member {number}
*/
diff --git a/packages/core/src/textures/TextureUvs.js b/packages/core/src/textures/TextureUvs.js
index 322e973..735d928 100644
--- a/packages/core/src/textures/TextureUvs.js
+++ b/packages/core/src/textures/TextureUvs.js
@@ -1,4 +1,4 @@
-import { GroupD8 } from '@pixi/math';
+import { groupD8 } from '@pixi/math';
/**
* Stores a texture's frame in UV coordinates, in
@@ -85,7 +85,7 @@
* @protected
* @param {PIXI.Rectangle} frame - The frame of the texture
* @param {PIXI.Rectangle} baseFrame - The base frame of the texture
- * @param {number} rotate - Rotation of frame, see {@link PIXI.GroupD8}
+ * @param {number} rotate - Rotation of frame, see {@link PIXI.groupD8}
*/
set(frame, baseFrame, rotate)
{
@@ -102,21 +102,21 @@
const cX = (frame.x / tw) + w2;
const cY = (frame.y / th) + h2;
- rotate = GroupD8.add(rotate, GroupD8.NW); // NW is top-left corner
- this.x0 = cX + (w2 * GroupD8.uX(rotate));
- this.y0 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, groupD8.NW); // NW is top-left corner
+ this.x0 = cX + (w2 * groupD8.uX(rotate));
+ this.y0 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2); // rotate 90 degrees clockwise
- this.x1 = cX + (w2 * GroupD8.uX(rotate));
- this.y1 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2); // rotate 90 degrees clockwise
+ this.x1 = cX + (w2 * groupD8.uX(rotate));
+ this.y1 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2);
- this.x2 = cX + (w2 * GroupD8.uX(rotate));
- this.y2 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2);
+ this.x2 = cX + (w2 * groupD8.uX(rotate));
+ this.y2 = cY + (h2 * groupD8.uY(rotate));
- rotate = GroupD8.add(rotate, 2);
- this.x3 = cX + (w2 * GroupD8.uX(rotate));
- this.y3 = cY + (h2 * GroupD8.uY(rotate));
+ rotate = groupD8.add(rotate, 2);
+ this.x3 = cX + (w2 * groupD8.uX(rotate));
+ this.y3 = cY + (h2 * groupD8.uY(rotate));
}
else
{
diff --git a/packages/math/src/GroupD8.js b/packages/math/src/GroupD8.js
deleted file mode 100644
index 513cea8..0000000
--- a/packages/math/src/GroupD8.js
+++ /dev/null
@@ -1,403 +0,0 @@
-// Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group
-//
-// This file implements the dihedral group of order 16, also called
-// of degree 8. That's why its called GroupD8.
-
-import { Matrix } from './Matrix';
-
-/*
- * Transform matrix for operation n is:
- * | ux | vx |
- * | uy | vy |
- */
-
-const ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1];
-const uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1];
-const vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1];
-const vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1];
-
-/**
- * [Cayley Table]{@link https://en.wikipedia.org/wiki/Cayley_table}
- * for the composition of each rotation in the dihederal group D8.
- *
- * @type number[][]
- * @private
- */
-const rotationCayley = [];
-
-/**
- * Matrices for each `GD8Symmetry` rotation.
- *
- * @type Matrix[]
- * @private
- */
-const rotationMatrices = [];
-
-/*
- * Alias for {@code Math.sign}.
- */
-const signum = Math.sign;
-
-/*
- * Initializes `rotationCayley` and `rotationMatrices`. It is called
- * only once below.
- */
-function init()
-{
- for (let i = 0; i < 16; i++)
- {
- const row = [];
-
- rotationCayley.push(row);
-
- for (let j = 0; j < 16; j++)
- {
- /* Multiplies rotation matrices i and j. */
- const _ux = signum((ux[i] * ux[j]) + (vx[i] * uy[j]));
- const _uy = signum((uy[i] * ux[j]) + (vy[i] * uy[j]));
- const _vx = signum((ux[i] * vx[j]) + (vx[i] * vy[j]));
- const _vy = signum((uy[i] * vx[j]) + (vy[i] * vy[j]));
-
- /* Finds rotation matrix matching the product and pushes it. */
- for (let k = 0; k < 16; k++)
- {
- if (ux[k] === _ux && uy[k] === _uy
- && vx[k] === _vx && vy[k] === _vy)
- {
- row.push(k);
- break;
- }
- }
- }
- }
-
- for (let i = 0; i < 16; i++)
- {
- const mat = new Matrix();
-
- mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0);
- rotationMatrices.push(mat);
- }
-}
-
-init();
-
-/**
- * @memberof PIXI
- * @typedef {number} GD8Symmetry
- * @see PIXI.GroupD8
- */
-
-/**
- * Implements the dihedral group D8, which is similar to
- * [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html};
- * D8 is the same but with diagonals, and it is used for texture
- * rotations.
- *
- * The directions the U- and V- axes after rotation
- * of an angle of `a: GD8Constant` are the vectors `(uX(a), uY(a))`
- * and `(vX(a), vY(a))`. These aren't necessarily unit vectors.
- *
- * **Origin:**
- * This is the small part of gameofbombs.com portal system. It works.
- *
- * @see PIXI.GroupD8.E
- * @see PIXI.GroupD8.SE
- * @see PIXI.GroupD8.S
- * @see PIXI.GroupD8.SW
- * @see PIXI.GroupD8.W
- * @see PIXI.GroupD8.NW
- * @see PIXI.GroupD8.N
- * @see PIXI.GroupD8.NE
- * @author Ivan @ivanpopelyshev
- * @namespace PIXI.GroupD8
- * @memberof PIXI
- */
-export const GroupD8 = {
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 0° | East |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- E: 0,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 45°↻ | Southeast |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- SE: 1,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 90°↻ | South |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- S: 2,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 135°↻ | Southwest |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- SW: 3,
-
- /**
- * | Rotation | Direction |
- * |----------|-----------|
- * | 180° | West |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- W: 4,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -135°/225°↻ | Northwest |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- NW: 5,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -90°/270°↻ | North |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- N: 6,
-
- /**
- * | Rotation | Direction |
- * |-------------|--------------|
- * | -45°/315°↻ | Northeast |
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- NE: 7,
-
- /**
- * Reflection about Y-axis.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MIRROR_VERTICAL: 8,
-
- /**
- * Reflection about the main diagonal.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MAIN_DIAGONAL: 10,
-
- /**
- * Reflection about X-axis.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- MIRROR_HORIZONTAL: 12,
-
- /**
- * Reflection about reverse diagonal.
- *
- * @memberof PIXI.GroupD8
- * @constant {PIXI.GD8Symmetry}
- */
- REVERSE_DIAGONAL: 14,
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The X-component of the U-axis
- * after rotating the axes.
- */
- uX: (ind) => ux[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The Y-component of the U-axis
- * after rotating the axes.
- */
- uY: (ind) => uy[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The X-component of the V-axis
- * after rotating the axes.
- */
- vX: (ind) => vx[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
- * @return {PIXI.GD8Symmetry} The Y-component of the V-axis
- * after rotating the axes.
- */
- vY: (ind) => vy[ind],
-
- /**
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotation - symmetry whose opposite
- * is needed. Only rotations have opposite symmetries while
- * reflections don't.
- * @return {PIXI.GD8Symmetry} The opposite symmetry of `rotation`
- */
- inv: (rotation) =>
- {
- if (rotation & 8)// true only if between 8 & 15 (reflections)
- {
- return rotation & 15;// or rotation % 16
- }
-
- return (-rotation) & 7;// or (8 - rotation) % 8
- },
-
- /**
- * Composes the two D8 operations.
- *
- * Taking `^` as reflection:
- *
- * | | E=0 | S=2 | W=4 | N=6 | E^=8 | S^=10 | W^=12 | N^=14 |
- * |-------|-----|-----|-----|-----|------|-------|-------|-------|
- * | E=0 | E | S | W | N | E^ | S^ | W^ | N^ |
- * | S=2 | S | W | N | E | S^ | W^ | N^ | E^ |
- * | W=4 | W | N | E | S | W^ | N^ | E^ | S^ |
- * | N=6 | N | E | S | W | N^ | E^ | S^ | W^ |
- * | E^=8 | E^ | N^ | W^ | S^ | E | N | W | S |
- * | S^=10 | S^ | E^ | N^ | W^ | S | E | N | W |
- * | W^=12 | W^ | S^ | E^ | N^ | W | S | E | N |
- * | N^=14 | N^ | W^ | S^ | E^ | N | W | S | E |
- *
- * [This is a Cayley table]{@link https://en.wikipedia.org/wiki/Cayley_table}
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotationSecond - Second operation, which
- * is the row in the above cayley table.
- * @param {PIXI.GD8Symmetry} rotationFirst - First operation, which
- * is the column in the above cayley table.
- * @return {PIXI.GD8Symmetry} Composed operation
- */
- add: (rotationSecond, rotationFirst) => (
- rotationCayley[rotationSecond][rotationFirst]
- ),
-
- /**
- * Reverse of `add`.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotationSecond - Second operation
- * @param {PIXI.GD8Symmetry} rotationFirst - First operation
- * @return {PIXI.GD8Symmetry} Result
- */
- sub: (rotationSecond, rotationFirst) => (
- rotationCayley[rotationSecond][GroupD8.inv(rotationFirst)]
- ),
-
- /**
- * Adds 180 degrees to rotation, which is a commutative
- * operation.
- *
- * @memberof PIXI.GroupD8
- * @param {number} rotation - The number to rotate.
- * @returns {number} Rotated number
- */
- rotate180: (rotation) => rotation ^ 4,
-
- /**
- * Checks if the rotation angle is vertical, i.e. south
- * or north. It doesn't work for reflections.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.GD8Symmetry} rotation - The number to check.
- * @returns {boolean} Whether or not the direction is vertical
- */
- isVertical: (rotation) => (rotation & 3) === 2, // rotation % 4 === 2
-
- /**
- * Approximates the vector `V(dx,dy)` into one of the
- * eight directions provided by `GroupD8`.
- *
- * @memberof PIXI.GroupD8
- * @param {number} dx - X-component of the vector
- * @param {number} dy - Y-component of the vector
- * @return {PIXI.GD8Symmetry} Approximation of the vector into
- * one of the eight symmetries.
- */
- byDirection: (dx, dy) =>
- {
- if (Math.abs(dx) * 2 <= Math.abs(dy))
- {
- if (dy >= 0)
- {
- return GroupD8.S;
- }
-
- return GroupD8.N;
- }
- else if (Math.abs(dy) * 2 <= Math.abs(dx))
- {
- if (dx > 0)
- {
- return GroupD8.E;
- }
-
- return GroupD8.W;
- }
- else if (dy > 0)
- {
- if (dx > 0)
- {
- return GroupD8.SE;
- }
-
- return GroupD8.SW;
- }
- else if (dx > 0)
- {
- return GroupD8.NE;
- }
-
- return GroupD8.NW;
- },
-
- /**
- * Helps sprite to compensate texture packer rotation.
- *
- * @memberof PIXI.GroupD8
- * @param {PIXI.Matrix} matrix - sprite world matrix
- * @param {PIXI.GD8Symmetry} rotation - The rotation factor to use.
- * @param {number} tx - sprite anchoring
- * @param {number} ty - sprite anchoring
- */
- matrixAppendRotationInv: (matrix, rotation, tx = 0, ty = 0) =>
- {
- // Packer used "rotation", we use "inv(rotation)"
- const mat = rotationMatrices[GroupD8.inv(rotation)];
-
- mat.tx = tx;
- mat.ty = ty;
- matrix.append(mat);
- },
-};
diff --git a/packages/math/src/groupD8.js b/packages/math/src/groupD8.js
new file mode 100644
index 0000000..8b9f542
--- /dev/null
+++ b/packages/math/src/groupD8.js
@@ -0,0 +1,403 @@
+// Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group
+//
+// This file implements the dihedral group of order 16, also called
+// of degree 8. That's why its called groupD8.
+
+import { Matrix } from './Matrix';
+
+/*
+ * Transform matrix for operation n is:
+ * | ux | vx |
+ * | uy | vy |
+ */
+
+const ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1];
+const uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1];
+const vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1];
+const vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1];
+
+/**
+ * [Cayley Table]{@link https://en.wikipedia.org/wiki/Cayley_table}
+ * for the composition of each rotation in the dihederal group D8.
+ *
+ * @type number[][]
+ * @private
+ */
+const rotationCayley = [];
+
+/**
+ * Matrices for each `GD8Symmetry` rotation.
+ *
+ * @type Matrix[]
+ * @private
+ */
+const rotationMatrices = [];
+
+/*
+ * Alias for {@code Math.sign}.
+ */
+const signum = Math.sign;
+
+/*
+ * Initializes `rotationCayley` and `rotationMatrices`. It is called
+ * only once below.
+ */
+function init()
+{
+ for (let i = 0; i < 16; i++)
+ {
+ const row = [];
+
+ rotationCayley.push(row);
+
+ for (let j = 0; j < 16; j++)
+ {
+ /* Multiplies rotation matrices i and j. */
+ const _ux = signum((ux[i] * ux[j]) + (vx[i] * uy[j]));
+ const _uy = signum((uy[i] * ux[j]) + (vy[i] * uy[j]));
+ const _vx = signum((ux[i] * vx[j]) + (vx[i] * vy[j]));
+ const _vy = signum((uy[i] * vx[j]) + (vy[i] * vy[j]));
+
+ /* Finds rotation matrix matching the product and pushes it. */
+ for (let k = 0; k < 16; k++)
+ {
+ if (ux[k] === _ux && uy[k] === _uy
+ && vx[k] === _vx && vy[k] === _vy)
+ {
+ row.push(k);
+ break;
+ }
+ }
+ }
+ }
+
+ for (let i = 0; i < 16; i++)
+ {
+ const mat = new Matrix();
+
+ mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0);
+ rotationMatrices.push(mat);
+ }
+}
+
+init();
+
+/**
+ * @memberof PIXI
+ * @typedef {number} GD8Symmetry
+ * @see PIXI.groupD8
+ */
+
+/**
+ * Implements the dihedral group D8, which is similar to
+ * [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html};
+ * D8 is the same but with diagonals, and it is used for texture
+ * rotations.
+ *
+ * The directions the U- and V- axes after rotation
+ * of an angle of `a: GD8Constant` are the vectors `(uX(a), uY(a))`
+ * and `(vX(a), vY(a))`. These aren't necessarily unit vectors.
+ *
+ * **Origin:**
+ * This is the small part of gameofbombs.com portal system. It works.
+ *
+ * @see PIXI.groupD8.E
+ * @see PIXI.groupD8.SE
+ * @see PIXI.groupD8.S
+ * @see PIXI.groupD8.SW
+ * @see PIXI.groupD8.W
+ * @see PIXI.groupD8.NW
+ * @see PIXI.groupD8.N
+ * @see PIXI.groupD8.NE
+ * @author Ivan @ivanpopelyshev
+ * @namespace PIXI.groupD8
+ * @memberof PIXI
+ */
+export const groupD8 = {
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 0° | East |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ E: 0,
+
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 45°↻ | Southeast |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ SE: 1,
+
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 90°↻ | South |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ S: 2,
+
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 135°↻ | Southwest |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ SW: 3,
+
+ /**
+ * | Rotation | Direction |
+ * |----------|-----------|
+ * | 180° | West |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ W: 4,
+
+ /**
+ * | Rotation | Direction |
+ * |-------------|--------------|
+ * | -135°/225°↻ | Northwest |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ NW: 5,
+
+ /**
+ * | Rotation | Direction |
+ * |-------------|--------------|
+ * | -90°/270°↻ | North |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ N: 6,
+
+ /**
+ * | Rotation | Direction |
+ * |-------------|--------------|
+ * | -45°/315°↻ | Northeast |
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ NE: 7,
+
+ /**
+ * Reflection about Y-axis.
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ MIRROR_VERTICAL: 8,
+
+ /**
+ * Reflection about the main diagonal.
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ MAIN_DIAGONAL: 10,
+
+ /**
+ * Reflection about X-axis.
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ MIRROR_HORIZONTAL: 12,
+
+ /**
+ * Reflection about reverse diagonal.
+ *
+ * @memberof PIXI.groupD8
+ * @constant {PIXI.GD8Symmetry}
+ */
+ REVERSE_DIAGONAL: 14,
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
+ * @return {PIXI.GD8Symmetry} The X-component of the U-axis
+ * after rotating the axes.
+ */
+ uX: (ind) => ux[ind],
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
+ * @return {PIXI.GD8Symmetry} The Y-component of the U-axis
+ * after rotating the axes.
+ */
+ uY: (ind) => uy[ind],
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
+ * @return {PIXI.GD8Symmetry} The X-component of the V-axis
+ * after rotating the axes.
+ */
+ vX: (ind) => vx[ind],
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} ind - sprite rotation angle.
+ * @return {PIXI.GD8Symmetry} The Y-component of the V-axis
+ * after rotating the axes.
+ */
+ vY: (ind) => vy[ind],
+
+ /**
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} rotation - symmetry whose opposite
+ * is needed. Only rotations have opposite symmetries while
+ * reflections don't.
+ * @return {PIXI.GD8Symmetry} The opposite symmetry of `rotation`
+ */
+ inv: (rotation) =>
+ {
+ if (rotation & 8)// true only if between 8 & 15 (reflections)
+ {
+ return rotation & 15;// or rotation % 16
+ }
+
+ return (-rotation) & 7;// or (8 - rotation) % 8
+ },
+
+ /**
+ * Composes the two D8 operations.
+ *
+ * Taking `^` as reflection:
+ *
+ * | | E=0 | S=2 | W=4 | N=6 | E^=8 | S^=10 | W^=12 | N^=14 |
+ * |-------|-----|-----|-----|-----|------|-------|-------|-------|
+ * | E=0 | E | S | W | N | E^ | S^ | W^ | N^ |
+ * | S=2 | S | W | N | E | S^ | W^ | N^ | E^ |
+ * | W=4 | W | N | E | S | W^ | N^ | E^ | S^ |
+ * | N=6 | N | E | S | W | N^ | E^ | S^ | W^ |
+ * | E^=8 | E^ | N^ | W^ | S^ | E | N | W | S |
+ * | S^=10 | S^ | E^ | N^ | W^ | S | E | N | W |
+ * | W^=12 | W^ | S^ | E^ | N^ | W | S | E | N |
+ * | N^=14 | N^ | W^ | S^ | E^ | N | W | S | E |
+ *
+ * [This is a Cayley table]{@link https://en.wikipedia.org/wiki/Cayley_table}
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} rotationSecond - Second operation, which
+ * is the row in the above cayley table.
+ * @param {PIXI.GD8Symmetry} rotationFirst - First operation, which
+ * is the column in the above cayley table.
+ * @return {PIXI.GD8Symmetry} Composed operation
+ */
+ add: (rotationSecond, rotationFirst) => (
+ rotationCayley[rotationSecond][rotationFirst]
+ ),
+
+ /**
+ * Reverse of `add`.
+ *
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} rotationSecond - Second operation
+ * @param {PIXI.GD8Symmetry} rotationFirst - First operation
+ * @return {PIXI.GD8Symmetry} Result
+ */
+ sub: (rotationSecond, rotationFirst) => (
+ rotationCayley[rotationSecond][groupD8.inv(rotationFirst)]
+ ),
+
+ /**
+ * Adds 180 degrees to rotation, which is a commutative
+ * operation.
+ *
+ * @memberof PIXI.groupD8
+ * @param {number} rotation - The number to rotate.
+ * @returns {number} Rotated number
+ */
+ rotate180: (rotation) => rotation ^ 4,
+
+ /**
+ * Checks if the rotation angle is vertical, i.e. south
+ * or north. It doesn't work for reflections.
+ *
+ * @memberof PIXI.groupD8
+ * @param {PIXI.GD8Symmetry} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ */
+ isVertical: (rotation) => (rotation & 3) === 2, // rotation % 4 === 2
+
+ /**
+ * Approximates the vector `V(dx,dy)` into one of the
+ * eight directions provided by `groupD8`.
+ *
+ * @memberof PIXI.groupD8
+ * @param {number} dx - X-component of the vector
+ * @param {number} dy - Y-component of the vector
+ * @return {PIXI.GD8Symmetry} Approximation of the vector into
+ * one of the eight symmetries.
+ */
+ byDirection: (dx, dy) =>
+ {
+ if (Math.abs(dx) * 2 <= Math.abs(dy))
+ {
+ if (dy >= 0)
+ {
+ return groupD8.S;
+ }
+
+ return groupD8.N;
+ }
+ else if (Math.abs(dy) * 2 <= Math.abs(dx))
+ {
+ if (dx > 0)
+ {
+ return groupD8.E;
+ }
+
+ return groupD8.W;
+ }
+ else if (dy > 0)
+ {
+ if (dx > 0)
+ {
+ return groupD8.SE;
+ }
+
+ return groupD8.SW;
+ }
+ else if (dx > 0)
+ {
+ return groupD8.NE;
+ }
+
+ return groupD8.NW;
+ },
+
+ /**
+ * Helps sprite to compensate texture packer rotation.
+ *
+ * @memberof PIXI.groupD8
+ * @param {PIXI.Matrix} matrix - sprite world matrix
+ * @param {PIXI.GD8Symmetry} rotation - The rotation factor to use.
+ * @param {number} tx - sprite anchoring
+ * @param {number} ty - sprite anchoring
+ */
+ matrixAppendRotationInv: (matrix, rotation, tx = 0, ty = 0) =>
+ {
+ // Packer used "rotation", we use "inv(rotation)"
+ const mat = rotationMatrices[groupD8.inv(rotation)];
+
+ mat.tx = tx;
+ mat.ty = ty;
+ matrix.append(mat);
+ },
+};
diff --git a/packages/math/src/index.js b/packages/math/src/index.js
index 4ff1eef..a500742 100644
--- a/packages/math/src/index.js
+++ b/packages/math/src/index.js
@@ -6,7 +6,7 @@
export * from './Point';
export * from './ObservablePoint';
export * from './Matrix';
-export * from './GroupD8';
+export * from './groupD8';
export * from './Transform';
export * from './shapes/Circle';
export * from './shapes/Ellipse';