动态调整复杂画布路径HTML5

3
我使用HTML5画布中的路径创建了一辆卡车的绘图。画布图像本身接近900行代码,我实现了一个函数来根据窗口的宽度/高度确定缩放比例来绘制图像。最终结果是画布及其内部所有元素都会动态调整大小以适应窗口内容。
请注意,我只是在使用画布的第二天,所以可能会漏掉一些东西,但肯定有更简单的方法来完成我正在做的事情。因此,我的问题是:当涉及复杂路径时,是否有更简单的方法/方法来调整画布及其内部元素的大小? 下面是我的代码示例,仅在body加载时调整大小,我尚未将其附加到onresize侦听器上...我无法将其全部放入,您可以在此处获取完整源代码:

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

正如您所看到的,我将canvasWidth传入semitruckv1函数并确定一个调整比例... 然后将每个坐标和线宽乘以该调整比例... 这需要一段时间... (您应该可以复制+粘贴完整的源代码并在本地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>
3个回答

5

对于这篇教程点个赞,我之前看过有关比例尺的内容,但是在阅读了这篇教程后,比例尺似乎是我应该探索的方向,我明天会试一试,如果它正是我需要的,你就解决了我的问题。感谢你抽出时间来帮助我。 - Jeff Wooden
我成功地使用了比例尺来达到我想要的结果,感谢您的帮助。 - Jeff Wooden

0

处理这个问题的最佳方式取决于您未来的应用,例如:

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

0

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


这将作为移动应用程序部署,不幸的是,Android和SVG目前还不能很好地兼容,否则我很想使用SVG,但在这种情况下无法使用,所以我不得不使用画布。 - Jeff Wooden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接