【问题标题】:Paper.js won't resize the canvas correctlyPaper.js 不会正确调整画布大小
【发布时间】:2015-03-06 09:54:47
【问题描述】:

我正在尝试Paper.js,但似乎我一开始就被困住了。

resize="true" 添加到canvas 标记应该使元素与浏览器窗口一样高和宽。但是,这样做会导致一些相当奇怪的行为。

我希望画布在加载页面后立即调整到视口,但它没有这样做,这就是我最初认为它根本没有调整大小的原因。然而,实际发生的事情更奇怪:画布一开始是默认大小 300x150,当我调整视口大小时,它会增长 - 缓慢但无限

为了记录,我尝试使用 data-paper-resize="true" 或仅使用 resize,或使用 Chrome 代替 Firefox - 均无济于事。

如果这个问题是由我的一些莫名其妙的奇怪设置引起的,我不期待答案。但是,我想知道这个问题是否普遍(甚至根本不知道存在)并且有已知的原因和解决方案。

这是我正在使用的代码:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="paper-full.min.js"></script>
        <script type="text/paperscript" canvas="myCanvas">

            var path = new Path();
            path.strokeColor = 'black';
            path.moveTo(new Point(120, 120));
            path.lineTo(new Point(500, 500));

        </script>
    </head>
    <body>
        <canvas id="myCanvas" style="border: 1px dotted red;" resize="true"></canvas>
    </body>
</html>

【问题讨论】:

  • 尝试将脚本放在结束

标签: javascript paperjs


【解决方案1】:

将以下 CSS 添加到您的项目中:

<style type="text/css">
html,
body {
    margin: 0;
    overflow: hidden;
    height: 100%;
}

/* Scale canvas with resize attribute to full size */
canvas[resize] {
    width: 100%;
    height: 100%;
}
</style>

【讨论】:

  • 看起来是这样做的!我想知道为什么 CSS 是必要的(例如,用户必须处理的东西),以及为什么文档似乎没有提到它。想要在 Paper.js 中使用全尺寸画布的人是否必须手动添加这些样式?
  • 我只需要全宽,所以canvas[resize] { width: 100%; height: 600px; } 为我做了。谢谢!!! (我使用的是 Paper.js 0.9.22)
  • 使用 overflow: hidden 可能会在以后导致麻烦。将画布设置为 display: block ,您可以在没有滚动条的情况下移除溢出。
  • @user3337813 如何以编程方式设置画布[resize]?
【解决方案2】:

我在 Github 上为此打开了一个问题,这似乎是 0.9.22 中引入的一个错误。 @Skalkaz 向我指出了这个问题。

这是未决问题:https://github.com/paperjs/paper.js/issues/662

您也可以在等待补丁时降级到 0.9.21。

【讨论】:

  • 啊,谢谢你解决这个问题。 :) 很高兴知道我不是唯一一个有这个问题的人。
  • 在 github 问题之后,这不会被修复,因此等待补丁不是一个可行的选择。细节在问题中,但作者认为画布大小是一项 CSS 任务,而不是纸质任务。我认为他是对的。
  • 对于未来遇到同样问题的人 - 库作者知道这是一个问题,但现在还没有机会更新文档以包含对 CSS 的需求。
【解决方案3】:

另一个选项是 - 如果您使用设置比例(相对于身体) - 覆盖纸张的视图:

var pageWidth = document.getElementsByTagName("BODY")[0].clientWidth
var pageHeight = document.getElementsByTagName("BODY")[0].clientHeight
view.size.width = pageWidth * myWidthScale
view.size.height = pageHeight * myHeightScale
center = new Point(width / 2, pageHeight / 2)
view.center = center

【讨论】:

  • 我不会这样做,因为它只会工作一次,如果调整窗口大小则不会。它也绑定到 body 并且不会在 DOM 中的任何其他元素上工作。
  • 此外,示例不完整,没有小提琴,在实际代码演示中没有上下文使用,没有 myWidthScalemyHeightScale 的定义或示例。
【解决方案4】:

对于仍然遇到此问题的任何人,这就是我的 TypeScript/React 项目中对我有用的方法。我遇到了 Paper.js 调整大小逻辑似乎与我在应用程序其他地方的现有调整大小逻辑冲突/不同步的问题(可能正在进行一些数据竞争)。不管怎样,我意识到manually update the viewSize of the canvas是可能的。

使用lodash debounce,可以在用户完成窗口大小调整后使用实际画布大小重新校准 Paper.js 视图。在我的示例中,我选择仅在用户调整大小 500 毫秒后才执行此操作,以免在调整大小时导致性能问题,并确保所有样式都已正确更新和重新渲染。这是我登陆的 TypeScript/React 示例,现在似乎运行良好:

export default function ChalkboardCanvas() {

// get a direct reference to the canvas element
const canvasRef = useRef(null);

 /** 
  * Sometimes the Paper.js view gets out of sync when resizing
  * manually update it instead once the user is done resizing 
  */
  const onResize = useCallback(debounce(() => {
    if (canvasRef.current) {
      const { width, height } = canvasRef.current.getBoundingClientRect();
      paper.view.viewSize = new paper.Size(width, height);
    }
  }, 500, {
    leading: false,
    trailing: true,
  }), []);

  useEffect(() => {
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, [onResize]);

return (
     <canvas
        style={{
          width: '100%',
          height: '100%',
        }}
        ref={canvasRef}
        resize="true"
      />
  );
}

【讨论】:

    猜你喜欢
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    相关资源
    最近更新 更多