2013-10-25 4 views
2

Я использую сценарий this coverflow на своем веб-сайте, и я не знаю, как вывести холст с закругленными углами.Canvas drawimage с круглыми углами

Это код, который рисует изображение

ctx.drawImage(image, cropLeft, cropTop, wid-2*cropLeft, hei-2*cropTop, 0, 0, newWidth, newHeight); 

Я прочитал некоторые учебники, используя дугу() или Аркто() функции, но ни один из них мы используем изображение в качестве объекта.

Update1: Понятно, что DrawImage() имеет только следующие параметры для рисования: • Изображения того же размера и состава, что и исходный • Изображения, которые изменяют свои размеры от оригинального • Изображения, которые обрезанных от первоначального

Таким образом, я предполагаю, что это невозможно сделать изображения с закругленными углами через холст ..

ответ

11

Вы можете использовать context.clip() нарисовать изображение, которое обрезается внутри прямоугольника с закругленными углами

enter image description here

Сначала нарисуйте прямоугольник с закругленными углами (не нужно погладить или заполнить):

// draw a rounded rectangle 

    ctx.beginPath(); 
    ctx.moveTo(x + radius, y); 
    ctx.lineTo(x + width - radius, y); 
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius); 
    ctx.lineTo(x + width, y + height - radius); 
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); 
    ctx.lineTo(x + radius, y + height); 
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius); 
    ctx.lineTo(x, y + radius); 
    ctx.quadraticCurveTo(x, y, x + radius, y); 
    ctx.closePath(); 

Затем вызовите context.clip, который заставит все будущие рисунки должны быть обрезаны внутри прямоугольника

ctx.clip(); 

Наконец, нарисуйте изображение внутри этого прямоугольника, и ваше изображение будет обрезано.

ctx.drawImage(img,10,10,102,77); 

Вот пример код и Фидл: http://jsfiddle.net/m1erickson/FLaee/

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

<style> 
    body{ background-color: ivory; } 
    #canvas{border:1px solid red;} 
</style> 

<script> 
$(function(){ 

    var canvas=document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d"); 

    var img=new Image(); 
    img.onload=function(){ 
     ctx.save(); 
     roundedImage(10,10,102,77,10); 
     ctx.clip(); 
     ctx.drawImage(img,10,10,102,77); 
     ctx.restore(); 
    } 
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/sky-bg2.jpg"; 


    function roundedImage(x,y,width,height,radius){ 
     ctx.beginPath(); 
     ctx.moveTo(x + radius, y); 
     ctx.lineTo(x + width - radius, y); 
     ctx.quadraticCurveTo(x + width, y, x + width, y + radius); 
     ctx.lineTo(x + width, y + height - radius); 
     ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); 
     ctx.lineTo(x + radius, y + height); 
     ctx.quadraticCurveTo(x, y + height, x, y + height - radius); 
     ctx.lineTo(x, y + radius); 
     ctx.quadraticCurveTo(x, y, x + radius, y); 
     ctx.closePath(); 
    } 

}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <canvas id="canvas" width=300 height=300></canvas> 
</body> 
</html> 
+0

Спасибо! Вероятно, это решило бы мою проблему, но на данный момент я создал скрипт для покрытия с нуля (я думал, что это было проще, поэтому я сделал это). – tbutcaru

+0

Возможно, я ошибаюсь, но я не могу отключить клип. Как это должно работать? –

+1

@SephReed Да, «Un-clipping» не так очевидно, как могло бы быть. Оберните 'ctx.clip' betweem' ctx.save' и 'ctx.restore'. «Сохранить» сохранит предварительные свойства незакрепленного контекста, и восстановление будет «un-clip», восстановив эти предварительные свойства. – markE

2

Проблема с раствором клипа() является то, что хром будет оказывать его с границами, не сглаженными, как показано в этом вопросе.

Одно решение было бы сделать это с globalCompositeOperation, как говорит Даниил в своем ответе:

//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(scratchCanves, ...); 
Смежные вопросы