2015-11-23 24 views
0

这里的的jsfiddle:https://jsfiddle.net/y06jberm/1/的Javascript画布不能画多条曲线

我打算动用3条以下,从这个职位第二高的答案例如随机生成的曲线:how to draw smooth curve through N points using javascript HTML5 canvas?

但画布只能说明尽管事实上我通过曲线循环,并在绘制每条曲线后调用.stroke,但是始终是一条曲线。函数drawCurve不知何故只被调用一次,但我不明白为什么它被阻止。任何人都可以从此代码中发现任何问题吗太感谢了。

  var curves = []; 
      var curX = 0; 
      for(var j = 0; j < 3; j++){ 
       x = []; 
       for(var i = 0; i < 100; i++){ 
        x.push(i*10); 
        x.push(100-Math.floor(Math.random()*100)); 
       } 
       console.log(x); 
       curves.push(x); 
      } 
      var colors = ["red", "blue", "green"]; 
      var canvas = document.getElementById('canvas'); 
      var ctx = canvas.getContext('2d'); 
      // console.log(ctx); 
      var tension = 1; 
      for(var i = 0; i < curves.length; i++){ 
       ctx.stroke(); 
       ctx.strokeStyle = colors[i]; 
       console.log(colors[i]); 
       drawCurve(ctx, curves[i]); 
      } 

      // var inter = setInterval(moveCurve, 20); 
      var interval = setInterval(loadCurve, 200); 

      function moveCurve(){ 
       curves[0].splice(0,2); 
       for(var i = 0; i < curves[0].length; i+=2){ 
        curves[0][i] -= 10; 
       } 
       curves[0].push(990, Math.floor(Math.random()*100)); 
       ctx.strokeStyle = colors[0]; 
       ctx.clearRect(0,0,canvas.width, canvas.height); 
       drawCurve(ctx, curves[0]); 
      } 


      function drawCurve(ctx, ptsa, tension, isClosed, numOfSegments, showPoints) { 

       showPoints = showPoints ? showPoints : false; 
       showPoints = true; 
       // ctx.stroke(); 
       ctx.beginPath(); 

       drawLines(ctx, getCurvePoints(ptsa, tension, isClosed, numOfSegments)); 
       // drawLines(ctx, ptsa); 

       // if (showPoints) { 
       //  ctx.stroke(); 
       //  // ctx.beginPath(); 
       //  for(var i=0;i<ptsa.length-1;i+=2) 
       //    ctx.rect(ptsa[i] - 2, ptsa[i+1] - 2, 4, 4); 
       // } 
      } 

      function getCurvePoints(pts, tension, isClosed, numOfSegments) { 

       // use input value if provided, or use a default value 
       tension = (typeof tension != 'undefined') ? tension : 0.5; 
       isClosed = isClosed ? isClosed : false; 
       numOfSegments = numOfSegments ? numOfSegments : 16; 

       var _pts = [], res = [], // clone array 
        x, y,   // our x,y coords 
        t1x, t2x, t1y, t2y, // tension vectors 
        c1, c2, c3, c4,  // cardinal points 
        st, t, i;  // steps based on num. of segments 

       // clone array so we don't change the original 
       _pts = pts.slice(0); 

       // The algorithm require a previous and next point to the actual point array. 
       // Check if we will draw closed or open curve. 
       // If closed, copy end points to beginning and first points to end 
       // If open, duplicate first points to befinning, end points to end 
       if (isClosed) { 
        _pts.unshift(pts[pts.length - 1]); 
        _pts.unshift(pts[pts.length - 2]); 
        _pts.unshift(pts[pts.length - 1]); 
        _pts.unshift(pts[pts.length - 2]); 
        _pts.push(pts[0]); 
        _pts.push(pts[1]); 
       } 
       else { 
        _pts.unshift(pts[1]); //copy 1. point and insert at beginning 
        _pts.unshift(pts[0]); 
        _pts.push(pts[pts.length - 2]); //copy last point and append 
        _pts.push(pts[pts.length - 1]); 
       } 

       // ok, lets start.. 

       // 1. loop goes through point array 
       // 2. loop goes through each segment between the 2 pts + 1e point before and after 
       for (i=2; i < (_pts.length - 4); i+=2) { 
        for (t=0; t <= numOfSegments; t++) { 

         // calc tension vectors 
         t1x = (_pts[i+2] - _pts[i-2]) * tension; 
         t2x = (_pts[i+4] - _pts[i]) * tension; 

         t1y = (_pts[i+3] - _pts[i-1]) * tension; 
         t2y = (_pts[i+5] - _pts[i+1]) * tension; 

         // calc step 
         st = t/numOfSegments; 

         // calc cardinals 
         c1 = 2 * Math.pow(st, 3) - 3 * Math.pow(st, 2) + 1; 
         c2 = -(2 * Math.pow(st, 3)) + 3 * Math.pow(st, 2); 
         c3 =  Math.pow(st, 3) - 2 * Math.pow(st, 2) + st; 
         c4 =  Math.pow(st, 3) -  Math.pow(st, 2); 

         // calc x and y cords with common control vectors 
         x = c1 * _pts[i] + c2 * _pts[i+2] + c3 * t1x + c4 * t2x; 
         y = c1 * _pts[i+1] + c2 * _pts[i+3] + c3 * t1y + c4 * t2y; 

         //store points in array 
         res.push(x); 
         res.push(y); 

        } 
       } 

       return res; 
      } 

      function drawLines(ctx, pts) { 
       ctx.moveTo(pts[0], pts[1]); 
       for(i=2;i<pts.length-1;i+=2) ctx.lineTo(pts[i], pts[i+1]); 
       ctx.stroke(); 
       ctx.closePath(); 
      } 

回答

0

问题是,您使用变量i作为变量在循环中绘制所有曲线。但是,然后在getCurvePoints()内,您再次使用相同的变量i作为循环计数器。因此,在绘制出第一条曲线之后,i包含的值大于您所拥有的曲线数量。所以,你的循环绘制所有三条曲线在第一条曲线之后退出。为了解决这个问题,我改变了你的曲线绘制循环变量C,所以就变成:

for (var c = 0; c < curves.length; c++) { 
     console.log(c); 
     ctx.stroke(); 
     ctx.strokeStyle = colors[c]; 
     console.log(colors[c]); 
     drawCurve(ctx, curves[c]); 
     console.log(curves); 
     console.log(curves.length); 
     console.log(c); 
} 

而且我还添加了var在循环声明igetCurvePoints()

for (var i = 2; i < (_pts.length - 4); i += 2) { 

这里的工作演示: https://jsfiddle.net/7mgft8qe/

+0

啊谢谢。我注意到这是一个JS的东西。一旦我在'getCurvePoints()'和'drawLines()'中添加'var'声明'i',问题就解决了。谢谢! – Fenwick