I'm drawing rectangles on a canvas with Javascript. When the user moves his mouse over one of the rectangles, a text should appear in that rectangle. At only that rectangle (i.e., not the other rectangles).
So I managed to draw the rectangles and created the mouseover event. It works perfectly: as soon as the mouse moves over one of the rectangles the text appears. However, the text appears in ALL rectangles... Any thought about what I'm doing wrong? There seems to be a looping problem, but I can't seem to fix it.
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
for(var i=0;i<entities.length;i++){
var entity=entities[i];
ctx.rect(entity.x, entity.y, width, height);
if(ctx.isPointInPath(mouseX,mouseY)){
ctx.font = "10px Arial";
ctx.fillStyle = "black";
ctx.textAlign = "left";
ctx.fillText("edit", entity.x + 5 , entity.y + 5 );
}
}
}
The isPointInPath method will check if the given coordinates are in any of the shapes formed by the current path. Every rect is added to the same, single path which has already been created during your initialisation code that draws the rectangles.
So the effect is that once your mouse is over any of the drawings, the condition is true in each iteration of your loop.
Solve this by creating a new path in each iteration:
for(var i=0;i<entities.length;i++){
var entity=entities[i];
ctx.beginPath(); // <----
ctx.rect(entity.x, entity.y, width, height);
// ...etc
Related
I want to draw something like a donut, so a circle with a hole in the middle. I tried using ctx.clip(), but I realized it limits the path to inside, and I want it to limit the path to the outside.
Things to note:
this.lineWidth is how thick the "rim" or the outside portion is
ctx.beginPath();
// this should be the hole
ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false);
ctx.clip();
// this should be the outside part
ctx.arc(this.x,this.y,this.r+this.lineWidth,0,Math.PI*2,false);
ctx.fillStyle = "#00ff00";
ctx.fill();
Instead I'm getting a filled-in circle because it's limiting the path to inside the smaller arc instead of outside it. Is there another method that does the opposite of clip()?
I found this solution http://jsfiddle.net/Hnw6a/:
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
//ctx.arc(x,y,radius,startAngle,endAngle, anticlockwise);
ctx.beginPath()
ctx.arc(100,100,100,0,Math.PI*2, false); // outer (filled)
ctx.arc(100,100,55,0,Math.PI*2, true); // outer (unfills it)
ctx.fill();
With following canvas node:
<canvas id="canvas1" width="500" height="500"></canvas>
Set the linewidth to the desired width, draw your circle, and use "ctx.stroke();". Note that this doesn't allow you to fill the inner circle with a color.
I am new in canvas can anyone please help to short this issue.
I create 5 canvas circle. When I hover on any circle I need to change canvas color only, when hover on circle I added one class on canvas but is it possible to change only color. I don't want to create canvas again change only color when hover.
$(document).ready(function(){
$('.menuballs').hover(function () {
$(".menuballs").children('canvas').toggleClass('hover-intro');
if($(this).is(':hover'))
{
var c = document.getElementsByClassName("hover-intro");
var graphics = c.getContext( '2d' );
graphics.fillStyle = 'green';
graphics.fill();
}
});
});
Try this as taking hover-intro class but its given HTMLElement, and I need CanvasElement to fill in circle.
Your :hover will never be triggered.
Circles drawn on html canvas are not DOM elements. Instead they are like forgotten painted pixels on a canvas.
These are the steps to apply a hover-effect to your circle
Keep track of your circle's definition (x,y,radius,etc) in a javascript object.
Listen for mousemove events and test if the mouse is inside your circle
When the mouse enters or leaves your circle, redraw your circle
This is how those steps might look in code:
Demo: http://jsfiddle.net/m1erickson/rV9cZ/
Keep track of your circle's definition (x,y,radius,etc) in a javascript object.
var myCircle={
x:150,
y:150,
radius:25,
rr:25*25, // radius squared
hovercolor:"red",
blurcolor:"green",
isHovering:false
}
Listen for mousemove events and test if the mouse is inside your circle
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
var dx=mouseX-myCircle.x;
var dy=mouseY-myCircle.y;
// math to test if mouse is inside circle
if(dx*dx+dy*dy<myCircle.rr){
// change to hovercolor if previously outside
if(!myCircle.isHovering){
myCircle.isHovering=true;
drawCircle(myCircle);
}
}else{
// change to blurcolor if previously inside
if(myCircle.isHovering){
myCircle.isHovering=false;
drawCircle(myCircle);
}
}
}
When the mouse enters or leaves your circle, redraw your circle
function drawCircle(circle){
ctx.beginPath();
ctx.arc(circle.x,circle.y,circle.radius,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle=circle.isHovering?circle.hovercolor:circle.blurcolor;
ctx.fill();
}
So I'm creating a simple userscript for me - I want to draw a play button over shaded version of any GIF image on the site to have them only played when I want to.
I have inspired myself here. To make the whole thing nice, I'm drawing a green circle over the animation. This is my intended effect (I really wonder if once can make some shapes in GIMP):
And this is what I currently have:
The Cleese ironic face animation comes from this GIF portal
I made a fiddle of my current GIF pauser userscript.
The critical code for printing the circle:
//Assume these variables
var ctx = canvas context (2d)
var w = canvas width
var h = canvas height
//The code:
ctx.beginPath();
//I'm making sure the circle will always fit - therefore Math.min
ctx.arc(w/2, h/2, Math.min(60, w/2-20, h/2-20), 0, 2 * Math.PI, false);
ctx.fillStyle = 'rgba(0,180,0,0.5)';
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = 'red';
ctx.stroke();
ctx.closePath();
I hope it's clear that the triangle must always fit into the circle (size of which may vary). It must have the vertical line a little bit shorter then the other two, which must be of equal length.
I'm totally not interested in any existing GIF pausing libraries. Keep in mind that the question is about the triangle, not the GIFs.
Like this? http://jsfiddle.net/32ECU/
//Draw a triangle in it
ctx.strokeStyle = 'white';
ctx.beginPath();
ctx.moveTo(w/3, h/3);
ctx.lineTo(w/3, h-h/3);
ctx.lineTo(w-w/4, h/2);
ctx.lineTo(w/3, h/3);
ctx.fillStyle = 'white';
ctx.fill();
I am trying to draw a gear in Canvas but running into issues from the start. I want to have a filled circle with a hallowed out middle. Instead, I am getting what looks to be an outline of a single circle.
Here is my code:
var ctx = document.getElementById("canvas").getContext("2d"),
i = 0;
function drawGear(){
ctx.fillStyle = "#000";
ctx.translate(50,50);
ctx.arc(0,0,20,0,Math.PI*2);
ctx.fill();
ctx.fillStyle = "#FFF";;
ctx.arc(0,0,5,0,Math.PI*2);
ctx.fill();
}
drawGear();
http://jsfiddle.net/te3jn/
I believe that the issue is something related to the globalCompositeOperation, but I tried several of them (source-over, source-atop, destination-over) and none seem to work the way I want.
You should begin a new path when drawing the second circle, like this:
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "#FFF";
// ...
JS Fiddle.
Without this, you'll essentially redraw both circles - the inner and the outer one - with the second fill call (check this fiddle for demonstration)
I am drawing some arrows in canvas (similar arrows can be viewed in a life cycle). I want to draw border to all these arrows individually just like we add to divs. I tried using stroke style and stroke method but it filled my entire arrow.
I am using fill style and fill to fill color to my arrows.
Is there any way to do it? Is it like fill and stroke methods can never be used together?
You'll have to use beginPath() and closePath() on your canvas's context ("ctx" down here), followed by a fill() to actually fill the element:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(170, 80);
ctx.lineTo(300,150);
ctx.lineTo(100,150);
ctx.lineTo(170, 80);
// Etc, Make your movements to draw the arrow, here.
ctx.closePath();
//Line settings and drawing
ctx.lineWidth = 5;
ctx.strokeStyle = 'blue';
ctx.stroke();
//Fill settings and drawing
ctx.fillStyle = '#8ED6FF';
ctx.fill();