【发布时间】:2015-11-24 16:25:29
【问题描述】:
我正在尝试将图像剪辑成形状,然后在画布上绘制它们。我很好奇如何剪辑图像以将其返回为椭圆形。我会使用arc() 或bezierCurves() 之类的东西吗?
【问题讨论】:
标签: javascript canvas shapes
我正在尝试将图像剪辑成形状,然后在画布上绘制它们。我很好奇如何剪辑图像以将其返回为椭圆形。我会使用arc() 或bezierCurves() 之类的东西吗?
【问题讨论】:
标签: javascript canvas shapes
我认为最方便的方法是设置边界半径。
#hey{
background:red;
color:white;
padding:5px;
border-radius:5px;
}
<div id="hey">hey</div>
如果你想用 javascript 来做,你应该使用:
document.getElementById("hey").style.borderRadius="5px";
这也适用于图像。
【讨论】:
您需要创建一个椭圆形剪切路径。您可以用四条贝塞尔曲线近似椭圆。假设你想让椭圆适合一个矩形,曲线端点可以是矩形边的中点,曲线控制点可以是矩形边的中点和角的中间。矩形。
例如,您可以将以下 HTML 代码用于画布元素...
<canvas id="myCanvas" width="300" height="250"></canvas>
使用以下 JavaScript 代码使用大致椭圆形的剪切路径绘制图像...
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var r = { x: 50, y: 50, w: 200, h: 150 };
var imag = new Image();
imag.src = "images/koala.png";
imag.addEventListener("load", function () {
context.save();
context.beginPath();
context.moveTo(r.x + r.w, r.y + 0.5 * r.h);
context.bezierCurveTo(r.x + r.w, r.y + 0.25 * r.h, r.x + 0.75 * r.w, r.y, r.x + 0.5 * r.w, r.y);
context.bezierCurveTo(r.x + 0.25 * r.w, r.y, r.x, r.y + 0.25 * r.h, r.x, r.y + 0.5 * r.h);
context.bezierCurveTo(r.x, r.y + 0.75 * r.h, r.x + 0.25 * r.w, r.y + r.h, r.x + 0.5 * r.w, r.y + r.h);
context.bezierCurveTo(r.x + 0.75 * r.w, r.y + r.h, r.x + r.w, r.y + 0.75 * r.h, r.x + r.w, r.y + 0.5 * r.h);
context.closePath();
context.clip();
context.drawImage(imag, r.x, r.y, r.w, r.h);
context.restore();
});
创建椭圆路径的另一种解决方案是使用 arc() 方法创建圆形路径,然后使用 scale() 方法将圆形路径转换为椭圆路径。
【讨论】:
您可以像这样通过缩放圆(圆 == 弧)来绘制椭圆:
// Make an oval that's twice as tall as its width
// and draw it at the center of the canvas
var scaleX=1;
var scaleY=2;
var radius=canvas.width;
ctx.scale(scaleX,scaleY);
ctx.arc(canvas.width/scaleX/2,canvas.height/scaleY/2,radius,0,Math.PI*2);
ctx.fill();
然后您可以使用合成来绘制图像,使其仅出现在椭圆形内部。
这是通过context.globalCompositeOperation='source-atop' 完成的,这会导致新像素仅在与现有不透明像素重叠时才会出现:
加入一点数学比率,你甚至可以得到椭圆来显示最大数量的图像...
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/kidwallpaper.jpg";
function start(){
// resize the canvas to equal the image size
var iw=img.width;
var ih=img.height;
cw=canvas.width=iw;
ch=canvas.height=ih;
// calculate the scaling needed to max the display of the image
// inside the oval
if(iw>ih){
var scaleX=iw/ih
var scaleY=1;
var r=ih/2;
}else{
var scaleX=1;
var scaleY=ih/iw;
var r=iw/2;
}
// scale so the circle (arc) becomes an oval
ctx.scale(scaleX,scaleY);
ctx.arc(cw/scaleX/2,ch/scaleY/2,r,0,Math.PI*2);
ctx.fill();
// undo the scaling
ctx.scale(1/scaleX,1/scaleY);
// draw the image centered inside the oval using compositing
ctx.globalCompositeOperation='source-atop';
ctx.drawImage(img,cw/2-img.width/2,ch/2-img.height/2);
ctx.globalCompositeOperation='source-atop';
}
body{ background-color: black; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>
【讨论】: