Skip to content

Commit

Permalink
Fixed transparent data URI images error (#147)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusLongmuir committed Feb 1, 2024
1 parent 69d93d4 commit a22695f
Showing 1 changed file with 31 additions and 9 deletions.
40 changes: 31 additions & 9 deletions packages/mml-web/src/elements/Image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,21 @@ export class Image extends TransformableElement {
super.removeSideEffectChild(child);
}

private clearImage() {
this.loadedImage = null;
this.srcApplyPromise = null;
if (this.material && this.material.map) {
this.material.map.dispose();
this.material.map = null;
}
}

private setSrc(newValue: string | null) {
this.props.src = (newValue || "").trim();
if (this.loadedImage !== null) {
const isDataUri = this.props.src.startsWith("data:image/");
if (this.loadedImage !== null && !isDataUri) {
// if the image has already been loaded, remove the image data from the THREE material
this.loadedImage = null;
this.srcApplyPromise = null;
if (this.material && this.material.map) {
this.material.map.dispose();
this.material.map = null;
}
this.clearImage();
}
if (!this.props.src) {
// if the src attribute is empty, reset the dimensions and return
Expand All @@ -162,7 +167,7 @@ export class Image extends TransformableElement {
return;
}

if (this.props.src.startsWith("data:image/")) {
if (isDataUri) {
// if the src is a data url, load it directly rather than using the loader - this avoids a potential frame skip
const image = document.createElement("img");
image.src = this.props.src;
Expand Down Expand Up @@ -195,15 +200,29 @@ export class Image extends TransformableElement {

private applyImage(image: HTMLImageElement) {
this.loadedImage = image;
if (!image.complete) {
// Wait for the image to be fully loaded (most likely a data uri that has not yet been decoded)
image.addEventListener("load", () => {
if (this.loadedImage !== image) {
// if the image has changed since we started loading, ignore this image
return;
}
this.applyImage(image);
});
return;
}
this.loadedImageHasTransparency = hasTransparency(this.loadedImage);
if (!this.material) {
return;
}
if (this.loadedImageHasTransparency) {
this.material.alphaMap = new THREE.CanvasTexture(this.loadedImage);
this.material.alphaTest = 0.01;
} else {
this.material.alphaMap = null;
this.material.alphaTest = 0;
}
this.material.transparent = this.loadedImageHasTransparency;
this.material.transparent = this.props.opacity !== 1 || this.loadedImageHasTransparency;
this.material.map = new THREE.CanvasTexture(this.loadedImage);
this.material.needsUpdate = true;
this.updateHeightAndWidth();
Expand Down Expand Up @@ -316,6 +335,9 @@ export function loadImageAsPromise(
}

function hasTransparency(image: HTMLImageElement) {
if (image.width === 0 || image.height === 0) {
return false;
}
const canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
Expand Down

0 comments on commit a22695f

Please sign in to comment.