5

我正在尝试使用我的画布中的 ctx.clip 属性绘制一个平滑的椭圆。我已经完成了绘制部分,我正面临椭圆弧线清晰度的问题。有人对此有任何想法,请告诉我?这是我的代码。

<canvas id="c" width="400" height="400"></canvas>


var canvas = new fabric.Canvas('c');
var ctx = canvas.getContext('2d');
var cx=180;
var cy=200;
var w=300;
var h=250;
    // Quadratric curves example
    ctx.beginPath();
    var lx = cx - w/2,
        rx = cx + w/2,
        ty = cy - h/2,
        by = cy + h/2;
    var magic = 0.551784;
    var xmagic = magic*w/2;
    var ymagic = h*magic/2;
    ctx.moveTo(cx,ty);
    ctx.bezierCurveTo(cx+xmagic,ty,rx,cy-ymagic,rx,cy);
    ctx.bezierCurveTo(rx,cy+ymagic,cx+xmagic,by,cx,by);
    ctx.bezierCurveTo(cx-xmagic,by,lx,cy+ymagic,lx,cy);
    ctx.bezierCurveTo(lx,cy-ymagic,cx-xmagic,ty,cx,ty);

    ctx.fill();
    ctx.stroke();
    ctx.clip();



var text;
text = new fabric.Text('Honey', {
  fontSize: 50,
  left: 150,
  top: 150,
  lineHeight: 1,
  originX: 'left',
  fontFamily: 'Helvetica',
  fontWeight: 'bold'
});
canvas.add(text);

这是我的小提琴链接

你可以在这里看到这个输出,椭圆的线边界不太清楚。 这是屏幕截图的输出

4

5 回答 5

3

试试这个它会帮助你//脚本

var canvas = new fabric.Canvas('c');
 var w;
 var h;
 var ctx = canvas.getContext('2d');
 w=canvas.width / 4;
 h=canvas.height / 2.4;
canvas.clipTo = function(ctx) {
 ctx.save();
 ctx.scale(2, 1.2);
 ctx.arc(w, h, 90, 0, 2 * Math.PI, true);
 ctx.stroke();
 ctx.restore();
}

小提琴演示

于 2013-09-30T05:56:10.487 回答
2

一个问题是您的显示屏的性质...

由于像素是矩形并且您正在绘制曲线,因此您的结果将具有“锯齿”,因为曲线试图将自己适合矩形空间。

您可以使用视错觉来欺骗眼睛看到锯齿状较少的椭圆形。

光学技巧:

减少背景颜色和椭圆颜色之间的对比度。

这不是治愈方法……锯齿仍然存在。

但是眼睛识别出的对比度较低,并且认为椭圆形更平滑。

因此,如果您的设计适应这种风格变化,这种视错觉可能会有所帮助。

这是代码和小提琴:http: //jsfiddle.net/m1erickson/vDWR3/

var cx=180;
var cy=200;
var w=300;
var h=250;

// Start with a less-contrasting background
ctx.fillStyle="#ddd";
ctx.fillRect(0,0,canvas.width,canvas.height);

ctx.beginPath();
var lx = cx - w/2,
    rx = cx + w/2,
    ty = cy - h/2,
    by = cy + h/2;
var magic = 0.551784;
var xmagic = magic*w/2;
var ymagic = h*magic/2;
ctx.moveTo(cx,ty);
ctx.bezierCurveTo(cx+xmagic,ty,rx,cy-ymagic,rx,cy);
ctx.bezierCurveTo(rx,cy+ymagic,cx+xmagic,by,cx,by);
ctx.bezierCurveTo(cx-xmagic,by,lx,cy+ymagic,lx,cy);
ctx.bezierCurveTo(lx,cy-ymagic,cx-xmagic,ty,cx,ty);

ctx.fillStyle="#555";
ctx.strokeStyle=ctx.fillStyle;
ctx.lineWidth=1.5;
ctx.stroke();
于 2013-09-28T15:45:58.923 回答
1

这是另一个替代例程,但它在视觉上与其他方法相同。这主要与显示设备的有限分辨率有关,尽管您可以使用较粗的铅笔、视错觉或执行一些抗锯齿来进行一些改进。否则我认为你将不得不接受你所拥有的。

Javascript

var canvas = new fabric.Canvas('c'),
    ctx = canvas.getContext("2d"),
    steps = 100,
    step = 2 * Math.PI / steps,
    h = 200,
    k = 180,
    r = 150,
    factor = 0.8,
    theta,
    x,
    y,
    text;

ctx.beginPath();

for (theta = 0; theta < 2 * Math.PI; theta += step) {
    x = h + r * Math.cos(theta);
    y = k - factor * r * Math.sin(theta);
    ctx.lineTo(x, y);
}

ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.clip();

text = new fabric.Text('Honey', {
    fontSize: 50,
    left: 150,
    top: 150,
    lineHeight: 1,
    originX: 'left',
    fontFamily: 'Helvetica',
    fontWeight: 'bold'
});

canvas.add(text);

jsfiddle

注意:通过更改步数和因子,您可以创建其他形状:圆形、正方形、六边形、其他多边形......

于 2013-09-28T15:58:25.407 回答
0
<canvas id="thecanvas" width="400" height="400"></canvas>

<script>
var canvas = document.getElementById('thecanvas');

if(canvas.getContext) 
{
  var ctx = canvas.getContext('2d');
  drawEllipse(ctx, 10, 10, 100, 60);
  drawEllipseByCenter(ctx, 60,40,20,10);
}

function drawEllipseByCenter(ctx, cx, cy, w, h) {
  drawEllipse(ctx, cx - w/2.0, cy - h/2.0, w, h);
}

function drawEllipse(ctx, x, y, w, h) {
  var kappa = .5522848,
      ox = (w / 2) * kappa, // control point offset horizontal
      oy = (h / 2) * kappa, // control point offset vertical
      xe = x + w,           // x-end
      ye = y + h,           // y-end
      xm = x + w / 2,       // x-middle
      ym = y + h / 2;       // y-middle

  ctx.beginPath();
  ctx.moveTo(x, ym);
  ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
  ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
  ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
  ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
  ctx.closePath();
  ctx.stroke();
}

</script>

http://jsbin.com/ovuret/2/edit

于 2013-09-28T13:42:38.167 回答
0

一种可能是使用更粗的线,这不是很好但更好

ctx.lineWidth = 3;

http://jsfiddle.net/xadqg/7/

我还注意到使用quadraticCurveTo似乎反别名行http://jsfiddle.net/d4JJ8/298/我没有更改您的代码来使用它,但我发布的 jsfiddle 表明这是真的。你应该修改你的代码并尝试一下

于 2013-09-28T14:03:37.737 回答