Fill between 2 partial ellipses - javascript

I have two half-ellipses and I'm trying fill the space between them. For whatever reason the "fill" is getting "twisted" in the middle:
const canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = canvas.height = 300;
ctx.ellipse(150, 0, 150, 90, 0, 0, Math.PI);
ctx.ellipse(150, 200, 150, 90, 0, 0, Math.PI);
ctx.fillStyle = "lightgreen";
ctx.fill();
ctx.stroke();
<canvas id="canvas"></canvas>
Any ideas how to make it fill so it's like a cylinder (without far side on top)

I guess all it need was rotate one of the ellipses and draw it in reverse:
const canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = canvas.height = 300;
ctx.ellipse(150, 0, 150, 90, 0, 0, Math.PI);
ctx.ellipse(150, 200, 150, 90, Math.PI, 0, Math.PI, true); //changed
ctx.fillStyle = "lightgreen";
ctx.fill();
ctx.stroke();
<canvas id="canvas"></canvas>

Related

Both squares aren't showing up on the canvas

This is my code:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
function draw() {
context.fillStyle = "rgb(200, 0, 0)";
context.fillRect(50, 50, 0, 0);
};
draw();
When I run it, I get no errors but it doesn't add the squares to the canvas. Can someone tell me why this happens and how to fix it?
Your second Rectangle does not have a height and width.
the function has the parameters x, y, width, height -> fillRect(x, y, width, height).
Your line context.fillRect(50, 50, 0, 0); creates a box with width and height of 0 at 50px from x and y.
const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
const settings = {x: 50, y: 50, height: 50, width: 50};
function draw() {
if (ctx) {
ctx.fillStyle = "rgb(0, 200, 0)";
ctx.fillRect(settings.x, settings.y, settings.width, settings.height);
ctx.fillStyle = "rgb(200, 0, 0)";
ctx.fillRect(0, 0, 50, 50);
};
};
draw();
<canvas id="myCanvas"></canvas>

Change canvas width and height without losing the current draw

I'm creating a pixel art app and when I want to save the image from the canvas the image is so small, so it seems pixelated when I want to resize it.
I want to resize it to bigger dimensions, but I don't know how.
This is the code example:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.rect(0, 0, 50, 50);
ctx.fillStyle = 'red';
ctx.fill();
document.write('<img style="width:300px;" src="'+c.toDataURL("image/png")+'"/>');
// This is an image with dimensions 108x108px and it seems very bad when i resize it to 300x300px
// I want to download the canvas image with more resolution
<canvas id="myCanvas" width="108" height="108" style="width: 300px; height:300px;">
</canvas>
you can create a canvas and put the imageData in it.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.rect(0, 0, 25, 25);
ctx.fillStyle = 'red';
ctx.fill();
ctx.beginPath();
ctx.rect(0, 25, 25, 25);
ctx.fillStyle = 'yellow';
ctx.fill();
ctx.beginPath();
ctx.rect(25, 0, 25, 25);
ctx.fillStyle = 'blue';
ctx.fill();
ctx.beginPath();
ctx.rect(25, 25, 25, 25);
ctx.fillStyle = 'green';
ctx.fill();
var c2 = document.createElement("canvas");
c2.width = 50;
c2.height = 50;
var ctx2 = c2.getContext("2d");
var imageData = ctx.getImageData(0, 0, 50, 50);
ctx2.putImageData(imageData, 0, 0);
document.write('<img style="width:300px;" src="' + c2.toDataURL("image/png") + '"/>');

transparent circle on opaque canvas

