html5-canvas在滑块移动时绘制曲线

时间:2013-05-31 02:08:52

标签: javascript html5-canvas

我试图在滑块移动时绘制二次曲线。因此,将绘制滑块移动曲线。我想为二次曲线和贝塞尔曲线做这个。这是我的代码,它只适用于chrome

            <!DOCTYPE HTML>
                        <html>
                            <head>
                                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                                <meta name="viewport" content="width=device-width, initial-scale=1">

                                <style type="text/css">
                                    .wrapper {
                                        margin: 0 auto;
                                        width: 1000px;
                                    }
                                    .canHdr {
                                        float: left;
                                        width: 450px;
                                        height: 400px;
                                        border: 1px solid red;
                                    }
                                </style>

                            </head>
                            <body>
                                <form>
                                    <!-- wrapper -->
                                    <div class="wrapper">

                                        <!-- canHdr -->
                                        <div id="canHdr" class="canHdr" >

                                            <p>
                                                This is my 1st div with quadratic curve I want to draw this curve as I move the slider. I want to make it dynamic so when I should be able to change the curve points. Also I want to move an object on that curve as I am doing in my 3rd div.
                                            </p>

                                            <div class="canOuterHdr" >
                                                <canvas id="myCanvas1" width="300" height="195" style="position: relative;">
                                                    [No canvas support]
                                                </canvas>

                                            </div>

                                            <div id="slider1" class="newBg">
                                                <input id="slide1" type="range" min="0" max="100" step="1" value="0" onchange="counterSlider('slide1');" />
                                            </div>

                                        </div>
                                        <!--/ canHdr -->
                                        <!-- canHdr2 -->
                                        <div id="canHdr2" class="canHdr" >

                                            <p>
                                                This is my 2nd div. I have bezier curve. I want to make it dynamic so when I should be able to change the curve points. Also I want to move an object on that curve as I am doing in my 3rd div.
                                            </p>

                                            <div class="canOuterHdr" >
                                                <canvas id="myCanvas2" width="300" height="195" style="position: relative;">
                                                    [No canvas support]
                                                </canvas>

                                            </div>

                                            <div id="slider2" class="newBg">
                                                <input id="slide2" type="range" min="0" max="100" step="1" value="0" onchange="counterSlider('slide2');" />
                                            </div>

                                        </div>
                                        <!-- canHdr2 -->


                                    </div>
                                    <!-- /wrapper -->

                                    <script type="text/javascript">
                                       // newSprite('myCanvas3', 16, 170);
                                        quadraticCurve('myCanvas1', 18.8, 45, 28, 160, 228, 165);
                                        bezierCurve('myCanvas2', 20, 75, 55.2, 150.0, 200,100, 228, 165)
                                        function counterSlider(sID) {

                                            var slideVal = document.getElementById(sID).value;
                                            /*if (maxValue ==100){

                                             slideVal=slideVal/100;
                                             }*/
                                            slideVal = slideVal / 100;

                                            if (slideVal == 0) {

                                            /*  erase('myCanvas2');
                                                erase('myCanvas3');
                                                erase('myCanvas4');*/
                                                //newSprite('myCanvas1b', 18.8, 45);
                                               // newSprite('myCanvas3', 16, 170);

                                            } else if (slideVal > 0 && slideVal <= 34) {

                                                /*erase('myCanvas1');
                                                //erase('myCanvas1b');
                                                erase('myCanvas2');
                                                erase('myCanvas3');
                                                erase('myCanvas4');*/

                                            } else if (slideVal > 34 && slideVal <= 67) {

                                                /*erase('myCanvas1');

                                                erase('myCanvas2');
                                                erase('myCanvas3');
                                                erase('myCanvas4');*/

                                            } else if (slideVal > 67 && slideVal <= 100) {

                                                /*erase('myCanvas1');

                                                erase('myCanvas2');
                                                erase('myCanvas3');
                                                erase('myCanvas4');*/

                                            }
                                        }

                                        function erase(canvasId) {

                                            var canvas = document.getElementById(canvasId);
                                            var context = canvas.getContext("2d");
                                            context.beginPath();
                                            context.clearRect(0, 0, canvas.width, canvas.height);
                                            canvas.width = canvas.width;

                                        }

                                        /**********for backgroundImage********************/

                                        function quadraticCurve(canId, spx, spy, cpx, cpy, endx, endy) {

                                            var canvas = document.getElementById(canId);
                                            var ctx = canvas.getContext('2d');

                                            ctx.beginPath();
                                            ctx.moveTo(spx, spy);
                                            ctx.quadraticCurveTo(cpx, cpy, endx, endy);
                                            ctx.strokeStyle = "#eaca2d";
                                            ctx.stroke();

                                        }

                                        function bezierCurve(canId, spx, spy, cpx1, cpy1, cpx2, cpy2, endx, endy) {

                                            var canvas = document.getElementById(canId);
                                            var ctx = canvas.getContext('2d');

                                            ctx.beginPath();
                                            ctx.moveTo(spx, spy);
                                            ctx.quadraticCurveTo(cpx1, cpy1, cpx2, cpy2, endx, endy);
                                            ctx.strokeStyle = "#eaca2d";
                                            ctx.stroke();

                                        }

                                        function newSprite(canId, mvx, mvy) {
                                            var canvas = document.getElementById(canId);
                                            var ctx = canvas.getContext('2d');
                                            ctx.globalCompositeOperation = 'source-over';
                                            //ctx.globalCompositeOperation = "destination-over";
                                            ctx.beginPath();
                                            ctx.fillStyle = "#0077c1";
                                            ctx.arc(mvx, mvy, 6, 0, Math.PI * 2, true);
                                            ctx.closePath();
                                            ctx.fill();
                                        }



                                    </script>
                                </form>
                            </body>
                        </html>

