Using multiple arcs to crop circle from image - javascript

I am trying to crop a circle out of 2 images and place them side by side like so:
const ctx = $('#canvas')[0].getContext("2d");
const image = new Image();
image.onload = () => {
const coords = [[115, 62.5], [495, 62.5]];
const coords2 = [[65, 12.5] , [445, 12.5]];
for(let i = 0; i < coords.length; i++) {
ctx.beginPath();
ctx.arc(coords[i][0], coords[i][1], 50, 0, Math.PI * 2, true);
ctx.clip();
ctx.drawImage(image, coords2[i][0], coords2[i][1], 100, 100);
}
};
image.src = 'https://placeholdit.imgix.net/~text?txtsize=50&w=700&h=250&bg=afeafe';
#canvas {
border:1px solid grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" width="800" height="200"></canvas>
However, this is only cropping one of the images and the other one is not showing and I don't understand why?
When I comment out these lines
ctx.beginPath();
ctx.arc(coords[i][0], coords[i][1], 50, 0, Math.PI * 2, true);
ctx.clip();
It places the 2 images correctly, so the positioning is not the issue.

Fixed by saving the context before clipping it and then restoring it after clipping it like so:
const ctx = $('#canvas')[0].getContext("2d");
const image = new Image();
image.onload = () => {
const coords = [[115, 62.5], [495, 62.5]];
const coords2 = [[65, 12.5] , [445, 12.5]]
for(let i = 0; i < coords.length; i++) {
ctx.save();
ctx.beginPath();
ctx.arc(coords[i][0], coords[i][1], 50, 0, Math.PI * 2, true);
ctx.closePath();
ctx.clip();
ctx.drawImage(image, coords2[i][0], coords2[i][1], 100, 100);
ctx.restore();
}
};
image.src = 'https://placeholdit.imgix.net/~text?txtsize=50&w=700&h=250&bg=afeafe';
#canvas {
border:1px solid grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" width="800" height="200"></canvas>

Related

How do I make a color invisible in a canvas using javascript

I am making a clicker game where you click on a potato for stonks. I have this code:
var canvas, canvasContext, imgaeAssets;
window.onload = function() {
canvas = document.getElementById('gaming');
canvasContext = canvas.getContext('2d');
canvasContext.canvas.width = window.innerWidth;
canvasContext.canvas.height = window.innerHeight * 0.95;
setInterval(mainloop, 1000 / 50);
}
var potatoes = 0;
var potatoClick = new Image();
potatoClick.src = 'images/potato.jfif'
function mainloop() { // runs once every second
colorRect(0, 0, canvas.width, canvas.height, 'black')
canvasContext.font = "15px Comic Sans MS";
canvasContext.fillStyle = "white";
canvas.style.backgroundColor = 'rgba(255, 255, 255, 0)';
drawImg(potatoClick, 0, (canvas.height / 2) - 125, 500, 250)
if (potatoes > 0) {
canvasContext.fillText(`you have ${potatoes} potatoes`, 0, 30);
}
}
function colorRect(x, y, w, h, c) {
canvasContext.fillStyle = c;
canvasContext.fillRect(x, y, w, h);
}
function drawImg(src, x, y, w, h) {
canvasContext.drawImage(src, x, y, w, h);
}
function printMousePos(event) {}
I want to make the white in potatoClick transparent, but I can't figure out how. I've already tried assigning an alpha to it, and have also tried changing the opacity of the image, but neither have worked. If you could figure out how to make any color transparent, I would appreciate it. I wouldn't mind needing to change the way to draw the potato, but I think it would be cleaner and easier the way I have it now.
edit: I think my question was fundamentally flawed, sorry for the confusion
After drawing things at canvas, you can't edit them anymore.
Because, Image in canvas doesn't have any parameters after draw it.
It means if you want to edit image on canvas, you need to clear your canvas when the difference is occurred.
and if you want to change the image opacity you should set globalAlpha of ctx (draw image with opacity on to a canvas)
Usually, I use Fabric.js(http://fabricjs.com/) for solve that problem.
but If you want, you can make a your own renderer by defining simple class.
like this!
<body>
<img id="dog" src="https://cdn.pixabay.com/photo/2022/07/19/10/35/puppies-7331739__340.jpg">
<img id="woman" src="https://cdn.pixabay.com/photo/2021/05/04/20/57/woman-6229693__340.jpg">
<canvas id="canvas" width="500" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
var canvas;
var ctx;
var img;
window.onload = function () {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
dog = document.getElementById("dog");
woman = document.getElementById("woman");
const exam1 = new Image(dog);
const exam2 = new Image(woman);
images = [];
images.push(exam1);
images.push(exam2);
render(images);
dog.onclick = function () {
exam1.opacity = 0.7;
exam2.opacity = 0.3;
exam1.y += 10;
exam2.x += 10;
render(images);
}
}
function render(images) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < images.length; i++) {
images[i].render();
}
}
function Image(original) {
this.image = original;
this.width = this.image.width;
this.height = this.image.height;
this.opacity = 1.0;
this.x = 0;
this.y = 0;
}
Image.prototype.render = function () {
this.image.width = this.width;
this.image.height = this.height;
ctx.globalAlpha = this.opacity;
ctx.drawImage(this.image, this.x, this.y);
ctx.globalAlpha = 1.0;
}
</script>
</body>

