I want to use onmouseover in this javascript code. So, whenever I move the mouse over the square, the function changeColor executes and picks one color each time, from the two given colors.
<!DOCTYPE html>
<html>
<head>
<title>TEST</title>
</head>
<body>
<h1>Canvas Art Gallary</h1>
<canvas id="myCanvas" width="400" height="300" style="border:10px solid #c3c3c3">
</canvas>
<script type="text/javascript">
function changeColor(){
ctx.fillStyle = "#FFFFFF";
ctx.fillStyle = "#04B45F";
}
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(150,100,100,100);
</script>
</body>
</html>
Thanks
Listen for mouse events and toggle the color on our own custom mouseenter
Note: the rect does not have mouseenter so we must custom build one.
Listen for mousemove events
On rect mouseenter: set a wasInside flag to true and changeColor() which toggles the rect color
On rect mouseleave: clear a wasInside flag to indicate the mouse has left the rect.
Example code and a Demo: http://jsfiddle.net/m1erickson/9GcbH/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color:ivory; }
#canvas{border:1px solid red;background-color:black;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var toggle=0;
var x=150;
var y=100;
var w=100;
var h=100;
var wasInside=false;
// draw the rect to start
ctx.fillStyle = "red";
ctx.fillRect(x,y,w,h);
function changeColor(){
if(toggle==0){
ctx.fillStyle = "#FFFFFF";
toggle=1;
}else{
ctx.fillStyle = "#04B45F";
toggle=0;
}
ctx.fillRect(x,y,w,h);
}
function handleMouseMove(e){
e.preventDefault();
var mx=parseInt(e.clientX-offsetX);
var my=parseInt(e.clientY-offsetY);
var isInsideNow=(mx>x && mx<x+w && my>y && my<=y+h);
if(isInsideNow && !wasInside){
changeColor();
wasInside=true;
}else if(!isInsideNow && wasInside){
wasInside=false;
}
}
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<h4>Rect color toggles white-green<br>each time mouse moves over it.</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
[ Addition: explain steps of toggling ]
Each time the mouse enters the rect changeColor is called.
changeColor both changes the color and also changes toggle.
Here's a step-by-step:
1. toggle==0 at the beginning of the ap
2. mouse enters rect and changeColor is called.
3. changeColor changes color to #ffffff because toggle==0.
4. changeColor changes toggle=1
5. mouse exits rect
6. mouse enters rect again and changeColor is called again.
7. changeColor changes color to #04b45f because toggle==1.
8. changeColor changes toggle=0;
mouseover will only know when you're over the canvas, so you need to detect you're above the square (I'm using the variables already defined by you):
var sqx1 = c.offsetLeft + 150; //left top corner of the square respect to the window
var sqy1 = c.offsetTop + 100;
var sqx2 = sqx1 + 100; //right bottom corner of the square respect to the window
var sqy2 = sqy1 + 100;
var lastOverSquare = false;
c.addEventListener('mousemove', function(e) {
var overSquare =
(sqx1 <= e.pageX && sqx2 >= e.pageX) &&
(sqy1 <= e.pageY && sqy2 >= e.pageY);
if (overSquare && !lastOverSquare) changeColour(); //change only when it enters the square, not every move when we're already over it.
lastOverSquare = overSquare;
}, false);
var colours = ['#FFFFFF', '#04B45F'];
var currentColour = 0;
ctx.fillStyle = colours[currentColour];
function changeColour() {
currentColour = (currentColour + 1) % colours.length;
ctx.fillStyle = colours[currentColour];
}
Related
I am trying to create a rect that moves on keypress for a pong game and when I press the key the left rect disappears..
Any ideas how to fix the problem? It is really important..
The code is written in vanilla javascript so please don't write jQuery..
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pong</title>
<script type="text/javascript">
var x = 100;
var y = 100;
var xmoveFirst = 720;
var ymoveFirst = 0;
var xmoveSecond = 30 ;
var ymoveSecond = 0;
function canvas() {
var can = document.getElementById('theCanvas');
can.style.backgroundColor = "black";
var ctx = can.getContext('2d');
//first player
ctx.fillStyle="white";
ctx.fillRect(xmoveFirst,ymoveFirst,5,75);
//second player
ctx.fillStyle = 'white';
ctx.fillRect(xmoveSecond,ymoveSecond,5,75);
//first player move
function moveFirst(eFirst) {
ctx.clearRect(0,0,750,750); //clear rects
if (eFirst.keyCode == 40) {
ymoveFirst+=25;
console.log("first,"+ymoveFirst);
}
else if (eFirst.keyCode == 38) {
ymoveFirst-=25;
console.log("first,"+ymoveFirst);
}
ctx.fillStyle="white";
ctx.fillRect(xmoveFirst,ymoveFirst,5,75);
ctx.fillRect(xmoveSecond,ymoveSecond,5,75);
}
var first = document.onkeydown = moveFirst;
//second player move
function moveSecond(eSecond) {
ctx.clearRect(0,0,750,750);
if (eSecond.keyCode == 83) {
ymoveSecond+=25;
console.log("second,"+ymoveSecond);
}
else if (eSecond.keyCode == 87) {
ymoveSecond-=25;
}
ctx.fillStyle="white";
ctx.fillRect(xmoveFirst,ymoveFirst,5,75);
ctx.fillRect(xmoveSecond,ymoveSecond,5,75);
console.log("second,"+ymoveSecond)
}
var second = document.onkeydown = moveSecond;
}
83,87
</script>
</head>
<body onload="canvas()">
<canvas id="theCanvas" width="750" height="750"></canvas>
</body>
</html>
This line: can.width=can.width; resets the canvas width.
When you change the canvas size (width or height), you clear the canvas (making everything black). After this line, you are only redrawing the rightmost paddle, so the left one remains missing.
You'll need to redraw the leftmost paddle as well if you want it to come back. Here is the modified moveRight() function:
function moveRight(eFirst) {
if (eFirst.keyCode==40) {
ymoveFirst+=25;
console.log(ymoveFirst);
}
else if (eFirst.keyCode==38) {
ymoveFirst-=25;
console.log(ymoveFirst);
}
can.width=can.width;
ctx.fillStyle="white";
// Redraw BOTH paddles
ctx.fillRect(xmoveFirst,ymoveFirst,5,75);
ctx.fillRect(xmoveSecond,ymoveSecond,5,75);
}
Also, replace
document.onkeydown = moveFirst; and document.onkeydown = moveSecond;
with
document.addEventListener("keydown", moveFirst);, and document.addEventListener("keydown", moveSecond);
Currently, you are overwritting the first listener with document.onkeydown = moveSecond;. By using addEventListener, you don't overwrite the ones that already exist.
After pressing a button, I'd like to draw a circle at the tip of the mouse pointer on a canvas and then place it when the user clicks again. Here's what I've got so far:
$("#button").click(function(e){
var canvas = document.getElementById('MyCanvas');
var context = canvas.getContext('2d');
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
console.log(message);
var nodehandle = document.getElementById('circle');
if(mousePos.x && mousePos.y) {
nodehandle.x = mousePos.x;
nodehandle.y = mousePos.y;
flag = 1;
}
}, false);
});
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
My problem is that when I draw a circle like this:
function drawCircle(mouseX, mouseY){
var c = document.getElementById("grid");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(95,50,5,0,2*Math.PI);
ctx.stroke();
}
I don't know how to select that circle (the getElementById('circle') returns null even if I add ctx.id='circle' to the drawCircle function). I'm also going to need to erase and redraw the circle each time the mouse moves, and I'm sure there's a nice way to do that but I'm not aware of it.
Anything you draw on the canvas--like circles, are just like dried paint on the canvas.
Your circles cannot be selected or moved like html elements.
To move a circle you must clear the canvas and redraw the circle at a different location.
It's convenient to store info about the circle in an object.
var circle1 = { centerX:100, centerY=100, radius=20 }
And you can draw circle1 using that info:
ctx.beginPath();
ctx.arc(circle1.centerX, circle1.centerY, circle1.radius, 0,Math.PI*2);
ctx.closePath();
ctx.fill();
For more than 1 circle you can create a circles array and put each circle object into that array
var circles=[];
circles.push(circle1);
Then to "move" a circle, just change the object's centerX/centerY to the mouse position and redraw all the circles on the canvas.
circle1.centerX=mouseX;
circle1.centerY=mouseY;
// Clear the canvas and redraw all circles
// The "moved" circle will be redrawn at its new position
function drawAll(){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<circles.length;i++){
var c=circles[i];
ctx.beginPath();
ctx.arc(c.centerX,c.centerY,c.radius,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle=c.color;
ctx.fill();
}
}
You can use Html radio buttons to determine which action a mouse-click will do:
Create a new circle at the mouse position, or
Select the circle under the mouse position, or
"Move" the currently selected circle
Here's example code and a Demo: http://jsfiddle.net/m1erickson/CEB7T/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
// get references to the canvas and its context
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
// get the canvas position on the page
// used to get mouse position
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
ctx.lineWidth=3;
// save info about each circle in an object
var circles=[];
var selectedCircle=-1;
// the html radio buttons indicating what action to do upon mousedown
var $create=$("#rCreate")[0];
var $select=$("#rSelect")[0];
var $move=$("#rMove")[0];
// draw all circles[]
function drawAll(){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<circles.length;i++){
var c=circles[i];
ctx.beginPath();
ctx.arc(c.cx,c.cy,c.radius,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle=c.color;
ctx.fill();
// if this is the selected circle, highlight it
if(selectedCircle==i){
ctx.strokeStyle="red";
ctx.stroke();
}
}
}
function handleMouseDown(e){
e.preventDefault();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
if($create.checked){
// create a new circle a the mouse position and select it
circles.push({cx:mouseX,cy:mouseY,radius:10,color:randomColor()});
selectedCircle=circles.length-1;
}
if($select.checked){
// unselect any selected circle
selectedCircle=-1;
// iterate circles[] and select a circle under the mouse
for(var i=0;i<circles.length;i++){
var c=circles[i];
var dx=mouseX-c.cx;
var dy=mouseY-c.cy;
var rr=c.radius*c.radius;
if(dx*dx+dy*dy<rr){ selectedCircle=i; }
}
}
if($move.checked && selectedCircle>=0){
// move the selected circle to the mouse position
var c=circles[selectedCircle];
c.cx=mouseX;
c.cy=mouseY;
}
// redraw all circles
drawAll();
}
// return a random color
function randomColor(){
return('#'+Math.floor(Math.random()*16777215).toString(16));
}
// handle mousedown events
$("#canvas").mousedown(function(e){handleMouseDown(e);});
}); // end $(function(){});
</script>
</head>
<body>
<input type="radio" name="grp1" id="rCreate" checked>Click will create a new circle.<br>
<input type="radio" name="grp1" id="rSelect">Click will select an existing circle.<br>
<input type="radio" name="grp1" id="rMove">Click will move selected circle.<br>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
I have this code in my project, here is the link: http://jsfiddle.net/89wgk/
This is my code:
<canvas id="myCanvas" width="188" height="200"></canvas>
var rectWidth = 110;
var rectHeight = 110;
var rectX = 10;
var rectY = 25;
When I put the mouse in curved rectangle starts the shadow, but I want that to happen when I put the mouse over the reeds (rectangle) and not within the canvas.
I wonder how do I run the shadow so when I move the mouse over the rectangle?
Here is how I would do it:
create a function that draws the arc shape because it must be redrawn often
listen for mouseMove events on the canvas
test whether the mouse is inside the arc with context.isPointInside(mouseX,mouseY)
redraw the arc with/without the shadow based on if the mouse is inside the arc
Have Fun!
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/64BHx/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var w = 110;
var h = 110;
var x = 10;
var y = 25;
var isShadowed=false;
context.strokeStyle="#FF2A2A";
context.shadowBlur = 20;
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
context.globalAlpha=.250;
context.strokeRect(x,y,w,h);
context.globalAlpha=1.00;
function draw(){
// clear the canvas
context.clearRect(0,0,canvas.width,canvas.height);
// save the context state
context.save();
// set/clear the shadow based on isShadowed
context.shadowColor= isShadowed ? '#7FD4FF' : "#FFFFFF";
// draw the arc shape
context.beginPath();
context.moveTo(x,y);
context.quadraticCurveTo(x+w-2,y+2,x+w,y+h);
context.lineTo(x+w-35,y+h);
context.quadraticCurveTo(x+w-2-35,y+2+35,x,y+35);
context.lineTo(x,y);
context.fillStyle="red";
context.fill();
context.stroke();
// restore the context state
context.restore();
}
// testing: display if mouse is in/out of arc shape
var $status=$("#status");
// listen for mousemove events
$("#canvas").mousemove(function(e){handleMouseMove(e);});
// handle mousemove events
function handleMouseMove(e){
// we alone are using mousemove events
e.preventDefault();
// get current mouse X/Y
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// hit test if mouse is inside the arc shape
var isInside=context.isPointInPath(mouseX,mouseY);
$status.text("Is mouse inside: "+isInside);
// don't redraw unless needed
if(isInside && isShadowed){return;}
if(!isInside && !isShadowed){return;}
// change the shadow and redraw
isShadowed=isInside;
draw();
}
// start by drawing the unshadowed arc
draw();
}); // end $(function(){});
</script>
</head>
<body>
<p id="status">Status</p><br>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
Hi i'm having trouble getting my paint canvas buttons that change the colours of the paint brush to move beside the canvas.
It seems to be stuck at the tope left hand corner of the webpage unfortunately and i'm struggling trying to re-locate it. And suggestions would be very helpful. Thank you.
Here is some of my code that should give you an idea of what im talking about.
var brush = 10;
function changeColour(colour)
{
g.fillStyle = colour;
}
function clearCanvas()
{
g.clearRect(0, 0, canvas.width, canvas.height);
}
var mouseIsDown = false;
function down(e)
{
mouseIsDown = true;
/*e.originalEvent.preventDefault();*/
}
function up(e)
{
mouseIsDown = false;
}
function changeBrushSize(symbol)
{
if(symbol =='+')
{
brush = brush + 2;
}
else if (symbol == '-')
{
brush = brush - 2;
}
}
function move(e)
{
var container = document.getElementById('container');
//g.clearRect(0, 0, canvas.width, canvas.height);
//g.fillRect(e.x - 5, e.y - 5, 100, 100);
if((e.button == 0) && (mouseIsDown))
{
g.beginPath();
document.onselectstart = function(){ return false; }
//g.fillStyle = "red";
g.arc((e.x - container.offsetLeft) - brush, (e.y - container.offsetTop) - brush, brush, 0, Math.PI * 2);
g.fill();
g.closePath();
}
}
</script>
</head>
<body>
<div id="container">
<canvas id = "paintCanvas" width = "500" height = "500">
Your browser does not support the HTML5 <canvas> tag.
</canvas>
</div>
<button onclick ="clearCanvas()">Clear Canvas</button></br>
<button onclick ="changeColour('red')">Red</button>
<button onclick ="changeColour('green')">Green</button>
<button onclick ="changeColour('blue')">Blue</button>
<button onclick ="changeColour('yellow')">Yellow</button>
<button onclick ="changeColour('orange')">Orange</button>
<button onclick ="changeColour('brown')">Brown</button>
<button onclick ="changeColour('purple')">Purple</button></br>
<button onclick ="changeBrushSize('+')">Bigger Brush</button>
<button onclick ="changeBrushSize('-')">Smaller Brush</button>
</body>
You might let the user select their colors and other tools from a second "tools" canvas
Then position the "tools" canvas before the "drawing" canvas.
<canvas id="toolsCanvas"></canvas><br>
<canvas id="drawingCanvas"></canvas>
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/y5xu7/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: white; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("drawingCanvas");
var context=canvas.getContext("2d");
var tools=document.getElementById("toolsCanvas");
var ctx=tools.getContext("2d");
var canvasOffset=$("#toolsCanvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var colors=['Red','Green','Blue','Yellow','Orange','Brown','Purple']
var lightcolors="Yellow|White";
var colorPickerWidth=25;
// draw the color picker
tools.width=colors.length*colorPickerWidth;
for(var i=0;i<colors.length;i++){
ctx.fillStyle=colors[i];
ctx.fillRect(i*colorPickerWidth,0,colorPickerWidth,25);
}
// called when the user clicks and picks a color
function handleMouseDown(e){
console.log("down");
var x=parseInt(e.clientX-offsetX);
var color=colors[parseInt(x/colorPickerWidth)];
ctx.save();
ctx.fillStyle=color;
ctx.fillRect(0,28,tools.width,25);
ctx.fillStyle="white";
if(lightcolors.indexOf(color)>-1){ctx.fillStyle="black";}
ctx.font="16px verdana";
ctx.fillText("Selected: "+color,10,45);
ctx.restore();
context.clearRect(0,0,canvas.width,canvas.height);
context.fillStyle=color;
context.font="14px arial";
context.fillText("fillStyle==your selected color",30,100);
}
$("#toolsCanvas").mousedown(function(e){handleMouseDown(e);});
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="toolsCanvas" width=300 height=53></canvas><br>
<canvas id="drawingCanvas" width=300 height=300></canvas>
</body>
</html>
I'd like to show a mouse tooltip like this:
with a coordinate system relative to its image.
Whenever the mouse is hovered over one of the 75x75 cells, the position is displayed in text. I can only show the mouse's raw coordinates, but can't figure out the math to display it like it is in the picture.
I'm open to HTML5 implementations as well.
Here’s how to convert mouse coordinates to cell coordinates and display a tooltip
This math calculates which 75x75 cell your mouse is inside:
var col=parseInt(mouseX/75);
var row=parseInt(mouseY/75);
And here is the math to calculate a tip rectangle in the upper-right of that cell:
var tipX=tipCol*75+75-tipWidth;
var tipY=tipRow*75;
You can use canvas to draw the tip inside the cell at your calculated coordinates:
function tip(x,y){
var tipX=tipCol*75+75-tipWidth;
var tipY=tipRow*75;
ctx.beginPath();
ctx.rect(tipX,tipY,tipWidth,tipHeight);
ctx.fillStyle="ivory";
ctx.fill();
ctx.fillStyle="blue";
ctx.fillText(tipCol+","+tipRow,tipX+2,tipY+17);
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/9V5QK/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:25px;}
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var startX;
var startY;
var isDown=false;
var tipWidth=35;
var tipHeight=22;
var tipRow;
var tipCol;
ctx.font="14pt verdana";
draw();
function draw(){
// you would just draw your image here
// ctx.drawImage(0,0,image.width,image.height);
// but for illustration, this just recreates your image
ctx.beginPath();
ctx.rect(0,0,375,225);
for(var x=1;x<5;x++){ ctx.moveTo(x*75,0); ctx.lineTo(x*75,canvas.height); }
for(var y=1;y<3;y++){ ctx.moveTo(0,y*75); ctx.lineTo(canvas.width,y*75); }
ctx.fillStyle="black";
ctx.fill();
ctx.strokeStyle="gray";
ctx.lineWidth=2;
ctx.stroke();
}
function tip(x,y){
var tipX=tipCol*75+75-tipWidth;
var tipY=tipRow*75;
ctx.beginPath();
ctx.rect(tipX,tipY,tipWidth,tipHeight);
ctx.fillStyle="ivory";
ctx.fill();
ctx.fillStyle="blue";
ctx.fillText(tipCol+","+tipRow,tipX+2,tipY+17);
}
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
$("#movelog").html("Move: "+ mouseX + " / " + mouseY);
// Put your mousemove stuff here
var col=parseInt(mouseX/75);
var row=parseInt(mouseY/75);
if(!(row==tipRow && col==tipCol)){
tipCol=col;
tipRow=row;
draw();
tip();
}
}
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<p>Move mouse over grid to display current cell</p>
<p id="movelog">Move</p>
<canvas id="canvas" width=375 height=225></canvas>
</body>
</html>