Is there a way to make the `<canvas>` used b...
# compose-web
s
Is there a way to make the
<canvas>
used by Compose fit the size of its contents? Currently it'll simply use whatever space was allocated by the browser, but what if we want it the other way around? I've built a workaround using Layout, to measure content (ignoring constraints, but coercing to max window size) and then update the canvas size from there. It... works, but sometimes during height changes (that involve text wrapping), there's a frame where it'll just draw blank. I hope this use-case gets officially supported at some point.
a
im confused what you are asking, as this seems like a css question than a compose question. are you asking how to make a canvas (html element) fit the size of its parent?
s
Not really, my question is not about "filling" the parent, it's the opposite, "fitting" the content of the
<canvas>
(i.e. the `@Composable`s inside). This cannot be done from CSS because it has no clue what's in the
<canvas>
etc... The JavaScript (Kotlin JS/Wasm) code is supposed to handle all sizing matters (internal canvas size as well as the element size).
In other words, if I put a single button in the
ComposeWindow
, I want the size of the HTML element (both
viewportContainer
and the created
canvas
) to match the size of that button, and stay in sync with the content size. Obviously this wouldn't be desired as a default behavior (most uses will either be full-screen, or will live in a fixed-size container), but this would be useful as an option to e.g. have the rest of the usual HTML/CSS layouts move out of the way/reflow on size changes inside the Composable.
a
ah gotcha. so you want the canvas to change it's size according to some composable size. i used to do the same at composeexamples.com with some javascript. I set a function on the html's
window
using javascript ie
window.onSizeUpdated = (value) =>{}
), then call this function from your composable when the composable is measured (ie
onPlaced {}
). within the onSizeUpdated, used the value you passed to update the size of the canvas
a word of advice: not worth the hustle. lots of debugging to get right, and the result might not be as smooth as you might expect
s
Yeah, I did something like that, directly using Kotlin (get the Composable size in
onSizeChanged
, and set the canvas size to it), and it didn't work. I guess it's because
onSizeChanged
is already too late. Didn't think of using
onPlaced
! Tried again using a
Layout
, measuring the content with constraints set to the window size (should probably replace it with the container size), and literally updating the cavnas size right there (side effects during layout! yohooo!). It kinda worked tho! E.g. one peculiar thing I spent a full hour debugging was that the container
div
that contained the
canavas
element was slightly larger than the canvas, causing Compose to keep resizing the canvas to match it on every size change. I forgot what but one line of CSS fixed it 😛 And even after getting it somewhat working (my demo was a text, that flowed as i shrunk the window), when the text height, the canvas goes blank for one frame. That might be fine if people were resizing windows manually (causing another window size change fixes it), but most users will trigger such changes on maximizing/minimizing, which means the app will receive a single change, and will stay blank 🥶 So yeah, pretty tricky as of now. That's why something built-in would be great.
Now that I re-explained what I did, I think that the issue is that Compose already runs some code on size changes (from the container div), and my resize handling code conflicted with that causing the weird drawing issues? No clue really, there's so many factors at play it's hard to know 😅
a
sending you hopes and prayers
🙏 1
🙌 1