【问题标题】:Dynamically Resize Complex Canvas Path HTML5动态调整复杂画布路径 HTML5
【发布时间】:2012-03-05 08:55:36
【问题描述】:

我使用 HTML5 画布中的路径创建了卡车的绘图。画布图像本身接近 900 行代码,我已经实现了一个函数来根据由窗口的宽度/高度确定的调整大小比率来绘制图像。最终结果是画布和画布中的所有元素都会动态调整大小以适应窗口的内容。

请记住,我只是在使用画布的第二天,所以我可能错过了一些东西,但必须有一种更简单的方法来完成我正在做的事情。所以,我的问题是:当涉及复杂路径时,是否有更简单的方法/方法来调整画布及其内部元素的大小?

我的代码示例如下,仅根据身体负载调整大小,我尚未将其附加到 onresize 侦听器...我无法将其全部放入,因此您可以在此处获取完整源代码:

http://www.epixseo.com/fullsource.txt

如您所见,我将 canvasWidth 传递给 semitruckv1 函数并确定调整大小比率....然后将每个坐标和 lineWidth 与该调整大小比率相乘...这需要一段时间...(您应该能够复制+粘贴完整的源代码并在您的 IDE 中本地运行)

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8" />
  <title>Semi truck</title>
  <style type="text/css">
  body {
      margin:0px;
  }
  </style>
  <script>

    function init() {

        var viewportWidth = window.innerWidth;
        var viewportHeight = window.innerHeight;

        var canvas = document.getElementById("canvas");

        var canvasWidth = viewportWidth;
        var canvasHeight = viewportHeight;
        canvas.style.position = "fixed";
        canvas.setAttribute("width", canvasWidth);
        canvas.setAttribute("height", canvasHeight);

        var ctx = canvas.getContext("2d");

        semitruckv1(ctx, canvasWidth);
    }

    function semitruckv1(ctx, canvasWidth) {
        //347 default width of initial image

        var resizeRatio = canvasWidth/347;
      // semitruckv1/Path
      ctx.save();
      ctx.beginPath();
      ctx.moveTo(251.3*resizeRatio, 143.8*resizeRatio);
      ctx.bezierCurveTo(251.3*resizeRatio, 146.9*resizeRatio, 253.9*resizeRatio, 149.5*resizeRatio, 257.0*resizeRatio, 149.5*resizeRatio);
      ctx.bezierCurveTo(260.2*resizeRatio, 149.5*resizeRatio, 262.8*resizeRatio, 146.9*resizeRatio, 262.8*resizeRatio, 143.8*resizeRatio);
      ctx.bezierCurveTo(262.8*resizeRatio, 140.6*resizeRatio, 260.2*resizeRatio, 138.1*resizeRatio, 257.0*resizeRatio, 138.1*resizeRatio);
      ctx.bezierCurveTo(253.9*resizeRatio, 138.1*resizeRatio, 251.3*resizeRatio, 140.6*resizeRatio, 251.3*resizeRatio, 143.8*resizeRatio);
      ctx.closePath();
      ctx.strokeStyle = "rgb(1, 1, 1)";
      ctx.lineWidth = 1*resizeRatio;
      ctx.stroke();

      // semitruckv1/Path
      ctx.beginPath();
      ctx.moveTo(243.3*resizeRatio, 143.8*resizeRatio);
      ctx.bezierCurveTo(243.3*resizeRatio, 151.4*resizeRatio, 249.5*resizeRatio, 157.5*resizeRatio, 257.0*resizeRatio, 157.5*resizeRatio);
      ctx.bezierCurveTo(264.6*resizeRatio, 157.5*resizeRatio, 270.8*resizeRatio, 151.4*resizeRatio, 270.8*resizeRatio, 143.8*resizeRatio);
      ctx.bezierCurveTo(270.8*resizeRatio, 136.2*resizeRatio, 264.6*resizeRatio, 130.1*resizeRatio, 257.0*resizeRatio, 130.1*resizeRatio);
      ctx.bezierCurveTo(249.5*resizeRatio, 130.1*resizeRatio, 243.3*resizeRatio, 136.2*resizeRatio, 243.3*resizeRatio, 143.8*resizeRatio);
      ctx.closePath();
      ctx.lineWidth = 1*resizeRatio;
      ctx.stroke();

      // semitruckv1/Path
      ctx.beginPath();
      ctx.moveTo(241.3*resizeRatio, 143.8*resizeRatio);
      ctx.bezierCurveTo(241.3*resizeRatio, 152.5*resizeRatio, 248.3*resizeRatio, 159.6*resizeRatio, 257.0*resizeRatio, 159.6*resizeRatio);
      ctx.bezierCurveTo(265.7*resizeRatio, 159.6*resizeRatio, 272.8*resizeRatio, 152.5*resizeRatio, 272.8*resizeRatio, 143.8*resizeRatio);
      ctx.bezierCurveTo(272.8*resizeRatio, 135.1*resizeRatio, 265.7*resizeRatio, 128.0*resizeRatio, 257.0*resizeRatio, 128.0*resizeRatio);
      ctx.bezierCurveTo(248.3*resizeRatio, 128.0*resizeRatio, 241.3*resizeRatio, 135.1*resizeRatio, 241.3*resizeRatio, 143.8*resizeRatio);
      ctx.closePath();
      ctx.lineWidth = 0.3*resizeRatio;
      ctx.stroke();

      // semitruckv1/Path
      ctx.beginPath();
      ctx.moveTo(232.5*resizeRatio, 143.8*resizeRatio);
      ctx.bezierCurveTo(232.5*resizeRatio, 157.3*resizeRatio, 243.5*resizeRatio, 168.3*resizeRatio, 257.0*resizeRatio, 168.3*resizeRatio);
      ctx.bezierCurveTo(270.6*resizeRatio, 168.3*resizeRatio, 281.6*resizeRatio, 157.3*resizeRatio, 281.6*resizeRatio, 143.8*resizeRatio);
      ctx.bezierCurveTo(281.6*resizeRatio, 130.2*resizeRatio, 270.6*resizeRatio, 119.3*resizeRatio, 257.0*resizeRatio, 119.3*resizeRatio);
      ctx.bezierCurveTo(243.5*resizeRatio, 119.3*resizeRatio, 232.5*resizeRatio, 130.2*resizeRatio, 232.5*resizeRatio, 143.8*resizeRatio);
      ctx.closePath();
      ctx.lineWidth = 0.5*resizeRatio;
      ctx.stroke();

      //THERE ARE ABOUT ANOTHER 800 LINES OF PATH DRAWING DOWNLOAD THE FULL SOURCE TO VIEW: www.epixseo.com/fullsource.txt

    }
  </script>
 </head>
 <body onLoad="init()">
   <canvas id="canvas"></canvas>
 </body>
