【问题标题】:Filling a custom-drawn shape in Javascript在 Javascript 中填充自定义绘制的形状
【发布时间】:2013-10-08 08:45:10
【问题描述】:

我正在尝试填充我制作的椭圆,但是虽然我可以用它来绘制轮廓,但我不能让它来填充它。我查看了很多资源,包括http://www.html5canvastutorials.com/tutorials/html5-canvas-shape-fill/https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Drawing_shapes,但是按照那里的建议并没有解决问题。我试图解释其他错误——比如拼写错误、传递参数错误或我的椭圆绘图方法错误,但它们都可以独立工作。我可以画出椭圆的轮廓。我可以将上下文传递给函数。我可以填充一个非椭圆。但我无法填充我的椭圆。下面是代码的样子:

main();

function main(){
    var canvas = document.getElementById('landscape');
    var context = canvas.getContext('2d');
    // var mySky = new sky(0, 0);
    // mySky.render(context);
    var myLake = new lake(400, 500, context);
    myLake.render(context);
    var ctx = context;
    ctx.beginPath();
    ctx.moveTo(75,50);
    ctx.lineTo(100,75);
    ctx.lineTo(100,25);
    ctx.fill();
}

function lake(x, y, context){

    this.context = context;
    this.x = x;
    this.y = y;
    var width = this.context.canvas.width/2;
    var height = this.context.canvas.height/4;
    var a = width/2;
    var b = height/2;
    var phi = Math.PI/2;

    this.render = function(context){
        var inc = (2*Math.PI)/200;
        var end = 200*inc;
        var oldX = oldY = newX = newY = 0;
        var x_0 = xcoord(0);
        var y_0 = ycoord(0);
        console.log("" + x_0 + ", " + y_0);
        var i = 0;
        context.beginPath();
        context.moveTo(x_0, y_0);
        while(i < end){
            i += inc;
            newX = xcoord(i);
            newY = ycoord(i);
            context.lineTo(newX, newY);
            context.moveTo(newX, newY);
            console.log("" + newX + ", " + newY);
        }
        context.lineTo(x_0, y_0); // close up the ellipse
        context.moveTo(x_0, y_0);
        context.closePath();
        context.fillStyle = '#6EB1F5';
        context.fill();
    }

    function xcoord(t){
        return x + a*Math.cos(t)*Math.sin(phi) + b*Math.sin(t)*Math.cos(phi);
    }

    function ycoord(t){
        return y + a*Math.cos(t)*Math.cos(phi) - b*Math.sin(t)*Math.sin(phi);
    }

我是否正确使用了 fill() 函数?是因为我的椭圆没有正确闭合吗?如果可能的话,请不要给我太多信息 - 我想自己做,我只是不知道出了什么问题,我已经花了将近 3 个小时试图解决这个问题。

【问题讨论】:

    标签: javascript canvas graphics


    【解决方案1】:

    尝试删除以下位置的moveTo

    context.beginPath();
    context.moveTo(x_0, y_0); /// keep this
    while(i < end){
        i += inc;
        newX = xcoord(i);
        newY = ycoord(i);
        context.lineTo(newX, newY);
        ///context.moveTo(newX, newY);  /// remove this
        console.log("" + newX + ", " + newY);
    }
    ///context.lineTo(x_0, y_0); /// not needed as closePath will close it
    ///context.moveTo(x_0, y_0); /// remove this
    context.closePath();
    

    当您为每个新坐标使用moveTo 时,您将创建仅包含无法填充的单行的子路径。您想创建一条在末端闭合的连续线,形成一个闭合的多边形。

    除此之外,您还正确地使用了fill()

    【讨论】:

    • 感谢您的快速回答。我想我不明白 moveTo() 和 lineTo() 是如何一起工作的。当然,现在我查看了这些教程,我发现他们每个人都只使用了一次 moveTo()。布拉格...
    【解决方案2】:

    既然您要问,有更简单、更便宜的方法来绘制椭圆。

    类似于以下内容:

    function ellipse(context, x, y, a, b, theta) {
        context.beginPath();
        context.save();
        /* translate to avoid having our x and y values scaled */
        context.translate(x, y); 
        /* we can even do some rotation. (rotate before stretching!) */
        context.rotate(theta);
        /* now stretch the axes */
        context.scale(a, b);
        /* circle of radius 1, centred at the origin */
        context.arc(0, 0, 1, 0, 2*Math.PI, false);
        /* undo transformations */
        context.restore();
        context.closePath();
    }
    

    JSFiddle here.

    【讨论】:

      【解决方案3】:
      function ellipse(context, x, y, a, b, theta) {
      context.beginPath();
      context.save();
      /* translate to avoid having our x and y values scaled */
      context.translate(x, y);
          context.scale(Math.random() * 1 ,Math.random() * 1);
      
      /* we can even do some rotation. (rotate before stretching!) */
      context.rotate(theta);
      /* now stretch the axes */
      context.scale(a, b);
      /* circle of radius 1, centred at the origin */
      context.arc(0, 0, 1, 0, 2*Math.PI, false);
      /* undo transformations */
      context.restore();
      context.closePath();};
      
      setInterval(function(){abc()}, 100);
      var c = document.getElementById("c");
       var ctx = c.getContext("2d");
      
      function abc()
      {
      c.width = c.width;
      for (var i=0; i < 20; i++) {
      ellipse(ctx, i*50+25, 100, 20, 30, Math.random() * 10 - 5);
      if (i % 3)
          ctx.fill();
      else
          ctx.stroke();
      };
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多