I have an issue with a game in JavaScript.
My game lives inside a canvas, and I make large use of function almost like:
document.onmousemove = function(event) {
var mouseX = event.clientX - canvas.getBoundingClientRect().left;
var mouseY = event.clientY - canvas.getBoundingClientRect().top;
//mouse position is relative to player position
mouseX -= CANVAS_WIDTH/2;
mouseY -= CANVAS_HEIGHT/2;
player.aimAngle = Math.atan2(mouseY, mouseX) / Math.PI * 180;
}
document.onclick = function(event) {
if(player.canAttack && player.distance >= 80) { //not for sword attack
performAttack(player);
player.canAttack = false;
}
if(player.distance < 80)
performAttack(player);
event.preventDefault();
}
But before dynamically creating the canvas I have a login form. When I click with mouse to select those form I got in console the error Uncaught TypeError: Cannot read property 'canAttack' of undefined . That's because I have not called yet the Player() constructor, so canAttack doesn't exists and for the onMouseMove canvas doesn't exist yet.
How do I "disable" or unbind the document.onclick and document.onmousemove?
If they were done with addEventListener I would disable them with removeEventListener. How could I do with document.onclick instead?
Thanks
Try following when have to remove listener
function noop(){}
document.onclick = noop // when have to remove click binding
Related
I am currently figuring out how to draw lines on page load without even having to actually moving the mouse to draw
Here is my code which draws line only when mouse is moved.
https://codepen.io/arvi/pen/RgYZqB
I added a "load" event listener and tied it to documentMouseMoveHandler but it seems not the solution for this scenario.
window.addEventListener('load', documentMouseMoveHandler, false);
Is it possible?
Ok do something like this until you get a mouse event , take random moue point in a interval if mouse event came, then remove it;
var intervalId;
function documentMouseMoveHandler(event) {
if (!event) {
intervalId = setInterval(function () {
mouseX = Math.floor(Math.random() * (window.innerWidth - 1));
mouseY = Math.floor(Math.random() * (window.innerHeight + 1));
}, 3000);
return;
}
if (event && intervalId) {
clearInterval(intervalId);
}
mouseX = event.clientX - (window.innerWidth - SCREEN_WIDTH) * .5;
mouseY = event.clientY - (window.innerHeight - SCREEN_HEIGHT) * .5;
}`
I have a scroll function for my canvas which detects distance moved by my mouse and offsets all my images in the canvas.
The problem is i barely move the mouse and the offset number exponentially increases and im not sure why... this is my function that deals with offset calculation:
canvas.addEventListener('mousedown', scrol_cnv, false);
function scroll_cnv(e) {
if (e.button == 2) {//right click only
var x = e.pageX; // get click X
var y = e.pageY; //get click Y
function clear() {
this.removeEventListener('mousemove', updt, false);
}
function updt(evt) {
var difx = evt.pageX - x;
var dify = evt.pageY - y;
//this is where offset is becoming incorrect
//offsets is globally defined `window.offsets = {}`
offsets.cur_offsetx -= difx;
offsets.cur_offsety -= dify;
}
this.addEventListener('mousemove', updt, false);
this.addEventListener('mouseup', clear, false);
}
}
Am i subtracting the offset incorrectly ?
You want the offset to be based on the offset at the time of mousedown. Events that happen frequently shouldn't be changing things without a basis.
You probably also want to remove your mouseup listener, otherwise you get an additional one every click (no functional harm, just unnecessary overhead).
canvas.addEventListener('mousedown', scrol_cnv, false);
function scroll_cnv(e) {
if (e.button == 2) {//right click only
var x = e.pageX; // get click X
var y = e.pageY; //get click Y
// store the initial offsets
var init_offsetx = offsets.cur_offsetx;
var init_offsety = offsets.cur_offsety;
function clear() {
this.removeEventListener('mousemove', updt, false);
this.removeEventListener('mouseup', clear, false);
}
function updt(evt) {
var difx = evt.pageX - x;
var dify = evt.pageY - y;
//this is where offset is becoming incorrect
//offsets is globally defined `window.offsets = {}`
offsets.cur_offsetx = init_offsetx - difx;
offsets.cur_offsety = init_offsetx - dify;
}
this.addEventListener('mousemove', updt, false);
this.addEventListener('mouseup', clear, false);
}
}
How do I get the x and y pixel value of the mouse click on the image after a canvas translate & scale? What's the needed calculation from the event x and y?
I am using panning & zooming code from this answer:
var zoom = function(clicks) {
var pt = ctx.transformedPoint(lastX,lastY);
ctx.translate(pt.x,pt.y);
var factor = Math.pow(scaleFactor,clicks);
ctx.scale(factor,factor);
ctx.translate(-pt.x,-pt.y);
redraw();
}
var handleScroll = function(evt) {
var delta = evt.wheelDelta ? evt.wheelDelta/40 : evt.detail ? -evt.detail : 0;
if (delta) zoom(delta);
return evt.preventDefault() && false;
};
Example website
If you're just trying to get the mouse X and Y position after a click, then you should attach a function to the mousedown event in Javascript. This is called event binding. In short, while in the DOM you can bind events to elements within the page. Here's an example I made which shows an event bound to the #box element.
document.getElementById("box").onmousedown = function() {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
alert("Mouse x: " + posx + "\nMouse y: " + posy);
};
This code finds an element with an ID of box and tells the code in the function to run every time after the mouse is depressed. In this example we also fall back for older system to ensure that it works cross-platform and cross-browser. If you wanted to bind this event to the whole webpage rather than just an element then you can replace document.getElementById("box") with window.
This however does not compute the relative position within a DOM element. There's multiple ways to do that which I won't go into detail on here, but I'll include a few methods below. Best of luck!
RESOURCES
More on handling mouseclicks in Javascript
Relative position of mouse clicks within an element
jQuery solution for the previous link
I'm new to JS. I'm not using jQuery, and I have a question. I've created a variable number of canvases on a page, all have an eventlistener like so:
for (i=0; i<numberOfCanvases; i++){
var canv = document.createElement("canvas");
canv.addEventListener('click', clickReporter, false);
document.body.appendChild(canv); }
Given the listener function clickReporter:
function clickReporter(e){...}
I am trying to use this function to tell me the mouse position of the click event relative to the canvas:
function getMousePos(canvas, evt){
// get canvas position
var obj = canvas;
var top = 0;
var left = 0;
while (obj && obj.tagName != 'BODY') {
top += obj.offsetTop;
left += obj.offsetLeft;
obj = obj.offsetParent;
}
// return relative mouse position
var mouseX = evt.clientX - left + window.pageXOffset;
var mouseY = evt.clientY - top + window.pageYOffset;
return {
x: mouseX,
y: mouseY
};
}
which i found from this tutorial: http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
The problem is, it assumes there is only one canvas, and I do have a list of canvases right now that are placed on a webpage, but I was wondering, given just the clickReporter() function, is there an easy way to determine which canvas was selected? a function like evt.getCanvas() or evt.getParentCanvas()?
I'm asking because when an event occurs (a mouse click on 1 of many canvases, I want to create actions at that location for ONLY that canvas)
function clickReporter(e){
console.log( this ); // in a eventListener , this point to the element fire the event
console.log( e.target ); // in fireFox and webkit, e.target point to the element fire the event
}
I would think evt.target (event.target) would work.
I came across the following very simple code for dragging a square around using javascript. It is drawn on the html5 canvas. Despite being very simple it has certainly exposed some gaps in my pretty flakey javascript knowledge. I am generally ok with the idea of drag and drop (i.e. start drag on mouse click, stop drag on mouse release) but my questions are as follows:
(1) I cannot see where the variable e is defined, yet it is used all the time.
(2) In the init funciton at the bottom, an onmousedown listener seems to be attached to the canvas. However it equals the function myDown, but myDown doesn't have parentheses after it. So the myDown function is not actually going to be exectuted. So what is it doing instead?
Thanks in advance. I have tried to research this myself but haven't had any success yet.
Matt
<html>
<head>
</head>
<body>
<section>
<div>
<canvas id="canvas" width="400" height="300">
</canvas>
</div>
<script type="text/javascript">
var canvas;
var ctx;
var x = 75;
var y = 50;
var dx = 5;
var dy = 3;
var WIDTH = 400;
var HEIGHT = 300;
var dragok = false;
function rect(x,y,w,h) {
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
ctx.fill();
}
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
return setInterval(draw, 10);
}
function draw() {
clear();
ctx.fillStyle = "#FAF7F8";
rect(0,0,WIDTH,HEIGHT);
ctx.fillStyle = "#444444";
rect(x - 15, y - 15, 30, 30);
}
function myMove(e){
if (dragok){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
}
}
function myDown(e){
if (e.pageX < x + 15 + canvas.offsetLeft && e.pageX > x - 15 +
canvas.offsetLeft && e.pageY < y + 15 + canvas.offsetTop &&
e.pageY > y -15 + canvas.offsetTop){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
dragok = true;
canvas.onmousemove = myMove;
}
}
function myUp(){
dragok = false;
canvas.onmousemove = null;
}
init();
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
</script>
</section>
</body>
</html>
You should really learn basic of the js language first.
1) e is param that is passed to functions. Callbacks receives one param: event object. So e stands for event.
2) myDown is not suppose to be executed when it is attached to onmousedown listener.
it is function object that is called everytime user clicks on canvas. It is callback.
e is the event variable which you get from onmousedown and onmouseup events. since you are attaching the mouse events with the canvas, so here e contains some information about mouse positions.
myDown is directly assigned to onmousedown which means that all the code of myDown function shall be assigned to onmousedown. If you add parenthesis after myDown then it would mean that you are assigning the response of myDown function to onmousedown event.
the other way of writing those events is like following
canvas.onmousedown = function(e)
{
myDown(e);
};
canvas.onmouseup = function(e)
{
myUp(e);
};
(1) I cannot see where the variable e is defined, yet it is used all the time.
You may know that a function is a set of instructions with input and output. They get their input through parameters and their output is what they return.
Now, the parameters they get are available in their body. This is why the e they get can be used inside.
(2) In the init funciton at the bottom, an onmousedown listener seems to be attached to the canvas. However it equals the function myDown, but myDown doesn't have parentheses after it. So the myDown function is not actually going to be exectuted. So what is it doing instead?
Function is a special object in javascript, with an extra internal property [[Call]]. When you type the function name alone, you're talking about the function itself. And as it is a first-class object it can be assigned to a variable, passed as an argument, returned from other functions, etc.
When you type the function name with parenthesize after it you execute the code in the function body by the [[Call]] internal property.