How add image to canvas by layers?

This is my code:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(55, 95, 30, 0, 2 * Math.PI);
var ctx1 = c.getContext("2d");
ctx1.rect(0, 0, 200, 300);
ctx.clip();
ctx.stroke();
var canvas = document.getElementById('myCanvas'),
context = canvas.getContext('2d');
make_base();
function make_base() {
base_image = new Image();
base_image.src = 'https://www.gravatar.com/avatar/4af2cdbaf02d97ba88d5d6daff94fbae/default=&s=80';
base_image.onload = function() {
context.drawImage(base_image, 15, 55);
}
}
canvas {
border: 1px solid #000000;
position: absolute;
top: 66px;
left: 22px;
}
<canvas id="myCanvas" width="236" height="413"></canvas>
From my code above I try to add image in to the circle and rectangle
I have done with add image in circle I try to add one more image in to the rectangle for the background but it seem not works.
You just need to create a second image and position it accordingly. Also use only one context, there is no need to declare it multiple times. Modified your code. I hope this will help you:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(55, 95, 30, 0, 2 * Math.PI);
ctx.rect(18, 150, 200, 250);
ctx.clip();
ctx.stroke();
make_base();
function make_base() {
base_image = new Image();
base_image.src = 'https://www.gravatar.com/avatar/4af2cdbaf02d97ba88d5d6daff94fbae/?default=&s=80';
base_image.onload = function() {
ctx.drawImage(base_image, 15, 55);
}
second_image = new Image();
second_image.src = 'https://www.gravatar.com/avatar/4af2cdbaf02d97ba88d5d6daff94fbae/?default=&s=80';
second_image.onload = function() {
ctx.drawImage(second_image, 19, 151);
}
}
<canvas id="myCanvas" width="236" height="413" style="border:1px solid #000000; position:absolute; top:66px; left:22px;"></canvas>

how i can draw image and rotate with shadow in html 5 canvas

