i want to move html canvas horizontally, then rotate it, and then again move it horizontally. problem is, that after i rotate it and want to move it again, rotation dissapear. what i am doing wrong ? thanks, my code is below
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title></title>
</head>
<body>
<style type="text/css">
#canvas {
width:400px;
height:400px;
border:1px solid red;
}
</style>
<canvas id="canvas"></canvas>
<script type="text/javascript">
var c=document.getElementById("canvas");
var ctx=c.getContext("2d");
var counterx = 0;
var canvasWidth = 400;
var canvasHeight = 400;
var imageObj = new Image();
imageObj.onload = function() {
ctx.drawImage(imageObj, counterx,0 ,69, 50);
};
imageObj.src = 'test.png';
function moveRight() {
ctx.save();
counterx += 5;
ctx.clearRect(0 ,0 ,canvasWidth, canvasHeight);
ctx.drawImage(imageObj, counterx,0 ,69, 50);
ctx.restore();
}
function rotate() {
ctx.save();
ctx.translate(counterx, 0);
ctx.rotate(Math.PI / 4);
ctx.clearRect(0 ,0 ,canvasWidth, canvasHeight);
ctx.drawImage(imageObj, counterx,0 ,69, 50);
ctx.restore();
}
</script>
<a onclick="moveRight(); return false;" href="#">move right</a>
<a onclick="rotate(); return false;" href="#">rotate</a>
</body>
</html>
I would recommend accumulating the values, then do an absolute transform only when needed. A little refactoring can also make it easier to track these changes, here that would be to use a common update method.
For example:
var rotation = 0;
var counterx = 0;
function moveRight() {
counterx += 5;
update();
}
function rotate() {
rotation += Math.PI / 4
update();
}
function update() {
ctx.clearRect(0 ,0 ,canvasWidth, canvasHeight);
ctx.translate(counterx, 0); // absolute translate
ctx.rotate(rotation); // absolute rotation
ctx.drawImage(imageObj, 0, 0, 69, 50); // we are already at counterx
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset all transformations
}
And if you want to rotate by image's center, just replace the drawImage line above with:
ctx.drawImage(imageObj, -69/2, -50/2, 69, 50);
Live demo
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var canvasWidth = 400;
var canvasHeight = 400;
var imageObj = new Image();
var rotation = 0;
var counterx = 0;
c.width = canvasWidth;
c.height = canvasHeight;
imageObj.onload = update;
imageObj.src = 'http://i.imgur.com/mP58PXJ.png';
function moveRight() {
counterx += 5;
update();
}
function rotate() {
rotation += Math.PI / 4
update();
}
function update() {
var iw = imageObj.width, ih = imageObj.height;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.translate(counterx, ih); // absolute translate
ctx.rotate(rotation); // absolute rotation
ctx.drawImage(imageObj, -iw*0.5, -ih*0.5); // we are already at counterx
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset all transformations
}
#canvas {
width: 400px;
height: 400px;
border: 1px solid red;
}
<canvas id="canvas"></canvas>
<a onclick="moveRight(); return false;" href="#">move right</a>
<a onclick="rotate(); return false;" href="#">rotate</a>
Related
I'm trying to have an image on my website become saturated at the same location the mouse is. When the mouse moves the saturation effect goes with it, and the area previously hovered over becomes grayscale again. I'm thinking this effect could be accomplished using saturate(), however I haven't had any success with it. Additionally, I would like the effect to be circular without hard edges similar to this.
Example of what it would look like (orange arrow indicating where the mouse is).
Any help or insight would be appreciated, thanks!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content= "width=device-width, initial-scale=1.0" />
</head>
<script>
const size = 250;
var radius = 30;
var rad = Math.PI / 180;
var canvas = document.querySelector("canvas")
var ctx = canvas.getContext("2d");
canvas.width = size;
canvas.height = size;
var image = new Image();
image.onload = demo
image.src = "https://picsum.photos/250"
function draw_circle(x, y, radius) {
ctx.clearRect(0, 0, size, size);
ctx.drawImage(image, 0, 0); // image to change
ctx.globalCompositeOperation = "saturation";
ctx.beginPath();
ctx.fillStyle = "hsl(0,100%,50%)"; // saturation at 100%
ctx.arc(x, y, radius, 0, 360 * rad, false);
ctx.fill()
ctx.closePath();
ctx.globalCompositeOperation = "source-over"; // restore default comp
}
function demo() {
ctx.drawImage(image, 0, 0); // image to change
canvas.addEventListener('mousemove', function(ev) {
var cx = ev.offsetX
var cy = ev.offsetY
draw_circle(cx, cy, radius)
})
}
</script>
<canvas></canvas>
</html>
Using a canvas we can try. Here's a start inspired by How can I adjust the huse, saturation, and lightness of in image in HTML5 Canvas?.
const size = 250;
var radius = 30;
var rad = Math.PI / 180;
var canvas = document.querySelector("canvas")
var ctx = canvas.getContext("2d");
canvas.width = size;
canvas.height = size;
var image = new Image();
image.onload = demo
image.src = "https://picsum.photos/250"
function draw_circle(x, y, radius) {
ctx.clearRect(0, 0, size, size);
ctx.drawImage(image, 0, 0); // image to change
ctx.globalCompositeOperation = "saturation";
ctx.beginPath();
ctx.fillStyle = "hsl(0,100%,50%)"; // saturation at 100%
ctx.arc(x, y, radius, 0, 360 * rad, false);
ctx.fill()
ctx.closePath();
ctx.globalCompositeOperation = "source-over"; // restore default comp
}
function demo() {
ctx.drawImage(image, 0, 0); // image to change
canvas.addEventListener('mousemove', function(ev) {
var cx = ev.offsetX
var cy = ev.offsetY
draw_circle(cx, cy, radius)
})
}
<canvas></canvas>
This is a simple answer (change the logic of the program as you want):
<!DOCTYPE html>
<html>
<head>
<style>
div.relative {
position: relative;
width: 200px;
height: 150px;
}
.image {
width: 100%;
height: 100%;
}
</style>
<script>
const width = 50;
const height = 50;
function create() {
const element = document.createElement("div");
element.id = "filtered";
element.style.width = `${width}px`;
element.style.height = `${height}px`;
element.style.borderRadius = "50%";
element.style.position = "absolute";
element.style.backgroundColor = "red";
element.style.opacity = "0.2";
element.style.zIndex = "2";
return element;
}
function changePos(e) {
x = e.clientX;
y = e.clientY;
let element = document.getElementById("filtered");
if (!element) {
element = create();
document.getElementById("focusArea").appendChild(element);
}
element.style.left = `${x - width / 2}px`;
element.style.top = `${y - height / 2}px`;
}
function removeElement() {
if (document.getElementById("filtered")) {
document.getElementById("filtered").remove();
}
}
</script>
</head>
<body>
<div
id="focusArea"
onmouseleave="removeElement()"
onmousemove="changePos(event)"
class="relative"
>
<img
src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/800px-Image_created_with_a_mobile_phone.png"
class="image"
/>
</div>
</body>
</html>
In My case i have performed path clipping and then draw a image in clipped region. But it does not working.
here my code.`
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 75;
var offset = 50;
/*
* save() allows us to save the canvas context before
* defining the clipping region so that we can return
* to the default state later on
*/
context.save();
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.clip();
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 69, 50);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth- vader.jpg';
</script>
</body>
</html>
Now image render without clipping.
Please share your valuable key to do this.
I have a canvas that I have in html that is supposed to be 25% of the page. I made a variable named width in javascript, and put it's value as 25%. When I make a context.clearRect(); with the width variable as the width parameter, it doesn't fix it what I was trying to do (which I have done tons of times) which is when the player rectangle moves, the clearRect keeps the background circulating so the rectangle isn't drawing (leaving a mark). Here is my width variable:
var width = 25%;
Here is my clearRect();
context.clearRect(0, 0, width, height);
Edit: I guess I will also post my whole entire code, to be easier.
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: #222222;
}
canvas {
background-color: #000000;
width: 25%;
height: 400px;
}
</style>
</head>
<body>
<canvas id="mainCanvas"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("mainCanvas");
var context = canvas.getContext("2d");
var keys = [];
var speed = 4;
var width = 25%;
var height = 400;
window.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
}, false);
window.addEventListener("keyup", function(e) {
delete keys[e.keyCode];
}, false);
var player = {
x: 10,
y: 10,
width: 30,
height: 30
};
function game() {
update();
render();
}
function update() {
if (keys[40]) player.y++ * speed;
if (keys[38]) player.y-- * speed;
if (keys[37]) player.x-- * speed;
if (keys[39]) player.x++ * speed;
}
function render() {
context.clearRect(0, 0, (canvas.width * 0.25)), height);
context.fillStyle = "white";
context.fillRect(player.x, player.y, player.width, player.height);
}
setInterval(function() {
game();
}, 1000/30);
</script>
You need to use something like this:
context.clearRect(0, 0, (canvas.width * 0.25), height);
Try this?
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: #222222;
}
canvas {
background-color: #000000;
width: 25%;
height: 400px;
}
</style>
</head>
<body>
<canvas id="mainCanvas"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("mainCanvas");
var context = canvas.getContext("2d");
var keys = [];
var speed = 4;
// var width = 25%;
var height = 400;
window.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
}, false);
window.addEventListener("keyup", function(e) {
delete keys[e.keyCode];
}, false);
var player = {
x: 10,
y: 10,
width: 30,
height: 30
};
function game() {
update();
render();
}
function update() {
if (keys[40]) player.y++ * speed;
if (keys[38]) player.y-- * speed;
if (keys[37]) player.x-- * speed;
if (keys[39]) player.x++ * speed;
}
function render() {
context.clearRect(0, 0, (canvas.width * 0.25), height);
context.fillStyle = "white";
context.fillRect(player.x, player.y, player.width, player.height);
}
setInterval(function() {
game();
}, 1000/30);
</script>
</body>
</html>
Not sure what you actually wanted to ask yet your code has two syntax errors - thus it does not execute correctly:
var keys = [];
var speed = 4;
//var width = 25%; //This is no valid assignment and the value is not used..
var height = 400;
and
function render() {
//context.clearRect(0, 0, (canvas.width * 0.25)), height); //One bracket too much, can skip both tho..
context.clearRect(0, 0, canvas.width * 0.25, height);
You need to put your canvas in a container, and set up the container the way you want, then you make your canvas 100% of the containers properties using
clientHeight
and
clientWidth
JSFiddle: https://jsfiddle.net/53n2s0s9/
I have 2 images on canvas and i want to make imageObg to animate. Actually i want it to make a linear move to the right.I found a way to animate an object like a rectangle but i cant animate an image object that i use from another source.
Is there anyway that can i manage to do i? Does anyone knows?
window.onload = function() {
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
var imageObj2 = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 69, 130);
};
imageObj2.onload = function() {
context.drawImage(imageObj2, 0, 0);
};
imageObj.src = 'http://imageshack.com/a/img745/822/pXDK5F.png'
imageObj2.src = 'http://i.dailymail.co.uk/i/pix/2014/09/04/1409790551890_wps_28_Astronaut_Reid_Wiseman_po.jpg'
};
body {
background-color: black
}
<div id='d1' style="position:absolute; top:80px; left:150px; z-index:1">
<canvas id='myCanvas' width='962' height='500' style="border:10px solid #ffffff;">
Your browser does not support HTML5 Canvas.
</canvas>
</div>
Just two things.
Set a periodically render routine using setInterval.
Set a move (or physics) routine, call it after each render.
window.onload = function() {
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
var imageObj2 = new Image();
imageObj.src = 'http://imageshack.com/a/img745/822/pXDK5F.png'
imageObj2.src = 'http://i.dailymail.co.uk/i/pix/2014/09/04/1409790551890_wps_28_Astronaut_Reid_Wiseman_po.jpg'
window.setInterval(renderFrame, 50);
var ship = {
x: 69,
y: 130
};
function renderFrame() {
moveShip();
context.clearRect(0, 0, canvas.width, canvas.height);
if (imageObj.complete) {
context.drawImage(imageObj2, 0, 0);
}
if (imageObj.complete) {
context.drawImage(imageObj, ship.x, ship.y);
}
}
function moveShip() {
ship.x += 20;
if (ship.x > canvas.width) {
ship.x = 0 - imageObj.width;
ship.y = Math.random() * 250 + 50;
}
}
};
body {
background-color: black
}
<div id='d1' style="position:absolute; top:80px; left:150px; z-index:1">
<canvas id='myCanvas' width='962' height='500' style="border:10px solid #ffffff;">
Your browser does not support HTML5 Canvas.
</canvas>
</div>
Just increase the x position of the image with a setInterval command.
var img = document.createElement("IMG");
var img.src = [Image Source];
var x = 0;
window.setInterval(function() {
x ++;
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, x, 0);
}, 50);
Hope this helps.
Edit:
Here is a JSFiddle Example.
When you put a picture named logo.png in the same directory as this html file and try to run it in a web browser the picture only appears 1 times out of 10 refreshes in IE and doesn't appear the first time in Firefox but does appear after further refreshes.
What the heck is going on ?
(drawImage() method is called in the showIntro() function)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Example 1 - Title Screen</title>
<script>
window.onload = function () {
var canvas = document.getElementById('myCanvas');
var c = canvas.getContext('2d');
var State = {
_current: 0,
INTRO: 0,
LOADING: 1,
LOADED: 2
}
window.addEventListener('click', handleClick, false);
window.addEventListener('resize', doResize, false);
doResize();
function handleClick() {
State._current = State.LOADING;
fadeToWhite();
}
function doResize() {
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;
switch (State._current) {
case State.INTRO:
showIntro();
break;
}
}
function fadeToWhite(alphaVal) {
// If the function hasn't received any parameters, start with 0.02
var alphaVal = (alphaVal == undefined) ? 0.02 : parseFloat(alphaVal) + 0.02;
// Set the color to white
c.fillStyle = '#FFFFFF';
// Set the Global Alpha
c.globalAlpha = alphaVal;
// Make a rectangle as big as the canvas
c.fillRect(0, 0, canvas.width, canvas.height);
if (alphaVal < 1.0) {
setTimeout(function () {
fadeToWhite(alphaVal);
}, 30);
}
}
function showIntro() {
var phrase = "Click or tap the screen to start the game";
// Clear the canvas
c.clearRect(0, 0, canvas.width, canvas.height);
// Make a nice blue gradient
var grd = c.createLinearGradient(0, canvas.height, canvas.width, 0);
grd.addColorStop(0, '#ceefff');
grd.addColorStop(1, '#52bcff');
c.fillStyle = grd;
c.fillRect(0, 0, canvas.width, canvas.height);
var logoImg = new Image();
logoImg.src = './logo.png';
// Store the original width value so that we can keep
// the same width/height ratio later
var originalWidth = logoImg.width;
// Compute the new width and height values
logoImg.width = Math.round((50 * document.body.clientWidth) / 100);
logoImg.height = Math.round((logoImg.width * logoImg.height) / originalWidth);
// Create an small utility object
var logo = {
img: logoImg,
x: (canvas.width / 2) - (logoImg.width / 2),
y: (canvas.height / 2) - (logoImg.height / 2)
}
// Present the image
c.drawImage(logo.img, logo.x, logo.y, logo.img.width, logo.img.height);
// Change the color to black
c.fillStyle = '#000000';
c.font = 'bold 16px Arial, sans-serif';
var textSize = c.measureText(phrase);
var xCoord = (canvas.width / 2) - (textSize.width / 2);
c.fillText(phrase, xCoord, (logo.y + logo.img.height) + 50);
}
}
</script>
<style type="text/css" media="screen">
html { height: 100%; overflow: hidden }
body {
margin: 0px;
padding: 0px;
height: 100%;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="100" height="100">
Your browser doesn't include support for the canvas tag.
</canvas>
</body>
</html>
The problem is that you aren't waiting for the image to load when you call drawImage().
You could use something like:
logo.img.onload = function(){
c.drawImage(logo.img, logo.x, logo.y, logo.img.width, logo.img.height);
};
Although make sure you don't start modifying the canvas until this has happened.