</html>

【问题讨论】:

    标签: javascript html canvas html5-canvas


    【解决方案1】:

    画布上下文有一个 scale 函数,它会自动缩放画布上绘制的任何内容,直到上下文恢复,或者将比例更改回 1。请参阅 https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Transformations#A_scale_example

    【讨论】:

    • 教程+1,我以前看过比例,但是在阅读了该教程之后,比例似乎是我应该前进的方向,明天我会试一试,如果这是我需要的得到答案,感谢您抽出宝贵的时间
    • 我可以使用 scale 来达到我想要的结果,感谢您的帮助
    【解决方案2】:

    我对使用画布了解不多(我有 GameMaker:HTML5 为我做),但你不能只加载一个 SVG 图像并以适当的大小绘制它吗?

    【讨论】:

    • 这是作为移动应用程序部署的,不幸的是 android 和 SVG 还不能很好地相处,否则我很想使用 SVG,但在这种情况下不能,所以我不得不求助于 canvas
    【解决方案3】:

    处理此问题的最佳方法取决于您未来的应用程序,例如:

    1. 如果您只是在绘制同一辆卡车,但想在调整页面大小时重绘,请使用画布的toDataURL 方法来拉取画布的图像,然后调整画布大小(使用 .width 和 .height 而不是 css因为您将拉伸图像)然后使用 drawImage 方法将该数据 url 绘制回画布(或将其放入 img 标签中)。
    2. 如果您计划为卡车的一部分(例如车轮)制作动画,则应使用与第一步相同的策略,但不要只拉动卡车的图像。例如,如果您正在为车轮制作动画:拉动卡车主体的图像,然后拉动仅车轮的图像,然后在调整大小时绘制卡车一次,然后连续重绘车轮,每帧稍微旋转它们。李>

    【讨论】:

      猜你喜欢
      • 2019-04-12
      • 2020-12-23
      • 2011-11-15
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-06
      • 2014-11-04
      相关资源
      最近更新 更多