最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Responsive full width canvas in sveltejs - Stack Overflow

programmeradmin8浏览0评论

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

发布评论

评论列表(0)

  1. 暂无评论