这是jsfiddle的链接:http://jsfiddle.net/Y5yYD/1/

1 个答案:

答案 0 :(得分:4)

以下是如何逐步绘制quad&amp; amp;带滑块的三次贝塞尔曲线

示例小提琴:http://jsfiddle.net/m1erickson/auFam/

enter image description here

此功能将以Quad曲线的指定百分比返回XY点:

      // quadratic bezier: percent is 0-1
      function getQuadraticBezierXY(percent,startPt,controlPt,endPt) {
          var x = Math.pow(1-percent,2) * startPt.x + 2 * (1-percent) * percent * controlPt.x + Math.pow(percent,2) * endPt.x; 
          var y = Math.pow(1-percent,2) * startPt.y + 2 * (1-percent) * percent * controlPt.y + Math.pow(percent,2) * endPt.y; 
          return( {x:x,y:y} );
      }

此函数将返回指定百分比曲线百分比的XY点:

      // cubic bezier pct is 0-1
      function getCubicBezierXY(pct,startPt,controlPt1,controlPt2,endPt){
          var x=CubicN(pct,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
          var y=CubicN(pct,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
          return({x:x,y:y});
      }

      // cubic formula at percent distance
      function CubicN(pct, a,b,c,d) {
          var t2 = pct * pct;
          var t3 = t2 * pct;
          return a + (-a * 3 + pct * (3 * a - a * pct)) * pct
          + (3 * b + pct * (-6 * b + b * 3 * pct)) * pct
          + (c * 3 - c * 3 * pct) * t2
          + d * t3;
      }

以下是示例代码和小提琴:http://jsfiddle.net/m1erickson/auFam/

<!doctype html>
<html lang="en">
<head>

  <style>
      body{ background-color: ivory; }
      #wrapper{ position:relative; }
      canvas{ position:absolute; left:40px; top:5px; border:1px solid blue;}
      #amount{ position:absolute; left:1px; top:5px; margin-bottom:15px; width:23px; border:0; color:#f6931f; font-weight:bold; }
      #slider-vertical{ position:absolute; left:5px; top:40px; width:15px; height:225px; border:0px; color:#f6931f; font-weight:bold; }
  </style>

  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
  <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

  <script>

  $(function() {

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

      // starting value
      var startingSliderValue=50;
      drawBoth(startingSliderValue);


      $( "#slider-vertical" ).slider({
        orientation: "vertical",
        range: "min",
        min: 0,
        max: 100,
        value: startingSliderValue,
        slide: function( event, ui ) {
          $( "#amount" ).val( ui.value );
          drawBoth( $("#amount").val() );
        }
      });
      $( "#amount" ).val( $( "#slider-vertical" ).slider( "value" ) );


      function drawBoth(sliderValue){
          ctx.clearRect(0,0,canvas.width,canvas.height);
          drawQuadBezier(sliderValue/100);
          drawCubicBezier(sliderValue/100);
      }


      function drawQuadBezier(pct){
          var startPt={ x:18.8, y:45 };
          var controlPt={ x:28, y:160};
          var endPt={ x:228, y:165 };

          ctx.beginPath();
          ctx.moveTo(startPt.x,startPt.y);
          for(var p=0;p<=pct;p+=.01){
              var pt=getQuadraticBezierXY(p,startPt,controlPt,endPt)
              ctx.lineTo(pt.x,pt.y);
          }
          ctx.strokeStyle="green";
          ctx.stroke();
          var pt=getQuadraticBezierXY(pct,startPt,controlPt,endPt)
          drawDot(pt.x,pt.y,"#0077c1");
      }

      function drawCubicBezier(pct){
          var startPt={ x:20, y:75 };
          var controlPt1={ x:55.2, y:150};
          var controlPt2={ x:200, y:100};
          var endPt={ x:228, y:165 };

          ctx.beginPath();
          ctx.moveTo(startPt.x,startPt.y);
          for(var p=0;p<=pct;p+=.01){
              var pt=getCubicBezierXY(p,startPt,controlPt1,controlPt2,endPt);
              ctx.lineTo(pt.x,pt.y);
          }
          ctx.strokeStyle="red";
          ctx.stroke();
          var pt=getCubicBezierXY(pct,startPt,controlPt1,controlPt2,endPt);
          drawDot(pt.x,pt.y,"#0077c1");
      }

      // just draw a dot at xy
      function drawDot(x,y,color){
          ctx.fillStyle=color;
          ctx.beginPath();
          ctx.arc(x,y,6,0,Math.PI*2,false);
          ctx.closePath();
          ctx.fill();
      }


      // quadratic bezier: percent is 0-1
      function getQuadraticBezierXY(percent,startPt,controlPt,endPt) {
          var x = Math.pow(1-percent,2) * startPt.x + 2 * (1-percent) * percent * controlPt.x + Math.pow(percent,2) * endPt.x; 
          var y = Math.pow(1-percent,2) * startPt.y + 2 * (1-percent) * percent * controlPt.y + Math.pow(percent,2) * endPt.y; 
          return( {x:x,y:y} );
      }

      // cubic bezier pct is 0-1
      function getCubicBezierXY(pct,startPt,controlPt1,controlPt2,endPt){
          var x=CubicN(pct,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
          var y=CubicN(pct,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
          return({x:x,y:y});
      }

      // cubic formula at percent distance
      function CubicN(pct, a,b,c,d) {
          var t2 = pct * pct;
          var t3 = t2 * pct;
          return a + (-a * 3 + pct * (3 * a - a * pct)) * pct
          + (3 * b + pct * (-6 * b + b * 3 * pct)) * pct
          + (c * 3 - c * 3 * pct) * t2
          + d * t3;
      }

  });   // end $(function(){});

  </script>
</head>
<body>
    <div id="wrapper">
        <input type="text" id="amount" />
        <div id="slider-vertical"></div>
        <canvas id="canvas" width=300 height=300></canvas>
    </div>
</body>
</html>