dnass / svelte-canvas Goto Github PK
View Code? Open in Web Editor NEW๐จ Reactive canvas rendering with Svelte.
Home Page: https://dnass.github.io/svelte-canvas/
License: ISC License
๐จ Reactive canvas rendering with Svelte.
Home Page: https://dnass.github.io/svelte-canvas/
License: ISC License
I made a sprite system on svelte-canvas.
Click position is generate without actually display position, instead that with source position.
I think it is a bug.
https://svelte.dev/repl/431f480a2ef545538a6d97cec8bc3e9d?version=4.2.14
The <Canvas>
element throws hundreds of Uncaught TypeError
errors while hovering over it, the canvas works as intended, however it causes the browser to hang a lot when the debug console is open.
node_modules/svelte/internal/index.mjs:691 Uncaught TypeError: Cannot read property '$$' of undefined
at bubble (node_modules/svelte/internal/index.mjs:691)
at HTMLCanvasElement.eval (node_modules/svelte-canvas/src/forwardEvents.js:24)
I don't have enough experience with canvas and event forwarding to understand what might be going on, but the problem seems to be coming from this line
svelte-canvas/src/forwardEvents.js
Line 24 in cf1dd0e
Thanks for this library!
Currently I am not sure how I would make changes to Layers based on events happening at the Canvas level, particularly if there might be a non-trivial number of Layers (and sub-Layers?). I can of course use bind
but it feels strange to propagate events down the layers / components rather than up.
I was wondering if you have a solution for this already, or whether you have one in mind such as $: render = ({ context, width, height, event }) => {}
etc
Hi, I'm not sure if I'm going about this the wrong way, but currently, I have a render setup similar to this:
let render = ({
context,
}: {
context: CanvasRenderingContext2D;
}) => {
context.fillStyle = PlaygroundConfig.NODE_BG_COLOR;
context.beginPath();
context.arc(x, y, PlaygroundConfig.NODE_RADIUS, 0, 2 * Math.PI);
context.closePath();
context.fill();
context.font = `25px Jetbrains Mono, monospace`;
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillStyle = PlaygroundConfig.NODE_TEXT_COLOR;
context.fillText(value!.toString(), x, y);
};
I would like to do some stuff when the user hovers over the circle, so naturally, I've set up on:mouseenter and on:mouseleave events on the corresponding Layer component. The events work correctly, however when the mouse touches the text inside the circle, the mouseleave event is triggered, and then when exiting the text and entering the circle area again the mouseenter event is triggered. Ideally, I would only like the mouseleave event to trigger only after the mouse leaves the circle path itself.
I'm fairly new to Canvas, so I wouldn't be surprised if there's a better way to do this where I wouldn't encounter this issue. I'd very much appreciate any help solving this issue :)
I noticed my animation stutters unless I reference $t
in the render function. I am guessing the render function is cached by Svelte and subscribing to t
helps re-assign a new render function. Do you happen to know why this is happening? do I need to use the redraw function? if so, could you share an example of how I can use that function?
I initialized a completely new project using
npm init svelte@next project
and in the routes/index.svelte
I did paste the example code from the readme.
After running npm run dev
I encountered the error 'window is not defined'.
After googling a bit, it seems to be an SSR issue.
While looking at the svelte-canvas code I realized that it is using onMount in Canvas.svelte, which should be used when calling browser internal API.
But in the lines 46 and 73 there is a call to the window object which is probably the cause of my problem.
I had to use
{#if browser}
<Canvas width={640} height={640}>
<Layer {render} />
</Canvas>
{:else}
<p>This default content will be shown on pre-render and SSR</p>
{/if}
u/anniedillard on reddit pointed me to the solution: https://www.reddit.com/r/sveltejs/comments/qlz4q6/how_to_dev_with_sveltecanvas/
https://svelte.dev/repl/9876cca0f1c2410b8920fec3fbc81375?version=3.44.2
On first load, the chess pieces are not shown. Usually. Sometimes a few might be.
Make an edit to the source code to trigger live reload, and all the pieces will be drawn.
This happens even if I preload the images. Any ideas what could be going on here?
Hello!
I would like to use this lib to create layout for my modeltrain hobby. With svelteKit I need to use TypeScript. I could use TS in this format:
$: setup = ({ width, height }: { width: number; height: number })...
$: render = ({ context }: { context: CanvasRenderingContext2D })...
but I cannot find proper type for on:mousemove={onMove}
in https://dnass.github.io/svelte-canvas/examples/layer-events.
Can you help me?
I'm learning svelte-canvas
and unable to fit the height of the canvas to the window. The height would stay 640px and if I use append class h-full
, the window would overflow. The width works as expected which confuses me.
Here's my setup:
<script>
import { Canvas } from 'svelte-canvas';
let width, height;
</script>
<div bind:clientWidth={width} bind:clientHeight={height}>
<Canvas
{width}
{height}
style="cursor: pointer"
>
</Canvas>
</div>
<style>
div {
width: 100%;
height: 100%;
background-color: white;
}
</style>
Aside div or other native tags, I wanna draw other svelte components inside canvas. I have my reason why I would like to do that: rare use-case, but I need that. Is that possible with svelte-canvas? Any idea how can be that possible?
Hi, I'm pretty new to svelte.
I've been trying to get a video element to play in the svelte-canvas render function.
I've seen how to do it with vanilla JS and canvas here but I'm unsure how to translate it to make the video reactive for the render function to update.
I've got a REPL going here to show the basics of what I'm trying to do, any help would be appreciated
Please :)
I just found this library, it looks cool and easy to use, well done!
As a fun project, I've set myself the challenge of cloning Google Sheets using Svelte.
I realised that the enter sheet is actually built with canvas, hence how I found svelte-canvas.
Would svelte-canvas cut the mustard in my endeavour or would you recommend something like Konva?
I see that you handle mouse and touch events, but what about keyboard events?
When editing a formula, it is possible in google sheets to navigate the sheet using the keyboard arrows.
Submitting cell content with "Enter" or "Tab"
toggle a cell edit on "Enter"
etc...
I new to canvas so not sure what the simplest and/or technically possible solution is.
By the looks of it I might have to handle these outside the canvas context but it's still quite unclear to me at this time.
I'm looking to try Svelte with canvas and I found this library. I noticed you can immediately subscribe to t
, but wasn't sure if you can manually start/stop the timer.
Also, are there plans to use performance
over Date
? d3 timer uses this here: https://github.com/d3/d3-timer/blob/main/src/timer.js#L10
Edit: Also, nice to see that you added the support for pixel ratio! I spent hours trying to figure out why my canvas was so blurry.
svelte-canvas/src/lib/components/Canvas.svelte
Lines 149 to 153 in 3497d91
Not sure if this is svelte-canvas related but the DVD demo for example, goes to 100% cpu usage on Safari. It's fine in Firefox/Chrome. Does Safari just suck at canvas animations?
I've run into a couple of times that the canvas that I've set up is too large for the device that I'm using, eg. iphones being extra restrictive.
While I can test my width/height myself, the canvas that's set up by svelte-canvas
can more easily ensure that its calculated with the correct device pixel ratio + ensure that the hit-canvas is not too big either.
Here's the library: https://jhildenbiddle.github.io/canvas-size/
One thing svelte-canvas
could offer to do as well is to reduce the device pixel ratio until the canvas fits: If eg. area is 2x larger than possible, divide pixel ratio by 2 and render at a lower resolution.
I am not super familiar with JS, so it would be helpful to have examples on how to use the methods described in the documentation.
I am not sure if there's an object (say x) on which these methods need to be called (x.getCanvas()
) or if there's an argument that needs to be passed to these methods (getCanvas(x)
)
Some examples would make this much more accessible. Thanks!
It would be awesome if we could pass the alpha property on the Canvas component for optimizing rendering performance, see the official docs: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas?retiredLocale=de#turn_off_transparency
The same big canvas that I mentioned in #40 is, when it isn't too big, still too big to be seen in one full iPhone screen, but scrolling past it becomes a challenge as layerEvents
are active and that seems to be preventing touch scrolling completely.
Any idea what could be done to help here?
I'm not sure if this is supposed to work with Sveltekit or not, but it doesn't for me. Even a single import of the Canvas component fails for me:
<script>
import { Canvas } from 'svelte-canvas';
// import Background from './LandBackground.svelte';
</script>
<!-- <Canvas autoplay> -->
<!-- <Background /> -->
<!-- </Canvas> -->
It fails with:
[vite] Error when evaluating SSR module /src/lib/components/utility/LandFinder.svelte: failed to import "svelte-canvas"
|- TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".svelte" for /Users/stepheneddy/Dropbox/Dev/Crypto/Pixels/web-app/node_modules/svelte-canvas/dist/components/Canvas.svelte
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
at defaultLoad (node:internal/modules/esm/load:141:22)
at async ModuleLoader.load (node:internal/modules/esm/loader:409:7)
at async ModuleLoader.moduleProvider (node:internal/modules/esm/loader:291:45)
The layer event functionality that was recently added is awesome!
I'm trying to get it to work with a layer that has been resized, but the mouse events seem to ignore the resizing.
I've tried using context.scale
, context.setTransform
(in Layer setup
and render
) and resizing with css, but the mouse events seem to stick to the original size elements.
Do you have any suggestions on how to handle this? I want to resize the layers because I have the elements to be drawn in a specific size but I want to resize the canvas scale based on the screen size etc.
I'd love to be able to use this library in a typescript project! I am not seeing any type defs on @types/svelte-canvas
As an OSS maintainer myself I know its nice to get some positive feedback every once in a while, and I must say, this library made it so very simple to add a reactive canvas element into Svelte, so I thought I would send you a thanks and also let you know that I've used in production and that it so far works great ๐
My use case was to draw arrows between HTML elements in a graph layout generated by @dagrejs/dagre
and with this one I could easily reactively sync hover states etc with the HTML elements without any excessive re-rendering ๐
Can I write to this? I got error on that example.
Argument of type '(e: CanvasLayerEvent) => void' is not assignable to parameter of type '(e: LayerEventDetail) => void'.
Types of parameters 'e' and 'e' are incompatible.
Type 'LayerEventDetail' is missing the following properties from type 'CustomEvent<LayerEventDetail>': detail, initCustomEvent, bubbles, cancelBubble, and 20 more.ts(2345)
on:
Originally posted by @hyuckkim in #34 (comment)
I am using the library well.
so I drawn a transparent image then everything works right.
However I don't understand that why drawImage don't work with canvas event.
Is there a reason?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.