Javascript 灵巧的全宽帆布

Javascript 灵巧的全宽帆布,javascript,html5-canvas,svelte,svelte-3,Javascript,Html5 Canvas,Svelte,Svelte 3,我是svelte的新手,我正在尝试使用svelte在全屏上渲染画布。听起来很容易,但我不能让它正常工作。我将width和height变量绑定到父对象的clientWidth/clientHeight,并使用这些变量设置画布的尺寸。现在的问题是,当调用onMount时,设置了width和height变量,但它们尚未应用于canvas元素。这意味着当画布第一次渲染时,它仍然具有初始维度,而不是父对象的维度。只有当我第二次渲染它时,它才具有正确的尺寸。如何使画布在第一次渲染时具有正确的维度,或者在画布

我是svelte的新手,我正在尝试使用svelte在全屏上渲染画布。听起来很容易,但我不能让它正常工作。我将
width
height
变量绑定到父对象的
clientWidth
/
clientHeight
,并使用这些变量设置画布的尺寸。现在的问题是,当调用
onMount
时,设置了
width
height
变量,但它们尚未应用于canvas元素。这意味着当画布第一次渲染时,它仍然具有初始维度,而不是父对象的维度。只有当我第二次渲染它时,它才具有正确的尺寸。如何使画布在第一次渲染时具有正确的维度,或者在画布具有正确的维度时再次渲染画布

你可以找到一个“工作”版本


从“svelte”导入{onMount};
让画布;
让ctx;
宽度=1007;
设高度=1140;
常量绘图=()=>{
ctx.clearRect(0,0,宽度,高度);
ctx.beginPath();
ctx.moveTo(宽/2-50,高/2);
ctx.弧(宽度/2,高度/2,50,0,2*Math.PI);
ctx.fill();
}
onMount(()=>{
ctx=canvas.getContext(“2d”);
draw();
设置超时(绘图,5000);
});
.集装箱{
宽度:100%;
身高:100%;
}

您可以通过等待下一个“滴答声”来解决此问题

从'svelte'导入{onMount,tick};
onMount(异步()=>{
ctx=canvas.getContext(“2d”);
画布宽度=宽度;
canvas.height=高度;
等待滴答声
draw();
});
await tick()
所做的是有效地暂停执行,直到所有当前更改都应用于dom


就我而言,您的代码似乎运行良好。画布始终是完整的客户端宽度和高度,无论是在初始加载、页面刷新还是在调整大小之后。我甚至在不同的浏览器中尝试过,总是像预期的那样工作?嘿,谢谢你的评论。是,画布的大小已正确调整。问题是,当调用onMount时,宽度和高度变量设置正确,但尚未应用于画布。这意味着调用draw()时,宽度/高度变量与画布的宽度/高度不对应。只有在下一次渲染时,画布的尺寸才会被设置,这会导致draw()中的黑色圆圈消失。效果很好!谢谢!
tick()
在这里是不必要的,不是吗?重要的一点是
canvas.width
canvas.height
设置在
draw()之前(并且
{width}和
{height}应该相应地从
中删除),如果从canvas元素本身删除
{width}
,则这是正确的,没有必要打勾。
<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>