I'm trying to draw a transparent circle on the HTML Canvas. Here is the code:
const canvas = document.querySelector('#canvas');
let ctx = canvas.getContext('2d');
canvas.width = 700;
canvas.height = 700;
ctx.beginPath();
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'destination-out';
ctx.clearRect(50, 50, 200, 200);
ctx.beginPath();
ctx.fillRect(50, 50, 200, 200);
ctx.moveTo(350, 150);
ctx.beginPath();
ctx.arc(350, 150, 80, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.fill();
I was able to make the rectangle transparent with globalCompositeOperation set to destination-out but it failed to make the circle fully transparent.
Here is what MDN says about destination-out operation,
The existing content is kept where it doesn't overlap the new shape.
The circle has still some opaque color applied to it. How to make it fully transparent?
Here is the live demo.
Unable to understand what's wrong with the code. Any help would be appreciated.
You are using beginpath methods but the directives you use aren't paths.
The fully transparent rectangle is created by the clearRect and not by the fillRect method.
So you should set fillStyle to white and then the code works.
const canvas = document.querySelector('#canvas');
let ctx = canvas.getContext('2d');
canvas.width = 600;
canvas.height = 400;
ctx.fillStyle = 'rgba(0, 0, 0, .5)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = 'rgba(255, 255, 255, 1)';
ctx.fillRect(25, 25, 150, 150);
ctx.arc(275, 100, 60, 0, 2 * Math.PI, false);
ctx.fill();
body {
background-color: skyblue;
position: relative;
}
img, #canvas {
position: absolute;
}
<body>
<img src="https://images.unsplash.com/photo-1635315850978-44cd0b237006?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1770&q=80" alt="" width=600 height=390>
<canvas id="canvas"></canvas>
</body>

Canvas Text and image blurry

I donĀ“t know why the text in canvas is blurry and the image drawed is also blurry, this is my example how I create the canvas with the image and text.
https://jsfiddle.net/jorge182/5ju5pLqb/2/
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.save();
context.beginPath();
context.arc(25, 25, 25, 0, Math.PI * 2, true);
context.closePath();
context.clip();
context.drawImage(imageObj, 0, 0, 50, 50);
context.beginPath();
context.arc(0, 0, 25, 0, Math.PI * 2, true);
context.clip();
context.closePath();
context.restore();
context.lineWidth = 2;
context.textAlign = 'left';
context.font = '8pt Signika Negative';
context.fillStyle = 'black';
context.fillText('Jorge', 60, 15);
context.fillText(' have been here!', 60, 30);
context.font = '6pt Signika Negative';
context.textAling = 'left';
context.fillStyle = '#555';
context.fillText('Caribe Photo Weading Photograpy', 60, 40);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'
The blurry image is probably because you resized the image too much from its original size. Take a look at the jsFiddle below and you can see if you only resize half of its size it's still looking good.
https://jsfiddle.net/gracegotlost/5ju5pLqb/3/
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
imageObj.onload = function() {
var width = imageObj.width;
var height = imageObj.height;
context.save();
context.beginPath();
context.arc(width/2, height/2, 150, 0, Math.PI * 2, true);
context.fill();
context.closePath();
context.clip();
context.drawImage(imageObj, 0, 0, imageObj.width, imageObj.height);
context.beginPath();
context.arc(0, 0, 25, 0, Math.PI * 2, true);
context.clip();
context.closePath();
context.restore();
context.textAlign = 'left';
context.font = '32pt Signika Negative';
context.fillStyle = 'black';
context.fillText('Jorge', 60, 350);
context.fillText(' have been here!', 150, 350);
context.font = '20pt Signika Negative';
context.textAling = 'left';
context.fillStyle = '#555';
context.fillText('Caribe Photo Weading Photograpy', 60, 400);
};
For the blurry text I found one post very helpful. If you can increase the text size it will look better, but to give it even more higher resolution you would probably do as follows:
https://stackoverflow.com/a/15666143/4809052
For the jagged edge the first answer is very helpful.

Animating an emoticon to wink with animation in HTML5 canvas

