5 ms·
I actually do if you have the time thanks! Whenever I'm trying to draw curved lines, I always have issues with how they look, they seem to look low quality/pix
by Trufa 5y ago
I actually do if you have the time thanks!
Whenever I'm trying to draw curved lines, I always have issues with how they look, they seem to look low quality/pixelated.
Like here: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo https://developer.mozilla.org/en-US/docs/Web/API/CanvasRende...
In the most basic examples they seem to always produce curves like this.
Sorry I don't have more specifics since it's a project I'm not actively working on right now but it was a spine that I never removed.
If the questions is too broad, please let me know!
- simonsarris 5y ago99% the problem is one of pixel density. That is, you have a 400x400 canvas, and a 400x400 CSS pixel space you are drawing it to, but your devices pixel ratio is higher than 1, so it looks kinda blurry. This is because devices squish more than one "hardware pixel" per CSS pixel. Often at a ratio of 1.5 or 2, or higher. The solution is to make a larger canvas, say, 800x800 and put it into that 400x400 space. Here is an example, using that MDN code, with a 400x400 canvas (red) next to a 800x800 canvas (blue). CSS is forcing them both to appear the same 400x400 size. The blue one should look sharper on most devices. Note how the 800x800 canvas needs to be scaled double with ctx2.scale(2,2) so that it appears correct. https://codepen.io/simonsarris/pen/eYexbOb https://codepen.io/simonsarris/pen/eYexbOb Pixel ratio is variable (window.devicePixelRatio), so this canvas pixel density is something you'll want to programmatically set for each user.
- Trufa 5y agoDude!! Freaking awesome!! Thanks a bunch!! That's exactly what I was looking for! If you have some sort of ko-fi account or whatever I'll buy you a coffee!
- simonsarris 5y agoHaha well, you could always subscribe to my newsletter for a month. You might get a kick out of it anyway. I'm glad to have solved your mystery!
- Trufa 5y agoDone!!
- etimberg 5y agoOne thing to keep in mind with the window.devicePixelRatio is that it is not a static value as it can change over time. Some common reasons it could change are if the user drags the browser window from a low density screen to a high density one. Additionally, it will change if the user zooms the page in and out.
- leeoniya 5y agoyou can use matchMedia to detect devicePixelRatio changes and re-sync: https://github.com/leeoniya/uPlot/blob/190134aa844cfa2a0c052e72501240efc6031ced/src/dom.js#L20-L33 https://github.com/leeoniya/uPlot/blob/190134aa844cfa2a0c052... everything stays crisp even as you browser-zoom. e.g. https://leeoniya.github.io/uPlot/demos/area-fill.html https://leeoniya.github.io/uPlot/demos/area-fill.html
- moron4hire 5y agoZooming also fires the Window's `resize` event, which will also catch a user rotating their smartphone/tablet, or, erh, resizing the window on desktop.
- leeoniya 5y agoresize and orientationchange don't change devicePixelRatio though, so they're somewhat different concerns.
- moron4hire 5y agoNo, it's the same concern. The concern is not "how do I keep track of just devicePixelRatio?" It's "how do I fill this window with a canvas at native resolution?" Resize handles all of that. Device changes orientation? Resize fires. User zooms on content (this changing devicePixelRatio)? Resize fires. Anything that changes the page's clientWidth/clientHeight causes the Resize event to fire. You need only the one event.
- deleted 5y ago
- altairprime 5y agoTo add a small caveat here for others, assuming 2x as the necessary scaling multiplier is not necessarily a safe shortcut when choosing your virtual canvas size; iPhones use 3x resources to look crisp, and 5K macOS users can have their 5120x2880 displays set to 2048x1152 or 1600x900 which are 2.5x and 3.2x respectively. It still helps when you do your canvas at 2x rather than just at 1x. But if you're looking for best-fidelity rather than better-fidelity, duly noted.
- ngcc_hk 5y agoWow. Great hint. Thanks.
- jorl17 5y agoI recently embarked on a months-long just-for-fun effort of porting an old AS3/Flash game to Haxe and make sure it worked on every imaginable Haxe target I could find. If there was something that bit me was how ugly everything looked inside the browser, even when using a WebGL backend. It turns out it was very obviously exactly what you described. You basically have to double the resolution to get it to look decent on retina and 4k screens. Once I found this out I was over the moon! (On a related note, colouring looks way off on the HTML5 target compared to native ones, and I spent an embarassing number of hours manually brute-forcing a shader to make everything look similar. Oh, and sound sucks in the browser. Oh, and Safari sucks. Seriously, it just sucks. The amount of hacks I put in place to workaround its egregious limitations, particularly regarding canvas operations is insane.)