How do you remove only the shape that's in CreateJS? For my example, I have created a few squares with a function called createSquare. My goal is to have a function, or a click event, that removes only the square that is clicked.
I have tried event listeners and on click, and have had no luck. I have commented out the code that I tried to use.
Here is a link to a working fiddle.
JS is as follows:
var canvas;
var stage;
var square;
function init() {
canvas = document.getElementById("canvas");
stage = new createjs.Stage(canvas);
}
function createSquare(){
square = new createjs.Shape();
square.graphics.beginFill("red").drawRect(0, 0, 50, 50)
square.x = Math.random() * canvas.width;
square.y = Math.random() * canvas.height;
stage.addChild(square);
stage.update();
}
// This code should remove the squares
/*
square.on("click", function(evt) {
stage.removeChild(this);
});
*/
window.onload = init();
createSquare();
createSquare();
createSquare();
createSquare();
createSquare();
createSquare();
Event handlers in CreateJS are passed an event object. Mouse events receive a MouseEvent.
The target of the event will be what was clicked on.
square.on("click", function(evt) {
stage.removeChild(evt.target);
stage.update();
});
You will need to add the listener to each square when it is created.
Alternatively, you could listen to the stage one time.
stage.on("click", function(evt) {
stage.removeChild(evt.target);
stage.update();
});
I have a Sharepoint page in which i want to show a hierarchical diagram with boxes.According to my requirement those boxes should work as links to other sharepoint pages in the same site.
Since sharepoint's default designer tools doesn't support designing such diagrams, I created a page with html5 canvas and the element i wanted inside that.
Inside the canvas i created few boxes and lines to connect them.And i added texts inside the boxes.Then i used a mouse listener to check whether the mouse pointer hovers over a box and if so changed the pointer icon and the link to be redirected to.
I added the canvas tag inside the sharepoint page by "Edit Source" and i added the javascript part using 'Embed Code'
Now the code works perfectly in IE and Firefox.
In chrome although the boxes,lines and text are drawn according to the coordinates i gave in the code but But when i hover the mouse over them it gives different coordinates for mouse listener in different browser sizes.So the mouse pointer doesn't change at correct locations ie: over the boxes.
This doesn't happen in firefox or IE. They changes the mouse pointer when it comes over the boxes and links to the pages perfectly.
Why does it change when i use chrome?
And why does it only affect to the mouse listener coordinates.
This is the code i used.(I have removed the repetitive parts which draws other boxes)
Same in jsfiddle
<canvas id="myCanvas" height="500" width="960" style="border: 1px solid;"><img src="" alt=""/> </canvas>
<script>
var canvas = document.getElementById("myCanvas");
var ctx;
var rNBDX = 50; var rNBDY = 150;
var rectWidth = 200;
var rectHeight = 100;
var cornerRadius = 20;
var linkNBD="https://google.com";
var textNBD1 ="Google";
var linkHeight=20;
var linkNum = 0;
function draw(){
canvas = document.getElementById("myCanvas");
if(canvas.getContext){
ctx=canvas.getContext("2d");
//Drawing Lines
ctx.lineWidth = 3;
ctx.strokeStyle = '#000000';
ctx.moveTo(380, 100);
ctx.lineTo(380, 125);
ctx.stroke();
//Drawing Rectangles
ctx.fillStyle="#0b61d0";
ctx.strokeStyle="#0b61d0";
ctx.lineJoin = "round";
ctx.lineWidth = cornerRadius;
ctx.strokeRect(rNBDX+(cornerRadius/2), rNBDY+(cornerRadius/2), rectWidth-cornerRadius, rectHeight-cornerRadius);
ctx.fillRect(rNBDX+(cornerRadius/2), rNBDY+(cornerRadius/2), rectWidth-cornerRadius, rectHeight-cornerRadius);
//Drawing the Texts
ctx.font='24px Segoe UI Light';
ctx.fillStyle = "#FFFFFF";
ctx.fillText(textNBD1,(rNBDX+rectWidth/2)-(ctx.measureText(textNBD1).width)/2,rNBDY+rectHeight/2);
//Add mouse listeners
canvas.addEventListener("mousemove", on_mousemove, false);
canvas.addEventListener("click", on_click, false);
}
}
function on_mousemove (ev) {
var x, y;
if (ev.layerX || ev.layerX == 0) {
x = ev.layerX;
y = ev.layerY;
}
x-=canvas.offsetLeft;
y-=canvas.offsetTop;
if(x>=rNBDX && x <= (rNBDX + rectWidth) && y>=rNBDY && y<= (rNBDY+rectHeight)){
document.body.style.cursor = "pointer";
linkNum=1;
}
else{
document.body.style.cursor = "";
}
}
function on_click(e) {
switch (linkNum)
{
case 1:
window.location = linkNBD;
break;
}
}
draw();
</script>
Try adjusting the mouse coordinates like this:
function on_mousemove (ev) {
var x, y,
rect = canvas.getBoundingClientRect();
x = ev.clientX - rect.left + 1;
y = ev.clientY - rect.top + 1;
...
You will have to add (as in the example) the width of the left/top border though as getBoundingClientRect does not include those (you can calculate this dynamically using getComputedStyle and getPropertyValue of that for the borders).
I'm trying to get an event to work on an image when the user clicks on it.
var canvas = document.createElement("canvas");
canvas.width = 800;
canvas.height = 600;
canvas.style = "border:2px solid black";
canvas.addEventListener('click', clickReporter, false);
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
var clickhere = new Image();
clickhere.onload = function () {
draw();
};
clickhere.src = "clickhere.png";
function draw() {
ctx.drawImage(clickhere, 200, 200);
}
function clickReporter(e) {
alert("Thanks for clicking!");
}
Obviously all this code will just let the alert box go off as long as the user clicks in the canvas. The image is 100 by 100 pixels.
First off: You apparently have an error in you code in regards to the image (at least in the example you provide):
var button = new Image();
clickhere.onload = function () {
draw();
};
clickhere.src = "clickhere.png";
function draw() {
ctx.drawImage(clickhere, 200, 200);
}
Should be like this for the example to work:
var button = new Image();
/// use button for these as well -
button.onload = function () { /// here
draw();
};
button.src = "clickhere.png"; /// here
function draw() {
ctx.drawImage(button, 200, 200); /// and here (or use 'this' instead)
}
The next problem
Canvas doesn't know what we draw into it so we need to make sure we provide all the underlying logic ourselves to handle these sort of things.
For example: Here is one way to check if the region the image was drawn into is clicked:
function clickReporter(e) { /// assign event to some variable
/// adjust mouse click position to be relative to canvas:
var rect = this.getBoundingClientRect(),
x = e.clientX - rect.left,
y = e.clientY - rect.top;
/// check x/y coordinate against the image position and dimension
if (x >= 200 && x <= (200 + button.width) &&
y >= 200 && y <= (200 + button.height)) {
alert("Thanks for clicking!");
}
}
You might want to convert those semi-absolute bounds to something more dynamic by for example using an image with a custom object where you store its x and y position and so forth. But you should get the idea.
Update:
A modified fiddle here
I have a webpage with an HTML5 canvas which I'm using to display a number of images as well as four 'description boxes' on the canvas.
The intention is that users will be able to drag and drop the images to their matching description boxes, however, I'm having a bit of trouble getting the dragging and dropping working.
The function I've written to add the drag and drop functionality is based on the tutorial I found at this page: http://simonsarris.com/blog/510-making-html5-canvas-useful
Obviously, I altered the code slightly, as I don't want to do everything suggested in the tutorial, and because I'm drawing images (not shapes) to the canvas. However, when viewing my page in the browser although all of the images are displayed on the canvas, the drag and drop functionality has not been added along with the new JavaScript file I've written based on that tutorial.
I'm not getting any errors in the Firebug console, and the page is displaying exactly as it was before I added the new JS function.
Can anyone spot what I'm missing?
My HTML is:
<!DOCTYPE html>
<html>
<head>
<script src = "kinetic.js" type = "text/javascript"></script>
<title>Home</title>
<script src = "drawLevelOneElements.js" type = "text/javascript"></script>
<script src = "layers&analytics.js" type = "text/javascript"></script>
<script src = "startGameDrawGameElementsDrawStartButton.js" type = "text/javascript"></script>
<script src = "interaction.js" type = "text/javascript"></script>
<script src = "dragAndDrop.js" type = "text/javascript"></script>
</head>
<body onLoad="startGame()">
<section hidden>
<img id="StartButton" src="StartButton.png" alt="Start Button" width="179" height="180" href="javascript:drawLevelOneElements();"/>
</section>
<h1>Home</h1>
<p>The purpose of this website is to teach users the basic principles of running a business by playing the game below. <br /><br /></p>
<canvas id="gameCanvas" width="1000" height="500" style="border:1px solid">
Your browser does not support the canvas element.
</canvas>
<br /><br />
<p>Use this paragraph to enter text that provides the user with instructions for how to play the game. <br />
Update the instructions so that they're appropriate to whatever level the user is currently playing.</p>
<script src = "layers&analytics.js" type = "text/javascript"></script>
<script src = "startGameDrawGameElementsDrawStartButton.js" type = "text/javascript"></script>
<script src = "variables&preloadingImages.js" type = "text/javascript"></script>
<script src = "drawLevelOneElements.js" type = "text/javascript"></script>
<script src = "interaction.js" type = "text/javascript"></script>-->
<script src = "variables&preloadingImages.js" type = "text/javascript"></script>
</body>
All of the script tags at the bottom of the page (except the last one) are actually commented out in my file, I just had to remove the comment to get it to display in a code block on here.
The javaScript I've added for the drag and drop functionality is:
function canvasState(myGameCanvas){
var bounding_box = myGameCanvas.getBoundingClientRect();
var mouseX = (mouse_event.clientX-bounding_box.left) * (myGameCanvas.width/bouding_box.width);
var mouseY = (mouse_event.clientY-bounding_box.top) * (myGameCanvas.height/bounding_box.height);
var pixels = context.getImageData(mouseX, mouseY, 1, 1);
this.valid = false; /*When set to true, the canvas will redraw everything */
this.allImagesArray; /*This is the array holding all of the images to be drawn */
this.dragging = false; /*Keep track of when the current selected object is being dragged */
this.selection = null;
this.dragOffX = 0; /*See mousedown and mousemove events for explanation */
this.dragOffY = 0;
this.interval = 30; /*This variable will be used to determine how often the draw method is called. */
/*Save a reference to the canvasState so that I'm still using this particular canvasState. */
var myState = this;
/*This stops double clicking on the canvas selecting text on the canvas */
myGameCanvas.addEventListener('selectstart', function(e) {e.preventDefault(); return false; }, false);
/*Up, down and move are for dragging */
myGameCanvas.addEventListener('mousedown', function(e){
var mouse = myState.getMouse(e);
var mX = mouse.x;
var mY = mouse.y;
var allImages = myState.allImagesArray;
var NoOfImages = allImages.length;
for (var i = 1-1; i >= 0; i--){
if(allImages[i].contains(mX, mY)){
var mySelection = allImages[i];
/*Keep track of where in the object was clicked, so that it can be
moved smoothly (see mousemove) */
myState.dragOffX = mX - mySelection.x;
myState.dragOffY = mY - mySelection.y;
myState.dragging = true;
myState.selection = mySelection;
myState.valid = false;
return;
}
}
/*If the code hasn't returned, it means that nothing has been selected.
If there was an object selected, then deselect it. */
if (myState.selection){
myState.selection = null;
myState.valid = false; /*Need to clear the old selection border */
}
}, true);
/*This event checks to see if the dragging flag has been set to true. If it has, it gets the
current mouse position and moves the selected object to that position, remembering the offset
where it was selected. If the dragging flag is false, the event does nothing. */
myGameCanvas.addEventListener('mousemove', function(e){
if(myState.dragging){
var mouse = myState.getMouse(e);
/*I don't want to drag the object by its top left corner, I want to drag from where the
object was clicked. That's why I saved the offset and use it here. */
myState.selection.x = mouse.x - myState.dragOffX;
myState.selection.y = mouse.y - myState.dragOffY;
myState.valid = false; /*Something's dragging, so I must redraw */
}
}, true);
/*All the mouseup event has to do is update the canvas state so that it is no longer dragging.
So, once the mouse button is lifted, the mousemove event should be back to doing nothing. */
myGameCanvas.addEventListener('mouseup', function(e){
myState.dragging = false;
}, true);
setInterval(function(){ myState.draw(); }, myState.interval);
canvasState.prototype.draw = function(){
/*If the state is invalid,redraw and validate. */
if (!this.valid){
var context = this.context;
var images = this.images;
this.clear();
/*Redraw the game elements here */
drawLevelOneElements();
}
}
}
Code for dragAndDrop.js:
function canvasState(myGameCanvas){
var bounding_box = myGameCanvas.getBoundingClientRect();
var mouseX = (mouse_event.clientX-bounding_box.left) * (myGameCanvas.width/bouding_box.width);
var mouseY = (mouse_event.clientY-bounding_box.top) * (myGameCanvas.height/bounding_box.height);
var pixels = context.getImageData(mouseX, mouseY, 1, 1);
this.valid = false; /*When set to true, the canvas will redraw everything */
this.allImagesArray; /*This is the array holding all of the images to be drawn */
this.dragging = false; /*Keep track of when the current selected object is being dragged */
this.selection = null;
this.dragOffX = 0; /*See mousedown and mousemove events for explanation */
this.dragOffY = 0;
this.interval = 30; /*This variable will be used to determine how often the draw method is called. */
/*Save a reference to the canvasState so that I'm still using this particular canvasState. */
var myState = this;
/*This stops double clicking on the canvas selecting text on the canvas */
myGameCanvas.addEventListener('selectstart', function(e) {e.preventDefault(); return false; }, false);
console.log("Event Listener 'selectstart' added to canvas.");
/*Up, down and move are for dragging */
myGameCanvas.addEventListener('mousedown', function(e){
console.log("Event Listener 'mousedown' added to canvas");
var mouse = myState.getMouse(e);
var mX = mouse.x;
var mY = mouse.y;
var allImages = myState.allImagesArray;
var NoOfImages = allImages.length;
for (var i = 1-1; i >= 0; i--){
if(allImages[i].contains(mX, mY)){
var mySelection = allImages[i];
/*Keep track of where in the object was clicked, so that it can be
moved smoothly (see mousemove) */
myState.dragOffX = mX - mySelection.x;
myState.dragOffY = mY - mySelection.y;
myState.dragging = true;
myState.selection = mySelection;
myState.valid = false;
return;
}
}
/*If the code hasn't returned, it means that nothing has been selected.
If there was an object selected, then deselect it. */
if (myState.selection){
myState.selection = null;
myState.valid = false; /*Need to clear the old selection border */
}
}, true);
/*This event checks to see if the dragging flag has been set to true. If it has, it gets the
current mouse position and moves the selected object to that position, remembering the offset
where it was selected. If the dragging flag is false, the event does nothing. */
myGameCanvas.addEventListener('mousemove', function(e){
console.log("Event listener 'mousemove' added to canvas.");
if(myState.dragging){
var mouse = myState.getMouse(e);
/*I don't want to drag the object by its top left corner, I want to drag from where the
object was clicked. That's why I saved the offset and use it here. */
myState.selection.x = mouse.x - myState.dragOffX;
myState.selection.y = mouse.y - myState.dragOffY;
myState.valid = false; /*Something's dragging, so I must redraw */
}
}, true);
/*All the mouseup event has to do is update the canvas state so that it is no longer dragging.
So, once the mouse button is lifted, the mousemove event should be back to doing nothing. */
myGameCanvas.addEventListener('mouseup', function(e){
console.log("Event listener 'mouseup' added to canvas.");
myState.dragging = false;
}, true);
setInterval(function(){ myState.draw(); }, myState.interval);
canvasState.prototype.draw = function(){
/*If the state is invalid,redraw and validate. */
if (!this.valid){
var context = this.context;
var images = this.images;
this.clear();
/*Redraw the game elements here */
drawLevelOneElements();
}
}
}
Code for drawLevelOneElements.js: (this now includes the call to canvasState(); )
function drawLevelOneElements(){
/*First, clear the canvas */
context.clearRect(0, 0, myGameCanvas.width, myGameCanvas.height);
/*This line clears all of the elements that were previously drawn on the canvas. */
/*Then redraw the game elements */
drawGameElements();
/*Call the function to enable drag and drop */
canvasState(document.getElementById('gameCanvas'));
/*Create the four description areas, and place them near the bottom of the canvas */
/*Create boxes with rounded corners for the description areas */
CanvasRenderingContext2D.prototype.drawDescriptionArea = function(x, y, width, height, radius, stroke){
if(typeof stroke == "undefined" ){
stroke = true;
}
if(typeof radius === "undefined"){
radius = 5;
}
this.beginPath();
this.moveTo(x + radius, y);
this.lineTo(x + width - radius, y);
this.quadraticCurveTo(x + width, y, x + width, y + radius);
this.lineTo(x + width, y + height - radius);
this.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
this.lineTo(x + radius, y + height);
this.quadraticCurveTo(x, y + height, x, y + height - radius);
this.lineTo(x, y + radius);
this.quadraticCurveTo(x, y, x + radius, y);
this.closePath();
if(stroke){
context.stroke();
}
}
context.drawDescriptionArea(70, 400, 120, 70);
context.font = '25pt Calibri';
context.strokeText('Asset', 90, 440);
context.drawDescriptionArea(300, 400, 120, 70);
context.strokeText('Liability', 310, 440);
context.drawDescriptionArea(540, 400, 120, 70);
context.strokeText('Income', 550, 440);
context.drawDescriptionArea(750, 400, 180, 70);
context.strokeText('Expenditure', 760, 440);
/*Now draw the images to the canvas */
/*First, create variables for the x & y coordinates of the image that will be drawn.
the x & y coordinates should hold random numbers, so that the images will be
drawn in random locations on the canvas.*/
var imageX = Math.floor(Math.random()*100);
var imageY = Math.floor(Math.random()*100);
/*Create a 'table' of positions that the images will be drawn to */
var imagePositionsX = [20, 80, 140, 200, 260, 320, 380, 440, 500, 560];
var imagePositionsY = [20, 60, 100, 140, 180, 220, 260, 300, 340, 380];
/*Draw all images from assetsImageArray */
/*Use a while loop to loop through the array, get each item and draw it. */
var arrayIteration = 0;
console.log('All Images Array length: ' + allImagesArray.length); /*Display the length of the array in the console, to check it's holding the correct number of images. */
while(arrayIteration < allImagesArray.length){
var randomPositionX = Math.floor(Math.random()*10);
var randomPositionY = Math.floor(Math.random()*10);
context.drawImage(allImagesArray[arrayIteration], imageX, imageY, 50, 50);
console.log(arrayIteration); /*Display the current array position that's being drawn */
arrayIteration = arrayIteration+1;
/*Now try changing the values of imageX & imageY so that the next image is drawn to a
different location*/
imageX = imagePositionsX[randomPositionX]; /* imageX+(Math.floor(Math.random()*100)); */
imageY = imagePositionsY[randomPositionY]; /* imageY+(Math.floor(Math.random()*100)); */
}
}
In conclusion to the comments, I can answer you this: Somewhere within your code, you have to call the canvasState() function, it's not enough just to define it. Where you must call it largely depends on when you need it's functionality. By example, if you want to set up the drag and drop functionality when the page loads, you have an event handler for the body's load event:
<body onLoad="startGame()">
Somewhere in the startGame() function's code, you would call canvasState(). If you you want it when StartButton is pressed, you should call it from within the drawLevelOneElements() function. Since you were following a tutorial, the order in which things happen might matter, so there might be a particular place where you need to call your function.
One more advice. Because you seem to be learning, start with the basics and work your way up with a deep understanding of what you learned up to that point, don't just follow random tutorials.
I have an HTML5 canvas on a web page, with a JavaScript function that draws an image on the canvas. I'm trying to add a mouse event to the image, so that when it is clicked, another JavaScript function that is called, which will update what is displayed on the canvas.
When viewing the page in Firefox, nothing happens when I click the image that's displayed on the canvas. I'm using Firebug to try and see what's wrong, and it's given me the following message:
mouse_event is not defined
drawStartButton()index.html (line 107)
startGame()index.html (line 64)
(?)()index.html (line 1)
event = load
[Break On This Error]
...useX = (mouse_event.clientX-boundingBox.left) * (myGameCanvas.width/boundingBox....
index.html (line 107)
The function I've used to draw the start button on the canvas, and mouse event I've added are below:
function drawStartButton(){
image.onload = function(){
context.drawImage(image, 260.5, 60);
};
image.src = "StartButton.png";
/** Now I need to add an event listener to the area of the canvas on
on which the button image is displayed, in order to 'listen' for
a click on the button */
var boundingBox = myGameCanvas.getBoundingClientRect();
var mouseX = (mouse_event.clientX-boundingBox.left) * (myGameCanvas.width/boundingBox.width);
var mouseY = (mouse_event.clientY-boundingBox.top) * (myGameCanvas.height/boundingBox.height);
var pixels = context.getImageData(mouseX, mouseY, 1, 1); }
Basically, all I want to do, is that when the user clicks the button, the function below will be called, and will update the contents of the canvas:
function drawLevelOneElements(){
var context = canvas.getContext("2d");
/* Draw the images for numbers 1-10.*/
var image1 = new Image();
/* Test that this code is being executed */
context.moveTo(300, 300);
context.font = "11pt Calibri";
context.strokeStyle = "black";
context.strokeText("Testing",300, 300);
/* End of test */
image1.onLoad = function(){
context.drawImage(image1, 50, 50);
};
image1.src="1.png";
}
It seems I was able to solve this by putting the variables mouseX, mouseY and pixels in a function and setting the boundingBox.onmousemove property equal to this function:
boundingBox.onmousemove = function(e){
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
var pixels = context.getImageData(mouseX, mouseY, 1, 1);
}