I have an image that's being displayed on an HTML5 canvas, to which I have added an onmouseover event that theoretically should call a JavaScript function that has been written in the same file.
However, when I view my page, and hover the cursor over the image, nothing happens.
I've added the image to a hidden section of my HTML using the line:
<img id="assetBox" src = "images/box.png" alt="Assets" onmouseover = "displayAssetDescriptionTip()"/>
The image has then been drawn to the canvas using the function:
function drawDescriptionBoxes(){
var assetsDescriptionBox = document.getElementById("assetBox");
var liabilitiesDescriptionBox = document.getElementById("liabilitiesBox");
var incomeDescriptionBox = document.getElementById("incomeBox");
var expenditureDescriptionBox = document.getElementById("expenditureBox");
assetsDescriptionBox.src = 'images/box.png';
liabilitiesDescriptionBox.src = 'images/box.png';
incomeDescriptionBox.src = 'images/box.png';
expenditureDescriptionBox.src = 'images/box.png';
context.drawImage(assetsDescriptionBox, 70, 400, 120, 70);
context.drawImage(liabilitiesDescriptionBox, 300, 400, 120, 70);
context.drawImage(incomeDescriptionBox, 530, 400, 120, 70);
context.drawImage(expenditureDescriptionBox, 760, 400, 120, 70);
context.strokeText("Assets", 100, 490);
context.strokeText("Liabilities", 325, 490);
context.strokeText("Income", 550, 490);
context.strokeText("Expenditure", 775, 490);
}
and the function that I want to be called when the cursor is detected as hovering over the image is:
function displayAssetDescriptionTip(){
document.getElementById('tipsParagraph').innerHTML = "Assets are items that can be bought or sold for cash.";
console.log("displayAssetDescriptionTip being called");
}
But, for some reason, when I view my page in the browser, and hover the cursor over the image on the canvas, nothing happens, and nothing is displayed in the console... I assume that this means that my onmouseover event isn't firing, but I have no idea why this is- can anyone explain it to me, and point out what I need to do to get it right?
Edit 22/02/2013 # 14:40
I tried adding the following JS to keep track of the mouse coordinates in one of the separate JS files I have:
/*Add code to keep track of the mouse coordinates */
var boundingBox = canvas.getBoundingClientRect();
var mousex = (mouse_event.clientX-boundingBox.left)*(canvas.width/boundingBox.width);
var mouseY = (mouse_event.clientY-boundingBox.top)*(canvas.height/boundingBox.height);
I know I will have to write the code to tell the script what to actually do with the coordinates, but I just wanted to give this a try first, since it's been a while since I've done any work with coordinates myself. But when I view the page in a browser, I'm getting a console error that says that "canvas is not defined, and complains about the line:
var boundingBox = canvas.getBoundingClientRect();
I'm wondering if this is because this is a separate script file, and doesn't actually have any reference to the canvas I'm using until where I've just added it. Do I need to define it again, even though it's already been defined in the HTML page that this script is being run on?
Just drawing an image doesn't magically make the image behave like a node. For instance, you can't change its src and have it automatically change the image shown on the canvas.
Instead, you have to manually track mouse movement with onmousemove on the canvas, then compute what the mouse is hovering over and do something about it. Having had experience making menus in Game Maker, I can tell you it's hard as hell!
This is an assumption, but the image that is drawn is a different element then the one that you have the onmouseover on. Try adding a class to the image and the one being drawn and set the onmouseover on the class (check jQuery to make this process easier)
Related
The Raphael Js website is down so I can't find any documentation or anything on how to do this. I want to create a rectangle with initial vertical size of 0 and make it animate so that it gets vertically larger and larger when I click another object. Thanks!
so i've got a rectangle
var water = paper.rect( 0, 300, 600, 0).attr({fill:"blue"});
how do I make it animate?
In particular, check out the documentation for
Element.attribute(),
Element.animate(),
Element.click(), and
Raphael.animation().
The following snippet demonstrates a simple animation like the one you are looking for. Click the red square to make the water "fill". It may not work in some browsers (e.g. Chrome) possibly because the snippet is trying to access an external third-party library, i.e. Raphael.js. So, to run it, either go to this SO question/answer page on Firefox or copy the code and run it on your own computer.
Note that, to make the water "fill" in the up direction, you can't just increase the height of the water rectangle...that would make the rectangle grow downwards. You also have to simultaneously raise the top of the rectangle by the identical amount. Thus you have to animate height and y simultaneously, as shown in the code.
UPDATE: provided an up-to-date link for the Raphael minified library
var paper = Raphael(0, 0, 500, 120);
var button = paper.rect( 10, 10, 40, 20).attr({fill:"red"});
var water = paper.rect( 10, 100, 400, 0).attr({fill:"blue"});
var anim = Raphael.animation({
height: 60,
y: (100 - 60)
}, 2000);
button.click(function() {water.animate(anim);});
<script src="https://raw.githubusercontent.com/DmitryBaranovskiy/raphael/master/raphael.min.js"></script>
To get the animation to start, click on the red rectangle.
I am using fabric Js on canvas where:
I am developing a product page for an e-commerce website where
I have drawn a background image and created a polygon on it and then inside of the polygon I have uploaded images, that works fine.
But now I have to make an image crop function inside the polygon for each image so that when I click on it I can crop it.
I have used canvas context.drawImage();. Function which works fine but when I click on the image or anywhere else on the canvas it disappears and I can't select it.
Can any one please help me with it ?
The code follows as
var image = new Image();
image.src = "uploads/cat.jpg";
image.onload = function(){
context.drawImage(image, 0, 19, 69, 97, 300, 100, 103, 145);
context.Image.selectable = true;
}
I could be missing something here without seeing more context but I think if you used fabric.Image feature to draw your image instead of context.draw image it might work? Seems like there might be an issue happening with mixing fabric functions and regular canvas drawing. image.Fabric
Sorry if I misunderstood! I'm a little fuzzy on the description of your image/shape stack order, screenshot might help if this answer doesn't apply.
I am working with CreateJs and the whole program I am working on is within a canvas element. Within that element I have a few (5-6 areas) where all the elements within it, should now go outside and should be cut.
I have made an image for you that explains the situation. The yellow part is the program. The red border is an area, where all elements within it should not go outside (I put an image in it, which is cut)
Do you have any idea how I can do that?
as mentioned by Marton I just masked the container. Here the code:
var container = new createjs.Container();
var maskShape = new craetejs.Shape();
maskShape.graphics.drawRect(50, 50, 200, 200); // x, y, width, height
container.mask = maskShape;
Is there any trick to determine if user clicks on given element rendered in canvas? For example I'm displaying rhombus from .png file with transparent background and i want to know if user click inside or outside that figure (like mouse-element collision).
There is no concept of individual elements in a canvas - it is simply just an area that you're drawing pixels onto. SVG on the other hand is made up of elements which you can then bind events to. However there are a few approaches you can take to add click events to canvas:
Position an html element that overlays the area on the canvas you want to be clickable. A for a rectangular area or an image map for something more irregular.
Use separate canvases for each element that you want to be clickable.
CAKE - I haven't used this myself, but it's description is "SVG sans the XML". This may cover your needs. Demos here http://glimr.rubyforge.org/cake/canvas.html#EditableCurve
One idea is to draw the image to a temporary canvas, then use getImageDate() to receive data for the pixel you are interested in, and check if its alpha value is 0 ( = transparent).
The following is a sketch of a solution. It is assumed that...
x and y are the coordinates of the mouse click event
you are looping over gameObjects, the current object being stored in the variable gameObject
the game object has been initialized with an image, x and y coordinates
The following code would then check whether the click was on a transparent area:
var tempCanvas = document.createElement('canvas');
if (tempCanvas.getContext) {
tempContext = tempCanvas.getContext('2d');
}
tempContext.drawImage(gameObject.img, 0, 0);
var imgd = tempContext.getImageData(x - gameObject.x, y - gameObject.y, 1, 1);
var pix = imgd.data;
if (pix[3] == 0) {
// user clicked on transparent part of the image!
}
Note: This is probably quite inefficient. I'm sure someone can come up with a better solution.
I have solve this problem using kintech.js, tutorials and examples can be found: http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-tutorial/
I am experimenting with html5 and I have a little image dropdown, the user selects and image and it draws it to the canvas using drawImage();
I can't seem to figure out how to add an event listener to the newly drawn image on the canvas.
I have tried putting it in a variable like so:
var newImg = ctx.drawImage(myImage, 200, 200);
and then adding an eventlistener to that, but it doesn't seem to work.
newImg.addEventListener('mousedown', onImgClick, false);
What is the correct way to do this.
If you're looking for this sort of interactivity, <canvas> is probably not what you want. You're looking for SVG. There is a fantastic library called Raphaël that makes working with SVG a piece of cake on all browsers, even on IE6. It's also completely compatible with jQuery, so you can do:
var paper = Raphael(10, 50, 320, 200);
var img = paper.image("/path/to/img.png", 10, 10, 80, 80);
$(img).click(onImgClick);
I'm pretty certain this will treat you better and be easier to use than <canvas>.
Note: Raphaël does come with some helpers for basic events like "click" and "mousedown", just do img.click(onImgClick), but if you're already using a library like jQuery, which you probably are, I'd recommend being consistent and using the library's event handling.
Canvas is not a retained-mode drawing surface. It's just a flat image; there is no object inside it to bind events to, and drawImage returns nothing.
You will have to detect clicks on the <canvas> and check if they are inside the [200, 200, 200+w, 200+h] rectangle manually. Or, if you want retained-mode drawing, consider using SVG instead of a canvas.
To do this without the help of JS:
Although you can't attach an event listener to the context on which you call drawImage(); you CAN attach event listeners to the Canvas itself.
myCanvasElement = document.getElementById('canvasElement');
myCanvasElement.addEventListener("click", someFunction, false);
If you need to have this per-image that you draw, you could probably stack the canvas objects and create a new one for each image you draw.