I am new to HTML canvas, I'm trying to draw a cylinder with different colors using JavaScript, I can see the drawing but the shape is not displayed fully, it is supposed to be a fully illustrated shape with colors. I tried to change the width and height settings but it stretched the shape itself.
var canvas = document.getElementById("cylinder");
var ctx = canvas.getContext("2d");
drawCylinder(canvas, ctx, "lightblue", "black", 3);
function drawCylinder(canvas, ctx, fill, border, lineWidth, r, centX, centY)
{
//canvas.width = 160;
var centX = 0;
var centY = -100;
var r = 30;
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.scale(6, 1);
ctx.beginPath();
ctx.arc(centX, centY, r, 0, 2 * Math.PI, false);
ctx.restore();
ctx.fillStyle = 'YellowGreen';
ctx.fill();
ctx.lineWidth = 7;
ctx.strokeStyle = 'GainsBoro';
ctx.stroke();
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.scale(6, 1);
ctx.beginPath();
ctx.arc(centX, 100, r, 0, 2 * Math.PI, false);
ctx.restore();
ctx.fillStyle = 'MediumSlateBlue';
ctx.fill();
ctx.lineWidth = 7;
ctx.strokeStyle = 'GainsBoro';
ctx.stroke();
ctx.save();
ctx.lineWidth = 3;
ctx.strokeStyle = 'Black';
ctx.moveTo(105, 150);
ctx.lineTo(105, 352);
ctx.moveTo(474, 150);
ctx.lineTo(474, 352);
ctx.stroke();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.scale(6, 1);
ctx.beginPath();
ctx.arc(centX, centY 2, r 0.8, 0, Math.PI, false);
ctx.restore();
ctx.lineWidth = 4;
ctx.strokeStyle = 'Black';
ctx.stroke();
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.scale(6, 1);
ctx.beginPath();
ctx.arc(centX, 100 2, r 0.8, 0, Math.PI, false);
ctx.restore();
ctx.lineWidth = 4;
ctx.strokeStyle = 'Black';
}
<div>
<canvas id="cylinder" width="300" height="400"></canvas>
</div>
I'm not sure why it displays like this, can you please help the brother out.
The canvas should look like an image below.
CodePudding user response:
You have a pretty unique way of drawing a cylinder. Of course you can do it by first drawing a circle and scaling the context vertically afterwards to ultimately stretch the circle to an ellipse but let's do it a little different.
Out of the box the CanvasRenderingContext2D
has a built-in method to draw an ellipse, conveniently called ellipse()
.
So you can start by drawing an ellipse for the top, another ellipse for the bottom and finally connect those with a black outline.
Something like:
var canvas = document.getElementById("cylinder");
var ctx = canvas.getContext("2d");
drawCylinder(canvas, ctx, "lightblue", "black", 7, 100, 0, -100);
function drawCylinder(canvas, ctx, fill, border, lineWidth, r, centX, centY) {
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.ellipse(centX, centY, r, r / 5, 0, 0, 2 * Math.PI);
ctx.fillStyle = 'YellowGreen';
ctx.strokeStyle = 'GainsBoro';
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.ellipse(centX, centY 100, r, r / 5, 0, 0, 2 * Math.PI);
ctx.fillStyle = 'MediumSlateBlue';
ctx.strokeStyle = 'GainsBoro';
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.lineWidth = 1;
ctx.strokeStyle = 'Black';
ctx.beginPath();
ctx.ellipse(centX, centY, r lineWidth / 2, r / 5 lineWidth / 2, 0, 0, 1 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.ellipse(centX, centY 100, r lineWidth / 2, r / 5 lineWidth / 2, 0, 0, 1 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(centX - r - lineWidth / 2, centY);
ctx.lineTo(centX - r - lineWidth / 2, centY 100);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(centX r lineWidth / 2, centY);
ctx.lineTo(centX r lineWidth / 2, centY 100);
ctx.stroke();
ctx.closePath();
}
<canvas id="cylinder" width="300" height="400"></canvas>