i write a canvas rotate image and trying to add drop shadows.
anyone can help me to how i can add a different shadow style for images inside canvas. i need drop shadows like as this image for result :
enter image description here
context.shadowColor = "rgba( 0, 0, 0, 0.3 )";
context.shadowOffsetX = 6;
context.shadowOffsetY = 6;
context.shadowBlur = 3;
context.drawImage( brolly, 25, 250 );
full code :
window.addEventListener("load", init);
var canvas = document.getElementById('c');
canvas.width = 360;
canvas.height = 360;
var context = canvas.getContext('2d');
var counter = 0;
var logoImageh = new Image();
logoImageh.src = 'http://sirati.info/tmp/h.png';
var logoImagem = new Image();
logoImagem.src = 'http://sirati.info/tmp/m.png';
TO_RADIANS = Math.PI / 180;
function init() {
setInterval(loop, 100 / 30);
}
function loop() {
context.clearRect(0, 0, canvas.width, canvas.height);
drawRotatedImage(logoImageh, 180, 180, counter++);
drawRotatedImage(logoImagem, 180, 180, counter++);
counter += 1;
}
function drawRotatedImage(image, x, y, angle) {
context.save();
context.translate(x, y);
context.rotate(angle * TO_RADIANS);
context.drawImage(image, -(image.width / 2), -(image.height / 2));
context.restore();
}
body {
margin: 0px;
padding: 0px;
text-align: center;
}
canvas {
outline: 0;
border: 1px solid #000;
margin-left: auto;
margin-right: auto;
}
<html>
<head>
<title>Simple</title>
</head>
<body>
<canvas id='c'></canvas>
</body>
</html>
i write
Add shadows to your images using in-memory canvases.
Then drawImage those in-memory canvases instead of the images. Yes, drawImage can draw other canvases as well as images!
[Addition: example code using question's code as a basis]
var canvas = document.getElementById('c');
canvas.width = 360;
canvas.height = 360;
var context = canvas.getContext('2d');
var counter = 0;
TO_RADIANS = Math.PI / 180;
var nextTime=0;
var delay=1000/60*2;
var logoImageh = new Image();
logoImageh.onload=start;
logoImageh.src = 'http://sirati.info/tmp/h.png';
var logoImagem = new Image();
logoImagem.onload=start;
logoImagem.src = 'http://sirati.info/tmp/m.png';
var imageCount=2;
//
function start(){
canvasLogoImageh=addShadowToImage(logoImageh);
canvasLogoImagem=addShadowToImage(logoImagem);
requestAnimationFrame(loop);
}
function addShadowToImage(img){
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
c.width=img.width;
c.height=img.height;
cctx.shadowColor='black';
cctx.shadowBlur=10;
cctx.drawImage(img,0,0);
return(c);
}
function loop(time) {
if(time<nextTime){requestAnimationFrame(loop);return;}
nextTime=time+delay;
context.clearRect(0, 0, canvas.width, canvas.height);
drawRotatedImage(canvasLogoImageh, 180, 180, counter++);
drawRotatedImage(canvasLogoImagem, 180, 180, counter++);
counter += 0.25;
requestAnimationFrame(loop);
}
function drawRotatedImage(image, x, y, angle) {
context.save();
context.translate(x, y);
context.rotate(angle * TO_RADIANS);
context.drawImage(image, -(image.width / 2), -(image.height / 2));
context.restore();
}
body{ background-color: ivory; }
canvas{border:1px solid red; margin:0 auto; }
<canvas id="c" width=300 height=300></canvas>

DrawImage() doesn't draw on canvas

I am trying to make a screen following the player so that the player is in the middle of the screen. I have already made it in another game, but here it doesn't work. Here is my code :
var c = document.getElementById("main");
var ctx = c.getContext("2d");
var screen = document.getElementById("screen").getContext("2d");
var WhatUSeeWidth = document.getElementById("screen").width;
var WhatUSeeHeight = document.getElementById("screen").height;
ctx.beginPath();
for (i = 0; i < 100; i ++) {
if (i % 2) {
ctx.fillStyle = "red";
}
else {
ctx.fillStyle = "blue";
}
ctx.fillRect(0, i * 100, 500, 100);
}
var player = {
x : 700,
y : 800
}
setInterval(tick, 100);
function tick() {
screen.beginPath();
screen.drawImage(c, player.x - WhatUSeeWidth / 2, player.y - WhatUSeeHeight / 2, WhatUSeeWidth, WhatUSeeHeight, 0, 0, WhatUSeeWidth, WhatUSeeHeight);
}
canvas {
border: 2px solid black;
}
<canvas id="main" width="500" height="500"h></canvas>
<canvas id="screen" width="500" height="500"></canvas>
I want to draw The Blue and red canvas in The "screen" canvas Using drawImage
Ok , from your comment I understood what you are looking for. But the problem is that you probably start by an example without having understood. I try to give you my interpretation of what you do , but you should look for a good guide that starts with the basics and deepen animations (for example this: http://www.html5canvastutorials.com/).
HTML
<canvas id="canvasLayer" width="500" height="500"></canvas>
Javascript
var canvas = document.getElementById("canvasLayer");
var context = canvas.getContext("2d");
var WhatUSeeWidth = document.getElementById("canvasLayer").width;
var WhatUSeeHeight = document.getElementById("canvasLayer").height;
var player = {
x : 0,
y : 0
}
function drawBackground() {
for (i = 0; i < 100; i ++) {
if (i % 2) {
context.fillStyle = "red";
}
else {
context.fillStyle = "blue";
}
context.fillRect(0, i * 100, 500, 100);
}
}
function playerMove() {
context.beginPath();
var radius = 5;
context.arc(player.x, player.y, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 1;
context.strokeStyle = '#003300';
context.stroke();
}
setInterval(tick, 100);
function tick() {
context.clearRect(0, 0, canvas.width, canvas.height);
drawBackground();
player.x++;
player.y++;
playerMove();
}
This is the JSFiddle.
EDIT WITH THE CORRECT ANSWER
The error is in the position of the object "player". It is located outside of the canvas, width:500 height:500 and the "player" is in position x:700 y:800.
Changing the position of the player your copy will appear.
var player = {
x : 50,
y : 50
}
Here the jsfiddle example.

Is it possible to show / hide part of canvas image like Image Sprite?

Is it possible to show / hide part of canvas image like Image Sprite ?
Example Case:
I have a canvas of 200 X 200 dimension.
On One button click i want to show part of canvas from point (100, 100) to (120, 120).
On another i want to show entire canvas.
Any help in how to do this?
As sprite are usually shown within another element as a background, perhaps hiding the parent element would take care of your problem?
<style>
#sprite {
width: 100px;
height: 100px;
background-image: src(sprite.png);
background-position: 100px 100px;
}
</style>
<script>
var hide = false;
function show() {
if(!hide) {
document.getElementById("sprite").style.width="200px";
hide = true;
}
else {
document.getElementById("sprite").style.width="100px";
hide = false;
}
}
</script>
<div id="button" onclick="show();">button</div>
<div id="sprite"></div>
This is if the sprite's position is 100px to the right. You could also use document.getElementById('#sprite').style.backgroundPosition="200px 200px"; to change position of the sprite background entirely.
You can use the clipping form of drawImage to display your desired portion of the full image:
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/stackoverflow/cats.png";
function start(){
ctx.drawImage(img, 0,0,78,86, 0,0,78,86);
document.getElementById('partial').onclick=function(){
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(img, 0,0,78,86, 0,0,78,86);
}
document.getElementById('full').onclick=function(){
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(img, 0,0);
}
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<button id='partial'>Show partial canvas</button>
<button id='full'>Show full canvas</button>
<br><canvas id="canvas" width=300 height=300></canvas>
You can clip the image this way.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var btn = document.getElementById('btn');
var c = 0;
var img = new Image();
img.src = 'http://placehold.it/200/200';
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0)
}
btn.onclick = function() {
if (c++ % 2 == 0) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 100, 100, 20, 20, 100, 100, 20, 20);
btn.value = 'Unclip';
}
else {
context.drawImage(img, 0, 0);
btn.value = 'Clip';
}
}
<input id="btn" type="button" value="Clip" /><br />
<canvas id="canvas"></canvas>
EDIT
When a user clicks on the canvas, you can get the exact co-ordinates of where the event happened and if the co-ordinates lies inside of the middle circle, you can toggle the whole image by using the same clipping method.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var c = 0;
var img = new Image();
img.src = 'http://s25.postimg.org/cv29exevj/index.png';
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 80, 80, 40, 40, 80, 80, 40, 40);
}
canvas.onclick = function(e) {
var x = e.clientX - canvas.getBoundingClientRect().left;
var y = e.clientY - canvas.getBoundingClientRect().top;
if (x >= 80 && x <= 120 && y >= 80 && y <= 120) {
if (c++ % 2 == 0) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 0, 0);
} else {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 80, 80, 40, 40, 80, 80, 40, 40);
}
}
}
<canvas id="canvas"></canvas>

Categories

Resources