javascript - Responsive full width canvas in sveltejs - Stack Overflow

I'm quite new to svelte and I'm trying to get a canvas to render on the full screen using sve

I'm quite new to svelte and I'm trying to get a canvas to render on the full screen using svelte. Sounds quite easy to do, but I can't get it to work properly. I'm binding a width and height variable to the clientWidth/clientHeight of the parent and using these variables to set the dimensions of the canvas. The issue now is that when onMount is called, the width and height variables are set but they are not applied to the canvas element yet. This means when the canvas renders for the first time, it still has the initial dimensions and not the ones of the parent. Only when I render it a second time it has the proper dimensions. How can get the canvas to have the right dimensions on the first render or render the canvas again when it has the proper dimensions?

Here you can find a "working" version.

<script>
  import { onMount } from "svelte";

  let canvas;
  let ctx;
  let width = 1007;
  let height = 1140;

    const draw = () => {
    ctx.clearRect(0, 0, width, height);
    ctx.beginPath();
    ctx.moveTo(width/2 - 50, height/2);
    ctx.arc(width/2, height/2, 50, 0, 2 * Math.PI);
    ctx.fill();
    }
    
  onMount(() => {
    ctx = canvas.getContext("2d");
        draw();
        setTimeout(draw, 5000);
  });
</script>

<style>
  .container {
    width: 100%;
    height: 100%;
  }
</style>

<div
  class="container"
  bind:clientWidth={width}
  bind:clientHeight={height}>
  <canvas bind:this={canvas} {width} {height} />
</div>

I'm quite new to svelte and I'm trying to get a canvas to render on the full screen using svelte. Sounds quite easy to do, but I can't get it to work properly. I'm binding a width and height variable to the clientWidth/clientHeight of the parent and using these variables to set the dimensions of the canvas. The issue now is that when onMount is called, the width and height variables are set but they are not applied to the canvas element yet. This means when the canvas renders for the first time, it still has the initial dimensions and not the ones of the parent. Only when I render it a second time it has the proper dimensions. How can get the canvas to have the right dimensions on the first render or render the canvas again when it has the proper dimensions?

Here you can find a "working" version.

<script>
  import { onMount } from "svelte";

  let canvas;
  let ctx;
  let width = 1007;
  let height = 1140;

    const draw = () => {
    ctx.clearRect(0, 0, width, height);
    ctx.beginPath();
    ctx.moveTo(width/2 - 50, height/2);
    ctx.arc(width/2, height/2, 50, 0, 2 * Math.PI);
    ctx.fill();
    }
    
  onMount(() => {
    ctx = canvas.getContext("2d");
        draw();
        setTimeout(draw, 5000);
  });
</script>

<style>
  .container {
    width: 100%;
    height: 100%;
  }
</style>

<div
  class="container"
  bind:clientWidth={width}
  bind:clientHeight={height}>
  <canvas bind:this={canvas} {width} {height} />
</div>
Share Improve this question asked Jul 31, 2020 at 13:28 FlavioFlavio 1,5975 gold badges20 silver badges30 bronze badges 2
  • Your code seems to be working fine as far as I'm concerned. svelte.dev/repl/49b8091d3d5c400b8c912be90d03c93e?version=3.24.0 the canvas is always full client width & height, be it on initial load, page refresh or after a resize. I even tried it in different browsers, always worked as expected? – Thomas Hennes Commented Aug 1, 2020 at 11:13
  • Hey, thanks for you ment. Yes the size of the canvas is adjusted correctly. The issue is that when onMount is called the width and height variables are set correctly but they are not applied to the canvas yet. This means that when draw() is called the width/height variables don't correspond to the width/height of the canvas. Only on the next render the dimensions of the canvas are set which causes the black circle from draw() to disappear. – Flavio Commented Aug 2, 2020 at 11:10
Add a ment  | 

1 Answer 1

Reset to default 6

You can solve this by waiting for the next 'tick'

import { onMount, tick } from 'svelte';

onMount(async () => {
  ctx = canvas.getContext("2d");
  canvas.width = width;
  canvas.height = height;
  await tick()
  draw();
});

What await tick() does is to effectively pause execution until all current changes have been applied to the dom

tick in the docs

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744365634a4570688.html

相关推荐

  • javascript - Responsive full width canvas in sveltejs - Stack Overflow

    I'm quite new to svelte and I'm trying to get a canvas to render on the full screen using sve

    7天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信