2012-03-02 24 views
29

Tôi đang sử dụng hàm clip() trên canvas.Làm thế nào để chống răng cưa clip() cạnh trong vải html5 dưới Chrome Windows?

Kết quả: using canvas clip in various browsers

Như bạn có thể thấy phiên bản chrome có răng cưa khủng khiếp/răng cưa dọc theo các cạnh. Làm thế nào để sửa lỗi này?

Mã để tái sản xuất:

http://jsfiddle.net/ZRA76/:

<canvas id="test" width="300" height="300"></canvas>​ 

<script type="text/javascript"> 
    cv = document.getElementById("test"); 
    ctx = cv.getContext("2d"); 

    var im = new Image(); 
    im.onload = function() { 
     ctx.beginPath(); 
     ctx.arc(110, 110, 100, 0, 2*Math.PI, true); 
     ctx.clip(); 
     ctx.drawImage(im, 0, 0); 
    } 
    im.src = "http://placekitten.com/300/300"; 
</script> 
+0

Tôi cũng gặp sự cố này. Những gì tôi đã làm là vẽ một vòng tròn ở cùng một vị trí với hình ảnh, đằng sau nó, với bán kính lớn hơn 1 hoặc 2 px. Giữ màu sắc tương tự và có bạn đi, "chống răng cưa" hình ảnh clip. – Automatico

Trả lời

2

từ các câu trả lời trên Can I turn off antialiasing on an HTML <canvas> element? có vẻ như nó là trình duyệt cụ thể. Nó thậm chí còn hoạt động bug report trên dự án chromium của google code. Xin lỗi, nhưng có vẻ như bạn không may mắn.

+1

Hiện tại, bản sửa lỗi đang ở trạng thái phát triển trong [bảng điều khiển chrome] (https://www.chromestatus.com/features/4871530282483712). Như được viết trong [Vấn đề] (https://code.google.com/p/chromium/issues/detail?id=422984), các trình duyệt khác (IE, Firefox, Safari) 'clip()' được chống răng cưa. – sapics

-1

Sử dụng clip svg. Làm việc như một sự quyến rũ nhưng không thuận tiện để sử dụng.

5

Tôi gặp vấn đề tương tự với Chrome và clip().

Trong trường hợp của tôi, tôi đã đạt được khả năng tương thích trình duyệt tốt hơn bằng cách đặt canvas globalCompositeOperation.

context.globalCompositeOperation = 'source-atop'; 

Vì vậy, vẽ hình dạng của bạn, hình tròn trong trường hợp này. Sau đó chuyển sang 'nguồn trên đỉnh' và vẽ hình ảnh con mèo con của bạn.

Lưu ý, đây là bản sửa lỗi nhanh cho bản vẽ cơ bản và giả sử một khung trống. Bản vẽ canvas trước sẽ ảnh hưởng đến clip của bạn.

+0

Giải pháp này hoạt động rất tốt, cảm ơn bạn. Một vòng cung cho clip và một cung cho cú đánh. Đơn giản. Tôi tin rằng giải pháp canvas xước là quá phức tạp và chậm chạp cho vấn đề này trừ khi bạn có một số vấn đề với KHÔNG muốn đột quỵ. – mattdlockyer

+0

Tôi đã có thể áp dụng điều này, cộng với kỹ thuật "back-canvas", để giảm một cạnh lởm chởm khó chịu khi tôi chạy video qua canvas: http://codepen.io/paceaux/pen/egLOeR Cảm ơn bạn đã chia sẻ. – paceaux

12

Sửa lỗi của tôi cho điều này là vẽ một đường nét trắng mỏng (2px) ở cùng bán kính sau khi vẽ hình ảnh. Nó bao gồm các bí danh độc đáo và trông tốt trên các trình duyệt.

+0

Một ý tưởng tuyệt vời! Cảm ơn!! – Keith

+0

Tôi đã đấu tranh với điều này ngày hôm nay trong hơn một giờ, một giải pháp đơn giản và tuyệt vời như vậy :) – trueicecold

+0

CÓ, NÀY, SẠCH, <3! –

22

Nếu bạn đang vẽ phức tạp, lớp, bạn có thể sử dụng globalCompositeOperation để mô phỏng cắt trong một khung hình thứ hai, đầu. Sau đó, bạn có thể sử dụng drawImage để sao chép canvas đầu vào lại khung ban đầu. Tôi không thể đảm bảo hiệu suất của phương pháp này, nhưng đó là cách duy nhất tôi biết để có được những gì bạn muốn.

//set-up - probably only needs to be done once 
var scratchCanvas = document.createElement('canvas'); 
scratchCanvas.width = 100; 
scratchCanvas.height = 100; 
var scratchCtx = scratchCanvas.getContext('2d'); 


//drawing code 
scratchCtx.clearRect(0, 0, scratchCanvas.width, scratchCanvas.height); 

scratchCtx.globalCompositeOperation = 'source-over'; //default 

//Do whatever drawing you want. In your case, draw your image. 
scratchCtx.drawImage(imageToCrop, ...); 


//As long as we can represent our clipping region as a single path, 
//we can perform our clipping by using a non-default composite operation. 
//You can think of destination-in as "write alpha". It will not touch 
//the color channel of the canvas, but will replace the alpha channel. 
//(Actually, it will multiply the already drawn alpha with the alpha 
//currently being drawn - meaning that things look good where two anti- 
//aliased pixels overlap.) 
// 
//If you can't represent the clipping region as a single path, you can 
//always draw your clip shape into yet another scratch canvas. 

scratchCtx.fillStyle = '#fff'; //color doesn't matter, but we want full opacity 
scratchCtx.globalCompositeOperation = 'destination-in'; 
scratchCtx.beginPath(); 
scratchCtx.arc(50, 50, 50, 0, 2 * Math.PI, true); 
scratchCtx.closePath(); 
scratchCtx.fill(); 


//Now that we have a nice, cropped image, we can draw it in our 
//actual canvas. We can even draw it over top existing pixels, and 
//everything will look great! 

ctx.drawImage(scratchCanvas, ...); 

Lý do chúng tôi thực hiện điều này trong canvas đầu là đích đến là một hoạt động khá phá hoại. Nếu bạn đã vẽ một số thứ vào trong khung chính (có lẽ bạn đã đặt một gradient đẹp ở phía sau), và sau đó muốn vẽ một hình ảnh bị cắt bớt, vòng tròn cắt cũng sẽ cắt ra mọi thứ bạn đã vẽ. Tất nhiên, nếu tình hình cụ thể của bạn là đơn giản hơn (có thể TẤT CẢ bạn muốn vẽ là một hình ảnh cắt bớt), sau đó bạn có thể bỏ qua vải đầu.

Bạn có thể phát xung quanh bằng các chế độ cắt khác nhau trên my demo page. Hàng dưới cùng (với các gradient) không phải là quá hữu ích cho bạn, nhưng hàng trên cùng (với hình tròn và hình vuông) có liên quan hơn nhiều.

chỉnh sửa

Rất tiếc, tôi vô tình forked your JSFiddle để chứng minh kỹ thuật này.

+0

Bạn thưa Ngài, đã cứu ngày của tôi! – enyce12

+0

cảm ơn người đàn ông! Nó hoạt động !!! –