正如标题所述。这可能吗?如何用HTML5画布绘制甜甜圈的分段?
编辑:当我说甜甜圈我的意思是一个顶,2D视图
是画一个圆缺的唯一选择,再画一个小圆圈的部分用相同的起源和较小的半径在顶部,背景的颜色?如果是这样,这将是废话:(
正如标题所述。这可能吗?如何用HTML5画布绘制甜甜圈的分段?
编辑:当我说甜甜圈我的意思是一个顶,2D视图
是画一个圆缺的唯一选择,再画一个小圆圈的部分用相同的起源和较小的半径在顶部,背景的颜色?如果是这样,这将是废话:(
您通过使单一路径与两条弧线做到这一点。
顺时针绘制一个圆,然后逆时针绘制第二个圆。我不会详细讨论它的细节,但路径构建的方式知道将其作为取消路径的一部分的理由。有关它在做什么的更多细节,你可以this wiki article。
如果您正在绘制“框架”矩形,则同样可行。您单向(顺时针)绘制一个盒子,然后以另一种方式(逆时针)绘制内盒以获得效果。
下面是一个甜甜圈代码:
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
// Pay attention to my last argument!
//ctx.arc(x,y,radius,startAngle,endAngle, anticlockwise);
ctx.beginPath()
ctx.arc(100,100,100,0,Math.PI*2, false); // outer (filled)
ctx.arc(100,100,55,0,Math.PI*2, true); // inner (unfills it)
ctx.fill();
实例:绘制只是一个“片段”它可以使道路更小做
(您可能需要使用beziers而不是arc),或者使用裁剪区域。这真的取决于你如何到底要“段”
这里有一个例子:http://jsfiddle.net/Hnw6a/8/
// half doughnut
ctx.beginPath()
ctx.arc(100,100,100,0,Math.PI, false); // outer (filled)
ctx.arc(100,100,55,Math.PI,Math.PI*2, true); // outer (unfills it)
ctx.fill();
WebGL(HTML5画布的上下文之一)是可能的。甚至有一些JS库不支持/实现它 - 浏览这些链接:
澄清的问题,我的意思在2D遗憾。你的答案仍然适用? –
@AndrewBullock它适用于“有点” - 你也可以使用2D的WebGL,它应该提供更多的选项来展现你想要绘制的内容......对于WebGL中的简单2D示例,请参阅https://developer.mozilla.org/en/WebGL/Adding_2D_content_to_a_WebGL_context – Yahia
您可以通过抚摸弧做出“顶视图甜甜圈”(圆空心中心)。你可以在这里看到这样一个例子:http://phrogz.net/tmp/connections.html
圆圈(带针头)由线239-245得出:
ctx.lineWidth = half*0.2; // set a nice fat line width
var r = half*0.65; // calculate the radius
ctx.arc(0,0,r,0,Math.PI*2,false); // create the circle part of the path
// ... some commands for the nib
ctx.stroke(); // actually draw the path
给出的要求,什么@SimonSarris说满足问题。但让我们说你和我一样,而你却想要“清除”一部分可能部分超出你正在清理的形状范围的形状。如果你有这个要求,他的解决方案不会让你想要你想要的。它看起来像下图中的“xor”。
的解决方案是使用context.globalCompositeOperation = 'destination-out'
蓝色是所述第一形状和所述红色是第二形状。如您所见,destination-out
将删除第一个形状的部分。下面是一些示例代码:
explosionCanvasCtx.fillStyle = "red"
drawCircle(explosionCanvasCtx, projectile.radius, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'destination-out' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
drawCircle(explosionCanvasCtx, projectile.radius + 20, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
下面是这个潜在的问题:第二fill()
将清除一切它的下面,包括背景。有时您只想清除第一个形状,但您仍然希望看到它下面的图层。
解决方案是在临时画布上绘制此图像,然后使用drawImage
将临时画布绘制到主画布上。该代码将是这样的:
diameter = projectile.radius * 2
console.log "<canvas width='" + diameter + "' height='" + diameter + "'></canvas>"
explosionCanvas = $("<canvas width='" + diameter + "' height='" + diameter + "'></canvas>")
explosionCanvasCtx = explosionCanvas[0].getContext("2d")
explosionCanvasCtx.fillStyle = "red"
drawCircle(explosionCanvasCtx, projectile.radius, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'destination-out' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
durationPercent = (projectile.startDuration - projectile.duration)/projectile.startDuration
drawCircle(explosionCanvasCtx, projectile.radius + 20, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'source-over' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
ctx.drawImage(explosionCanvas[0], projectile.pos.x - projectile.radius, projectile.pos.y - projectile.radius) #center
是的,我明白这个问题有多老:)
这里是我的两分钱:
(function(){
var annulus = function(centerX, centerY,
innerRadius, outerRadius,
startAngle, endAngle,
anticlockwise) {
var th1 = startAngle*Math.PI/180;
var th2 = endAngle*Math.PI/180;
var startOfOuterArcX = outerRadius*Math.cos(th2) + centerX;
var startOfOuterArcY = outerRadius*Math.sin(th2) + centerY;
this.beginPath();
this.arc(centerX, centerY, innerRadius, th1, th2, anticlockwise);
this.lineTo(startOfOuterArcX, startOfOuterArcY);
this.arc(centerX, centerY, outerRadius, th2, th1, !anticlockwise);
this.closePath();
}
CanvasRenderingContext2D.prototype.annulus = annulus;
})();
这将增加一个功能“轮( )“类似于CanvasRenderingContext2D原型中的”arc()“。如果你想检查点包含,使闭合路径派上用场。
有了这个功能,你可以这样做:
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
ctx.annulus(0, 0, 100, 200, 15, 45);
ctx.fill();
或者检查了这一点:https://jsfiddle.net/rj2r0k1z/10/
谢谢!
谢谢。今天我会用很多:) – T4NK3R
适配/简化@Simon萨里斯的回答容易地与任何角度工作给出以下:
要创建一个圆弧段你在一个方向上绘制的外弧(的n为弧度),然后相对的圆弧(的相同的弧度数)以较小的半径填充所得区域。
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
var angle = (Math.PI*2)/8;
var outer_arc_radius = 100;
var inner_arc_radius = 50.;
ctx.beginPath()
//ctx.arc(x,y,radius,startAngle,endAngle, anticlockwise);
ctx.arc(100,100,outer_arc_radius,0,angle, false); // outer (filled)
// the tip of the "pen is now at 0,100
ctx.arc(100,100,inner_arc_radius,angle,0, true); // outer (unfills it)
ctx.fill();
<canvas id="canvas1" width="200" height="200"></canvas>
aha!这看起来就像我需要的,谢谢! –
而不是填充和不填充,为什么不只是用宽度的中风? – Phrogz
@Progrog你可能想要边框和填充为不同的颜色。 – 2012-01-11 15:30:51