我正在尝试使用画布中的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);
你可以在这里看到这个输出椭圆的线条边界不太清楚。
答案 0 :(得分: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();
}
小提琴Demo
答案 1 :(得分: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();
答案 2 :(得分: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);
注意:通过更改步数和因子,您可以创建其他形状:圆形,正方形,六边形,其他多边形....
答案 3 :(得分: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>
答案 4 :(得分:0)
可能是使用更粗的线,它不是很好但是它更好
ctx.lineWidth = 3;
我还注意到使用quadraticCurveTo
似乎反对别名行http://jsfiddle.net/d4JJ8/298/我没有改变你的代码来使用它,但我发布的jsfiddle表明它是真的。你应该修改你的代码并尝试它