I am attempting to animate an emoticon that was previously drawn in canvas. I am attempting to do a draw and clear using frames following a tutorial but am not getting results. I have 6 frames of the emoticon coded and am unsure how to include this within the code. This is what I have so far:
<!DOCTYPE html>
<html>
<head>
<title>Adding Animation</title>
<style>
canvas {
border: 3px #CCC solid;
}
</style>
</head>
<body>
<div id="container">
<canvas id="myCanvas" height="1200" width="900"></canvas>
</div>
<script>
var mainCanvas = document.querySelector("#myCanvas");
var mainContext = mainCanvas.getContext("2d");
var canvasWidth = mainCanvas.width;
var canvasHeight = mainCanvas.height;
function drawCircle() {
mainContext.clearRect(0, 0, canvasWidth, canvasHeight);
// color in the background
mainContext.fillStyle = "#EEEEEE";
mainContext.fillRect(0, 0, canvasWidth, canvasHeight);
// draw the circle
ctx.beginPath();
ctx.strokeStyle = "000000";
ctx.lineWidth = 5;
ctx.fillStyle = "yellow";
ctx.arc(600, 450, 150, 0, Math.PI * 2, true);
ctx.stroke();
ctx.closePath();
ctx.fill();
//The smile
ctx.beginPath();
ctxstrokeStyle = "black";
ctx.lineWidth = 2;
ctx.arc(600, 475, 75, .1 * Math.PI, Math.PI * .9, false)
ctx.stroke();
ctx.closePath();
//The eyes
//Left
ctx.save();
ctx.scale(0.65, 1);
ctx.beginPath();
ctx.arc(850, 405, 40, 0 * Math.PI, Math.PI * 2, false);
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
//Right
ctx.save();
ctx.scale(0.65, 1);
ctx.beginPath();
ctx.arc(1000,405,40, 0*Math.PI, Math.PI*2, false);
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore()
}
drawCircle();
</script>
</body>
</html>
I am unsure if I am even on the right track as I have a difficult time with animation. Does anyone have any suggestions they can give me guidance on?
You have 2 names for the context: mainContext & ctx.
Change it to a single name and your face is "smiley" ! :-)
...
To animate:
Use a requestAnimationFrame loop to change the scaleY value in scale(scaleX,scaleY) over time.
Here's annotated code and a Demo:
var mainCanvas = document.querySelector("#myCanvas");
var ctx = mainCanvas.getContext("2d");
var canvasWidth = mainCanvas.width;
var canvasHeight = mainCanvas.height;
ctx.translate(-425,-275);
drawCircle(1);
// global var to hold pct the left eye is open
// 1==fully open, 0==fully closed
var scaley=1;
var direction=-1;
// request 1 animate() loop
requestAnimationFrame(animate);
function animate(time){
// draw smiley with the specified eye openness
drawCircle(scaley);
scaley+=.02*direction;
if(scaley<0){
scaley=0;
direction=1;
}
if(scaley>1){
scaley=1;
direction=-1;
}
requestAnimationFrame(animate);
}
function drawCircle(scaleY) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// color in the background
ctx.fillStyle = "#EEEEEE";
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
// draw the circle
ctx.beginPath();
ctx.strokeStyle = "000000";
ctx.lineWidth = 5;
ctx.fillStyle = "yellow";
ctx.arc(600, 450, 150, 0, Math.PI * 2, true);
ctx.stroke();
ctx.closePath();
ctx.fill();
//The smile
ctx.beginPath();
ctxstrokeStyle = "black";
ctx.lineWidth = 2;
ctx.arc(600, 475, 75, .1 * Math.PI, Math.PI * .9, false)
ctx.stroke();
//The eyes
//Left
ctx.save();
// move the [0,0] origin to the left eye's centerpoint
ctx.translate(550,405);
// close the left eye by the specified scaleY
ctx.scale(0.65, scaleY);
ctx.beginPath();
// draw the left eye (arc) at 0,0 because
// we translated the origin to [550,405] earlier
ctx.arc(0, 0, 40, 0 * Math.PI, Math.PI * 2, false);
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
//Right
ctx.save();
ctx.scale(0.65, 1);
ctx.beginPath();
ctx.arc(1000,405,40, 0*Math.PI, Math.PI*2, false);
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore()
}
<canvas id="myCanvas" height="1200" width="900"></canvas>
You never declared a ctx variable.
Change all your mainContext by ctx and it should be working fine.

Categories