Handle missing textures better (and export them properly)
This commit is contained in:
parent
47d54d6e26
commit
74809acd2d
25
src/main.js
25
src/main.js
|
|
@ -41,6 +41,7 @@ import {
|
||||||
rgbToHsv,
|
rgbToHsv,
|
||||||
multiplyMatrices,
|
multiplyMatrices,
|
||||||
growBoundingBox,
|
growBoundingBox,
|
||||||
|
createMissingTexturePattern,
|
||||||
} from "./utils.js";
|
} from "./utils.js";
|
||||||
import {
|
import {
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
|
@ -2940,7 +2941,13 @@ class BaseShape {
|
||||||
if (this.filled) {
|
if (this.filled) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
if (this.fillImage) {
|
if (this.fillImage) {
|
||||||
let pat = ctx.createPattern(this.fillImage, "no-repeat");
|
let pat;
|
||||||
|
if (this.fillImage instanceof Element ||
|
||||||
|
Object.keys(this.fillImage).length !== 0) {
|
||||||
|
pat = ctx.createPattern(this.fillImage, "no-repeat");
|
||||||
|
} else {
|
||||||
|
pat = createMissingTexturePattern(ctx)
|
||||||
|
}
|
||||||
ctx.fillStyle = pat;
|
ctx.fillStyle = pat;
|
||||||
} else {
|
} else {
|
||||||
ctx.fillStyle = this.fillStyle;
|
ctx.fillStyle = this.fillStyle;
|
||||||
|
|
@ -3162,12 +3169,20 @@ class Shape extends BaseShape {
|
||||||
this.inProgress = true;
|
this.inProgress = true;
|
||||||
}
|
}
|
||||||
static fromJSON(json) {
|
static fromJSON(json) {
|
||||||
|
let fillImage = undefined;
|
||||||
|
if (json.fillImage && Object.keys(json.fillImage).length !== 0) {
|
||||||
|
let img = new Image();
|
||||||
|
img.src = json.fillImage.src
|
||||||
|
fillImage = img
|
||||||
|
} else {
|
||||||
|
fillImage = {}
|
||||||
|
}
|
||||||
const shape = new Shape(
|
const shape = new Shape(
|
||||||
json.startx,
|
json.startx,
|
||||||
json.starty,
|
json.starty,
|
||||||
{
|
{
|
||||||
fillStyle: json.fillStyle,
|
fillStyle: json.fillStyle,
|
||||||
fillImage: json.fillImage,
|
fillImage: fillImage,
|
||||||
strokeStyle: json.strokeStyle,
|
strokeStyle: json.strokeStyle,
|
||||||
lineWidth: json.lineWidth,
|
lineWidth: json.lineWidth,
|
||||||
fillShape: json.filled,
|
fillShape: json.filled,
|
||||||
|
|
@ -3199,7 +3214,11 @@ class Shape extends BaseShape {
|
||||||
json.startx = this.startx;
|
json.startx = this.startx;
|
||||||
json.starty = this.starty;
|
json.starty = this.starty;
|
||||||
json.fillStyle = this.fillStyle;
|
json.fillStyle = this.fillStyle;
|
||||||
json.fillImage = this.fillImage;
|
if (this.fillImage instanceof Element) {
|
||||||
|
json.fillImage = {
|
||||||
|
src: this.fillImage.src
|
||||||
|
}
|
||||||
|
}
|
||||||
json.strokeStyle = this.fillStyle;
|
json.strokeStyle = this.fillStyle;
|
||||||
json.lineWidth = this.lineWidth;
|
json.lineWidth = this.lineWidth;
|
||||||
json.filled = this.filled;
|
json.filled = this.filled;
|
||||||
|
|
|
||||||
27
src/utils.js
27
src/utils.js
|
|
@ -461,6 +461,32 @@ function drawCheckerboardBackground(ctx, x, y, width, height, squareSize) {
|
||||||
ctx.fillRect(x, y, width, height);
|
ctx.fillRect(x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const missingTexturePatternCache = new Map();
|
||||||
|
|
||||||
|
function createMissingTexturePattern(ctx) {
|
||||||
|
// Return cached pattern if it exists
|
||||||
|
if (missingTexturePatternCache.has(ctx)) return missingTexturePatternCache.get(ctx);
|
||||||
|
|
||||||
|
// Create an offscreen canvas for the checkerboard pattern
|
||||||
|
const size = 16;
|
||||||
|
const patternCanvas = document.createElement('canvas');
|
||||||
|
patternCanvas.width = patternCanvas.height = size * 2;
|
||||||
|
const patternCtx = patternCanvas.getContext('2d');
|
||||||
|
|
||||||
|
// Draw the magenta and black checkerboard pattern
|
||||||
|
for (let y = 0; y < 2; y++) {
|
||||||
|
for (let x = 0; x < 2; x++) {
|
||||||
|
patternCtx.fillStyle = (x + y) % 2 === 0 ? 'magenta' : 'black';
|
||||||
|
patternCtx.fillRect(x * size, y * size, size, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache and return the pattern
|
||||||
|
const pattern = ctx.createPattern(patternCanvas, 'repeat');
|
||||||
|
missingTexturePatternCache.set(ctx, pattern);
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
function hexToHsl(hex) {
|
function hexToHsl(hex) {
|
||||||
// Step 1: Convert hex to RGB
|
// Step 1: Convert hex to RGB
|
||||||
let r = parseInt(hex.substring(1, 3), 16) / 255;
|
let r = parseInt(hex.substring(1, 3), 16) / 255;
|
||||||
|
|
@ -919,6 +945,7 @@ export {
|
||||||
rgbToHex,
|
rgbToHex,
|
||||||
rgbToHsv,
|
rgbToHsv,
|
||||||
drawCheckerboardBackground,
|
drawCheckerboardBackground,
|
||||||
|
createMissingTexturePattern,
|
||||||
clamp,
|
clamp,
|
||||||
signedAngleBetweenVectors,
|
signedAngleBetweenVectors,
|
||||||
rotateAroundPoint,
|
rotateAroundPoint,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue