【问题标题】:Responsive full width canvas in sveltejssveltejs 中的响应式全宽画布
【发布时间】:2020-11-21 08:34:07
【问题描述】:

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

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

<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>

【问题讨论】:

  • 就我而言,您的代码似乎运行良好。 svelte.dev/repl/49b8091d3d5c400b8c912be90d03c93e?version=3.24.0 画布始终是完整的客户端宽度和高度,无论是在初始加载、页面刷新还是调整大小之后。我什至在不同的浏览器中尝试过,总是按预期工作?
  • 嘿,谢谢你的评论。是的,画布的大小已正确调整。问题是,当调用 onMount 时,宽度和高度变量设置正确,但尚未应用于画布。这意味着当 draw() 被调用时,宽度/高度变量不对应于画布的宽度/高度。只有在下一次渲染时才会设置画布的尺寸,这会导致 draw() 中的黑色圆圈消失。

标签: javascript html5-canvas svelte svelte-3


【解决方案1】:

你可以通过等待下一个'tick'来解决这个问题

import { onMount, tick } from 'svelte';

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

await tick() 所做的是有效地暂停执行,直到所有当前更改都已应用于 dom

tick in the docs

【讨论】:

  • 有效!非常感谢!
  • 这里不需要tick(),不是吗?重要的一点是canvas.widthcanvas.height 设置在draw() 之前(并且{width} and {height}` 应该相应地从&lt;canvas&gt; 中删除)
  • 没错,如果你把画布元素本身的{width}{height}去掉,就不需要打勾了。
猜你喜欢
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 2016-04-26
  • 1970-01-01
相关资源
最近更新 更多