Comments (31)
@1j01
Yeah, I'm afraid the test page works fine for me: I'm seeing multiple stacked squares.
Just moving the selection will NOT reset the canvas
Just resizing the selection WILL reset the canvasMoving the selection doesn't use
drawImage
, but resizing the selection usesdrawImage
. Also, drawing with most of the tools usesdrawImage
when done.Resizing and then moving the selection (without "applying" the resize first by clicking outside the selection) will NOT reset the canvas
This is curious. I'm not sure I can explain that. And, well, finalizing the selection also uses
drawImage
, so that somewhat muddles things.
Hmm, I'm not sure whether the behavior changed or I just didn't record it properly, but it does behave a bit differently to how I explained it! Let me try again:
- Making a selection immediately resets the canvas outside of the selection
- Moving the selection leaves a ghost/shadow of the background color in place of the original selection
- Clicking outside of the selection at this point to commit the change will keep the selection and the ghost
- Resizing the selection will also leave a ghost
- Clicking outside at this point will keep the selection, but deletes the ghost
- In fact, I can do any combination of moving and resizing the selection, and the ghost will always disappear if the last thing I did was a resize; or the ghost will stay around if the last thing I did was a move
Quick video demo (where my background color was set to red 🟥):
Screen.Recording.2023-11-15.at.6.53.41.PM.mov
Thanks for the time you're putting into diagnosing this! I didn't realize how much I used the app until I stopped being able to use it 😅
from jspaint.
i wonder if there has been further updates since then…? (no pressure! ^^;;)
I reported this issue to Chromium, and it looks like they already have someone assigned.
from jspaint.
i see multiple circles, so that means it's good?
Well it's good in that it's displaying correctly; it's not so good in that we've not identified the problem :)
Thanks for testing though!
from jspaint.
I have the same problem. Interestingly, the bug persists even when I use other online MS Paint alternatives.
from jspaint.
same problem:
macOS (macbook)
OS: 13.6
Chrome: 119.0.6045.123 (arm64)
I think it was OK 20 days ago
from jspaint.
I made a tweaked test page, hopefully demonstrating the bug.
Let me know if this reproduces the bug, y'all. (I feel like it won't, since it's a shot in the dark, and the Chrome team ought to have automated tests for things like this, but still...)
Screen.Recording.2023-11-15.at.7.58.02.PM.mov
aight tested the square thing, i already had a pile going before the recording, but i spam clicked even more just incase it wasn't enough
from jspaint.
I have also been encountering this issue. It indeed happens whenever drawImage()
is called on the main context.
As others have reported, this issue only occurs on Apple Silicon (M1) Chromium browsers. Firefox for me is fine, as is Chrome on Windows.
I found that disabling Accelerated 2D canvas (chrome://flags/#disable-accelerated-2d-canvas), which is an experimental Chrome feature, did the trick.
After reloading the browser, the app works with no issue. Hopefully it gets fixed with the next Chrome update.
from jspaint.
I have also been encountering this issue. It indeed happens whenever
drawImage()
is called on the main context. As others have reported, this issue only occurs on Apple Silicon (M1) Chromium browsers. Firefox for me is fine, as is Chrome on Windows.I found that disabling Accelerated 2D canvas (chrome://flags/#disable-accelerated-2d-canvas), which is an experimental Chrome feature, did the trick.
After reloading the browser, the app works with no issue. Hopefully it gets fixed with the next Chrome update.
You are a life saver, I can't believe how often I google jspaint to sketch something then remember it's broken due to this bug.
from jspaint.
Screen.Recording.2023-12-06.at.0.45.30.AM.mov
now on 120.0.6099.62 (Official Build) (x86_64) and it registers again~
(sprite is off because i enlargened my mouse but otherwise nothing off on my end)
from jspaint.
Same issue arises after I upgraded to the newest version of chrome.
Version 119.0.6045.105 (Official Build) (arm64)
from jspaint.
Same issue arises after I upgraded to the newest version of chrome.
Version 119.0.6045.105 (Official Build) (arm64)
possibly chrome itself breaks it, idk the technical who-now but updated it, build does the same thing
119.0.6045.123 (Official Build) (x86_64)
from jspaint.
Ah, the wonders of software rot. (The rectangle tool also broke recently on Firefox, and I've been experiencing tons of graphical glitches and WebGL crashes recently in Chrome.)
I can't reproduce this issue though, on Ubuntu 22 or macOS 10.14.6
What operating system does this happen on? Does it happen all the time?
from jspaint.
Ah, the wonders of software rot. (The rectangle tool also broke recently on Firefox, and I've been experiencing tons of graphical glitches and WebGL crashes recently in Chrome.) I can't reproduce this issue though, on Ubuntu 22 or macOS 10.14.6 What operating system does this happen on? Does it happen all the time?
my main computer is a macbook air that's a Retina 13-inch 2020, Sonoma 14.0.
hopefully that might help find where the issue is coming from
from jspaint.
same here I dont whats happening but i would like it fixed.
I need to use this software for a project but i cant due to the bug
from jspaint.
Does this test page show multiple circles when you click it multiple times, or just one?
I'm thinking this chromium bug could be the culprit.
from jspaint.
Does this test page show multiple circles when you click it multiple times, or just one? I'm thinking this chromium bug could be the culprit.
Screen.Recording.2023-11-10.at.4.10.48.AM.mov
i see multiple circles, so that means it's good?
from jspaint.
I have the same problem.
Mackbook Pro M2 Pro
macOS Sonoma 14.1
Google Chrome Versión 119.0.6045.123 (Build oficial) (arm64)
from jspaint.
Same problem
from jspaint.
same problem
macbook pro M1
macOS Sonoma 14.1
Chromium: 119.0.6045.105 (arm64)
from jspaint.
Similar problem for me on macOS 12.7, Chrome 119.0.6045.123
But I noticed that:
- Using the fill tool does not reset the canvas, except in Black and white mode
- Using the free-form select or rectangle select tools:
- Just moving the selection will NOT reset the canvas
- Just resizing the selection WILL reset the canvas
- Resizing and then moving the selection (without "applying" the resize first by clicking outside the selection) will NOT reset the canvas
- Clicking and immediately releasing with the ellipse/rectangle/rounded-rectangle tools (i.e. without dragging into an actual shape) triggers the "Woah! / Your browser may have cleared the canvas due to memory usage" message.
- This message is also triggered when using Image > Clear Image from the toolbar
from jspaint.
Similar problem for me on macOS 12.7, Chrome 119.0.6045.123
But I noticed that:
Using the fill tool does not reset the canvas, except in Black and white mode
Using the free-form select or rectangle select tools:
- Just moving the selection will NOT reset the canvas
- Just resizing the selection WILL reset the canvas
- Resizing and then moving the selection (without "applying" the resize first by clicking outside the selection) will NOT reset the canvas
Clicking and immediately releasing with the ellipse/rectangle/rounded-rectangle tools (i.e. without dragging into an actual shape) triggers the "Woah! / Your browser may have cleared the canvas due to memory usage" message.
This message is also triggered when using Image > Clear Image from the toolbar
interesting, i think i recalled seeing that just moving a selected box will delete the area around it, but the selected stuff itself will be safe
i ended up recording what i did with the canvas since i don't know how to describe it
Untitled.mov
from jspaint.
I made a tweaked test page, hopefully demonstrating the bug.
Let me know if this reproduces the bug, y'all. (I feel like it won't, since it's a shot in the dark, and the Chrome team ought to have automated tests for things like this, but still...)
Using the fill tool does not reset the canvas, except in Black and white mode
In Black and White mode it renders the fill region to a separate canvas and then draws that canvas onto the main canvas, whereas in Color mode, it draws the fill directly onto the canvas. This explains the difference. Similarly...
Just moving the selection will NOT reset the canvas
Just resizing the selection WILL reset the canvas
Moving the selection doesn't use drawImage
, but resizing the selection uses drawImage
. Also, drawing with most of the tools uses drawImage
when done.
Resizing and then moving the selection (without "applying" the resize first by clicking outside the selection) will NOT reset the canvas
This is curious. I'm not sure I can explain that. And, well, finalizing the selection also uses drawImage
, so that somewhat muddles things.
from jspaint.
@1j01
I did some research into this myself, and it does definitely seem to be an issue with drawImage()
. In fact, it seems to be something particular to passing an HTMLCanvasElement
as the image parameter. I found that using an HTMLImageElement
or OffscreenCanvas
worked fine!
I was tinkering with tool.pointerup()
at src/tools.js:1195
, using the line tool to experiment. The existing line of code I was replacing is this one at line 1201:
main_ctx.drawImage(tool.shape_canvas, 0, 0);
If I create a dummy canvas element and draw to it as an intermediate step, I just get the same result as usual: each new line erases all existing canvas data. Here's the code for that:
// Dummy intermediate HTMLCanvasElement fails 🚫
const dummyCanvas = document.createElement("canvas");
dummyCanvas.height = tool.shape_canvas.height;
dummyCanvas.width = tool.shape_canvas.width;
const dummyCtx = dummyCanvas.getContext("2d");
dummyCtx.drawImage(tool.shape_canvas, 0, 0);
main_ctx.drawImage(dummyCanvas, 0, 0);
// main_ctx.drawImage(tool.shape_canvas, 0, 0);
However, if I do the same thing with an OffscreenCanvas, this fixes the issue and the line tool works as expected!
// Dummy intermediate OffscreenCanvas succeeds! ✅
const offscreenCanvas = new OffscreenCanvas(tool.shape_canvas.width, tool.shape_canvas.height);
const offscreenCtx = offscreenCanvas.getContext("2d");
offscreenCtx.drawImage(tool.shape_canvas, 0, 0);
main_ctx.drawImage(offscreenCanvas, 0, 0);
// main_ctx.drawImage(tool.shape_canvas, 0, 0);
I also did a version where I rendered the tool canvas to a blob, then put that in an HTMLImageElement
and passed that to drawImage()
... it's more complicated and maybe a little less performant, but it works too.
// Dummy intermediate HTMLImageElement succeeds! ✅
tool.shape_canvas.toBlob((blob) => {
const newImg = document.createElement("img");
const url = URL.createObjectURL(blob);
newImg.onload = () => {
URL.revokeObjectURL(url);
main_ctx.drawImage(newImg, 0, 0);
newImg.parentElement.removeChild(newImg);
};
newImg.src = url;
tool.shape_canvas = null;
document.body.appendChild(newImg);
});
// main_ctx.drawImage(tool.shape_canvas, 0, 0);
Okay, so the problem is with HTMLCanvasElement
s... is it all of them? I tried creating a dummy canvas element and drawing that instead of the actual tool canvas (similar to your test page) and it exhibits the problem too! This code will make a red square appear somewhere on the canvas every time you draw a line, but it clears the whole canvas each time too, so you only ever see up to 1 square:
// Dummy brand new, unrelated HTMLCanvasElement fails 🚫
const canvas = document.createElement("canvas");
canvas.width = tool.shape_canvas.width;
canvas.height = tool.shape_canvas.height;
const ctx = canvas.getContext("2d");
const x = Math.floor(Math.random()*100);
const y = Math.floor(Math.random()*100);
ctx.fillStyle = "rgb(200, 0, 0)";
ctx.fillRect(x, y, 50, 50);
main_ctx.drawImage(canvas, 0, 0);
// main_ctx.drawImage(tool.shape_canvas, 0, 0);
So it would seem that this behavior is happening with any HTMLCanvasElement
... except, I tried one other thing, which was to render the main canvas to itself (using a small 10px offset so I can actually see something happening):
// Self-referential HTMLCanvasElement succeeds! ✅
main_ctx.drawImage(main_ctx.canvas, 10, 0);
// main_ctx.drawImage(tool.shape_canvas, 0, 0);
And in this case, the bug doesn't manifest—we are indeed rendering the main canvas on top of itself, without clearing it every time.
I have no idea why we would see the problem when using the tool canvas, or a fresh canvas, but not when using the main canvas. I also have no idea why the test page doesn't reproduce the bug.
Any ideas?
from jspaint.
Same issue on Chrome 119 / MacOS 13.6.
Luckily it works on Firefox (using Nightly 121) 🦊
from jspaint.
@exonjoe Thank you for your research and clear breakdown!
I have no idea why we would see the problem when using the tool canvas, or a fresh canvas, but not when using the main canvas. I also have no idea why the test page doesn't reproduce the bug.
Any ideas?
Well it's natural that drawing a canvas to itself might behave differently as it's a special case. It probably needs to copy a region of the canvas before performing the operation, in case the source and destination regions overlap. Drawing an OffscreenCanvas also would need a different implementation under the hood, but it's good to know that this works.
As for the test case, what I want to know is:
- Does the bug show up when loading JS Paint in an iframe? https://jsfiddle.net/1j01/t23hobw8/ (or https://98.js.org for that matter)
- Does the bug show up when loading my test case without any iframes involved, if you save the following as an HTML file and open it?
<!doctype html>
<html>
<head>
<title>Bug Repo Attempt for jspaint issue #328</title>
</head>
<body>
<canvas id="myCanvas" width="500" height="200"></canvas>
<button onclick="hopefullyRepro()">Click me</button>
<p>
This should display purple squares with blue outlines on top of each other each time you click.
If you see only one square "jumping around", it's broken, demonstrating the bug.
</p>
<a href="https://github.com/1j01/jspaint/issues/328">See JS Paint issue about this Chrome bug</a>
<script>
function hopefullyRepro()
{
const brushCanvas = document.createElement("canvas");
const brushCtx = brushCanvas.getContext("2d");
brushCtx.fillStyle = "blue";
brushCtx.fillRect(10, 10, 10, 10);
let x = ~~(Math.random() * 100);
let y = ~~(Math.random() * 50);
const imageData = brushCtx.getImageData(12, 12, 6, 6);
for (let i=0; i<imageData.data.length; i+=4) {
imageData.data[i] = 255;
}
brushCtx.putImageData(imageData, 12, 12);
document.getElementById('myCanvas').getContext('2d').drawImage(brushCanvas, x, y);
}
</script>
<style>
button {
font-size: 3em;
display: block;
}
</style>
</body>
</html>
from jspaint.
- Does the bug show up when loading JS Paint in an iframe? https://jsfiddle.net/1j01/t23hobw8/ (or https://98.js.org for that matter)
Yes, still seeing the bug in both the JSFiddle and 98.js :(
- Does the bug show up when loading my test case without any iframes involved, if you save the following as an HTML file and open it?
Nah, the test case is still fine for me!
Doesn't seem like being in an iframe is making a difference...
One thing I just tried: I made a new dummy canvas (using your make_canvas
function, to keep the dummy canvas as similar to the main canvas as possible) and added it to the document so I could see what's going on in it. I started drawing the tool.shape_canvas
to it, while still also drawing to the main canvas. I did this to check whether the problem applied when writing to any canvas, or just the main canvas.
I also added debugger
statements immediately before and after the main_ctx.drawImage()
call to confirm that the bug happens during that call.
// Dummy canvas renders fine but main canvas doesn't 😖
if (!document.getElementById(`dummyCanvas`)) {
const dummyCanvas = make_canvas(tool.shape_canvas.width, tool.shape_canvas.height);
dummyCanvas.style.position = `fixed`;
dummyCanvas.style.top = `0`;
dummyCanvas.style.right = `0`;
dummyCanvas.style.zIndex = `99999`;
dummyCanvas.style.border = `2px solid red`;
dummyCanvas.id = `dummyCanvas`;
document.body.append(dummyCanvas);
}
const dummyCanvasActual = document.getElementById(`dummyCanvas`);
const dummyCtx = dummyCanvasActual.getContext("2d");
dummyCtx.drawImage(tool.shape_canvas, 0, 0);
debugger;
main_ctx.drawImage(tool.shape_canvas, 0, 0);
debugger;
In this video, we can see in the red box that the dummyCanvas
behaves itself just fine. We can also see that the debugger statements coming either side of the main_ctx.drawImage()
calls capture the "before and after" of the bug, as we see the main canvas being cleared between the two:
Screen.Recording.2023-11-18.at.7.57.31.PM.mov
So... is the main canvas being "corrupted" at some point, making it misbehave in a way that a fresh canvas doesn't? I did try checking the obvious suspects like the globalAlpha
and globalCompositeOperation
of the canvases, but they're identical...
from jspaint.
i wonder if there has been further updates since then…?
(no pressure! ^^;;)
from jspaint.
trying to read the comments over on the chromium forms gives me a bit of a headache
1j01:
Does this test page show multiple circles when you click it multiple times, or just one? I'm thinking this chromium bug could be the culprit.
1431968 and
boowangoo:
I reported this issue to Chromium, and it looks like they already have someone assigned.
1506384 (aka the post above) kinda describes the same situation though right?
from jspaint.
@tempaccount9317 I don't fully understand the bisect information either 😅. But 119 is the current stable build. So I focused on the first forward bisect information, which I'm guessing is to find the first breaking commit. Seems like the issue was traced to a commit (4881264) in September, and the owner already has a patch (5027957) for it. I'm guessing that the reverse bisects are to find the last working commit? If you read the description from 5027957, the author acknowledges that it fixes an bug from 4881264, which sounds like the bug that we are experiencing.
I just installed Chrome Beta, which is on build 120.0.6099.62 and already has that patch applied, and can confirm that the issue is not there. Seems like the bug will be resolved in the next stable update.
1431968 and 1506384 (aka the post above) kinda describes the same situation though right?
1431968 was reported on build 112 in April, and the team cannot reproduce it yet. So I'm inclined to believe that it's a separate issue, but I could be wrong.
from jspaint.
If you're using Apple Silicon M1 on a Chromium browser then it's a known bug in Chromium and the solution is chrome://flags/#disable-accelerated-2d-canvas via #328 (comment)
from jspaint.
As per the comment on this bug (1500272#c30), the fix has been merged and the stable build has been shipped.
I just updated Chrome and no longer see the bug on jspaint.
from jspaint.
Related Issues (20)
- Unable to Flip Vertical HOT 2
- Unable to Rotate By Angle HOT 2
- "Width" field is not focused and selected when opening Image -> Attributes... HOT 3
- Inactive window of Paint in https://98.js.org
- How to open multiple windows in electron macOS? HOT 2
- why does electron app make requests to internet when started? HOT 4
- Bucket tool went weird today HOT 5
- i cant draw after making 1 brushstroke or anything on the canvas HOT 3
- Pixel data offset field from the BMP header is ignored
- The Recover Document (Woah!) pop-up still occurs despite the following HOT 2
- Blended/Anti-Aliased edges on rectangle tool HOT 4
- [feature] comic creator
- Shortcut keys?
- Pasted screenshots show up twice as big (HiDPI Retina screenshot) HOT 1
- Error when changing eraser size with keyboard
- Internal copy not working on macOS Safari
- Error trying to paste a screenshot on Windows 11
- Errors trying to paste/open an SVG file
- Shift+Insert, Ctrl+Insert, and Ctrl+Delete shortcuts throw errors HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jspaint.