2013-09-28 48 views
5

Tôi đang cố gắng vẽ một hình bầu dục mịn bằng cách sử dụng thuộc tính ctx.clip trong canvas.I của tôi đã thực hiện với phần vẽ tôi đang đối mặt với vấn đề với đường thẳng hình bầu dục rõ ràng. Bất kỳ ai có bất kỳ ý tưởng nào về điều này chỉ cho tôi biết? Đây là mã của tôi.Làm thế nào để vẽ một hình bầu dục mịn trong vải

<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); 

Here is my fiddle link

Bạn có thể thấy sản lượng này trên đây biên giới dòng hình bầu dục không rõ ràng hơn nhiều. Here is output of screen shot

+2

Một dòng một pixel sẽ không phải rất rõ ràng, bạn sẽ phải chống alias nó –

+0

gì exacly @JuanMendes –

Trả lời

2

Một vấn đề là ở bản chất của màn hình hiển thị của bạn ...

Từ pixel là hình chữ nhật và bạn đang vẽ một đường cong, kết quả của bạn sẽ có "răng cưa" như đường cong cố gắng để phù hợp với chính nó trong không gian hình chữ nhật.

Bạn có thể sử dụng ảo ảnh quang học để lừa mắt nhìn thấy hình bầu dục ít bị lởm chởm hơn.

Một lừa quang học:

Giảm sự tương phản giữa màu nền và màu hình bầu dục.

Đây không phải là cách chữa trị ... các jaggies vẫn còn đó.

Nhưng mắt nhận ra độ tương phản ít hơn và nhận thấy hình bầu dục trơn tru hơn.

Vì vậy, nếu thiết kế của bạn thích ứng với thay đổi kiểu này, ảo giác quang học này có thể hữu ích.

Dưới đây là mã và một Fiddle: 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(); 
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

+0

Điều này cũng không rõ ràng lắm khi tôi tích hợp mã này vào mã số của tôi –

+0

Ok Tôi đã tìm thấy một giải pháp mà tôi nghĩ, vài phút cập nhật. – OBV

+0

http://jsbin.com/ecipiq/5/edit cách tiếp cận chống răng cưa thanh toán, không thấy m uch sự khác biệt tbh. – OBV

0

Một khả năng là sử dụng một đường dày hơn, nó không phải là lớn nhưng nó tốt hơn

ctx.lineWidth = 3; 

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

Tôi cũng nhận thấy rằng việc sử dụng quadraticCurveTo dường như chống bí danh dòng http://jsfiddle.net/d4JJ8/298/ Tôi không thay đổi mã của bạn để sử dụng nó nhưng jsfiddle tôi đăng cho thấy rằng đó là sự thật. Bạn nên thay đổi mã của bạn và thử nó

+0

Tôi thấy nó nhưng khi tôi chọn văn bản của nó sẽ không rõ ràng nữa. –

+1

@SanjayNakate Tôi không nhìn thấy những gì bạn đang quan sát, nó trông giống hệt nhau khi tôi chọn văn bản (trong Chrome) –

+0

Tôi nghĩ rằng một bút chì dày hơn là về đơn giản và tốt như nó được. +1 – Xotic750

1

Dưới đây là một thói quen thay thế, nhưng có vẻ trực quan giống như các phương pháp khác. Điều này chủ yếu là để làm với độ phân giải hữu hạn của thiết bị hiển thị, mặc dù bạn có thể thực hiện một số cải tiến bằng cách sử dụng bút chì dày hơn, ảo giác quang học hoặc thực hiện một số chống răng cưa. Nếu không, tôi nghĩ bạn sẽ phải chấp nhận những gì bạn có.

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

Lưu ý: bằng cách thay đổi số lượng các bước và các yếu tố, bạn có thể tạo hình dạng khác: tròn, hình vuông, hình lục giác, đa giác khác ....

+1

+1 Và đây là một biến thể cho phép xác định bán kính x và y: http://jsfiddle.net/AbdiasSoftware/VrKJV/ – K3N

+0

@ Ken xuất hiện để tạo ra hiệu ứng chống răng cưa tốt đẹp. – Xotic750

+0

@ken Tôi nhận thấy nó trông giống như tất cả các phương thức khác khi 'ctx.clip()' được gọi là [jsfiddle] (http://jsfiddle.net/Xotic750/8gG9p/) – Xotic750

3

thử này nó sẽ giúp bạn // Script

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(); 
} 

Fiddle Demo

Các vấn đề liên quan