最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dynamically Resize Complex Canvas Path HTML5 - Stack Overflow

programmeradmin6浏览0评论

I've created a drawing of a truck using paths in an HTML5 canvas. The canvas image itself is close to 900 lines of code and I've implemented a function to draw the image based on a resize ratio determined by the window's width/height. The end result is that the canvas and all elements within the canvas are dynamically resized to fit the contents of the window.

Keep in mind that I'm only on day 2 of utilizing the canvas, so I may have missed something, but there has got to be an easier way to acplish what I am doing. So, my question is: Is there an easier way / method to acplish resizing the canvas and its internal elements when plex paths are involved?

A sample of my code is below and only resizes on body load, I've not attached it to an onresize listener yet... I could not fit it all in so you can get the full source here:

.txt

as you can see, I pass the canvasWidth into the semitruckv1 function and determine a resize ratio.... then multiply every coordinate and lineWidth with that resize ratio... which takes a while to do... (you should be able to copy+paste the full source code and run local in your 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/fullsource.txt

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

I've created a drawing of a truck using paths in an HTML5 canvas. The canvas image itself is close to 900 lines of code and I've implemented a function to draw the image based on a resize ratio determined by the window's width/height. The end result is that the canvas and all elements within the canvas are dynamically resized to fit the contents of the window.

Keep in mind that I'm only on day 2 of utilizing the canvas, so I may have missed something, but there has got to be an easier way to acplish what I am doing. So, my question is: Is there an easier way / method to acplish resizing the canvas and its internal elements when plex paths are involved?

A sample of my code is below and only resizes on body load, I've not attached it to an onresize listener yet... I could not fit it all in so you can get the full source here:

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

as you can see, I pass the canvasWidth into the semitruckv1 function and determine a resize ratio.... then multiply every coordinate and lineWidth with that resize ratio... which takes a while to do... (you should be able to copy+paste the full source code and run local in your 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./fullsource.txt

    }
  </script>
 </head>
 <body onLoad="init()">
   <canvas id="canvas"></canvas>
 </body>
</html>
Share Improve this question asked Feb 13, 2012 at 22:53 Jeff WoodenJeff Wooden 5,4992 gold badges21 silver badges24 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 5

A canvas context has a scale function, which will automatically scale anything drawn on the canvas until the context has been restored, or you change the scale back to 1. See https://developer.mozilla/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Transformations#A_scale_example

I don't know much about using canvas (I have GameMaker:HTML5 do it for me), but can't you just load an SVG image and draw it at the appropriate size?

the best way to handle this depends on your future applications for example:

  1. If you are just drawing the same truck but want to redraw when the page is resized instead use toDataURL method of the canvas to pull the image of the canvas then resize the canvas (using .width and .height instead of css because you will stretch the image) then use the drawImage method to draw that data url back to the canvas (or just plop it into an img tag).
  2. If you plan to animate a piece of the truck, the wheels for example, you should use the same strategy as step one however instead of pulling an image of the truck pull only pieces. For example if you are animating the wheels: Pull an image of the main body of the truck then pull an image of just a wheel, then draw the truck once at resize, but then continuously redraw the wheels rotating them slightly every frame.
发布评论

评论列表(0)

  1. 暂无评论