I'm trying to drag the bucket image (left and right only) with touch.
I'm new to mobile developing so I'm not that acquainted with touch events.
bucket = document.getElementById("bucket");
window.addEventListener('load', function () {
var startx = 0;
var dist = 0;
bucket.addEventListener('touchstart', function (e) {
var touchobj = e.changedTouches[0]; // reference first touch point (ie: first finger)
startx = parseInt(touchobj.clientX); // get x position of touch point relative to left edge of browser
e.preventDefault();
}, false)
bucket.addEventListener('touchstart', function (e) {
var touchobj = e.changedTouches[0]; // reference first touch point for this event
var dist = parseInt(touchobj.clientX) - startx;
bucket.style.left = bucket.offsetLeft + dist;
e.preventDefault();
}, false)
}, false)
Thank you all the helpers.
Related
I have an angular project wherein the three representation is using threeJs. I wish to add a context menu on right-click to the scene. This is what I have so far. I am also receiving an error called 'menu does not exist'.
window.addEventListener('mousedown', (e: MouseEvent) => { this.rightClickContextMenu(e); }, false);
if (document.addEventListener) {
document.addEventListener('contextmenu', function (e) {
e.preventDefault();
}, false);
} else {
(<any>document).attachEvent('oncontextmenu', function () {
window.event.returnValue = false;
});
}
public rightClickContextMenu(e: MouseEvent): void {
var rightclick;
if (!event) var event = window.event;
if ((<any>event).which) rightclick = ((<any>event).which == 3);
else if ((<any>event).button) rightclick = ((<any>event).button == 2);
if (!rightclick) return;
const x = e.clientX - this.rect.left;
const y = e.clientY - this.rect.top;
var intersect;
let scenePointer = new th.Vector2();
scenePointer.x = (x / this.canvas.clientWidth) * 2 - 1;
scenePointer.y = (y / this.canvas.clientHeight) * - 2 + 1;
// Determine the component in-focus using raycasting
this.raycaster.setFromCamera(scenePointer, this.camera);
var intersects = this.raycaster.intersectObjects(this.scene.children);
if (intersects.length) {
intersect = intersects[0].object;
menu.style.left = x + "px";
menu.style.top = y + "px";
menu.style.display = "";
}
else {
intersect = undefined;
}
}
So far, on left-click, the color of the mesh changes but nothing happens on right click. I was wondering how do I add on a context menu to the same on right click. Modifications to my code to highlight the correct one would be much appreciated from you guys. I apologise, I am very new to threejs in case this question sounds trivial.
Stop event propagation on the control where u want this feature and then capture the event and diplay
I am trying to change the length of two bars (div) by mouse dragging (extending one example in eloquetjavascript book chapter 14, which involves changing the length of one bar by dragging the mouse.) The intended behavior is clicking on any bar, moving the mouse when holding the left mouse key would change the length of that bar.
Here is my implementation (also available on JSfiddle)
<script>
var lastX; // Tracks the last observed mouse X position
var rect1 = document.getElementById("bar1");
var rect2 = document.getElementById("bar2");
rect1.addEventListener("mousedown", function(){watchmousedown(rect1)});
rect2.addEventListener("mousedown", function(){watchmousedown(rect2)});
function watchmousedown(rec) {
if (event.which == 1) {
lastX = event.pageX;
addEventListener("mousemove",function(){moved(rec)});
event.preventDefault(); // Prevent selection
} else {
removeEventListener("mousedown", watchmousedown)}
}
function moved(rec) {
if (event.which != 1) {
removeEventListener("mousemove", moved);
} else {
var dist = event.pageX - lastX;
var newWidth = Math.max(10, rec.offsetWidth + dist);
rec.style.width = newWidth + "px";
lastX = event.pageX;
}
}
</script>
The problem is I can only change the length of the bar where the first mouse click event happened. I assume I didn't handle the mousedown event correctly (probably need a reset some how).
I am new to javascript, help on programming style is also appreciated.
Thanks!
Add rec. to addEventListener("mousemove", function () { so that the event listener is bound to the rec you clicked on instead of to the window.
function watchmousedown(rec) {
if (event.which == 1) {
lastX = event.pageX;
rec.addEventListener("mousemove", function () {
moved(rec)
});
event.preventDefault(); // Prevent selection
} else {
rec.removeEventListener("mousedown", watchmousedown)
}
}
Edit: I there are some event handlers not being cleaned up properly. I don't know if this would be my final code, but this is closer to how I would do it:
var lastX; // Tracks the last observed mouse X position
var rect1 = document.getElementById("bar1");
var rect2 = document.getElementById("bar2");
var moveRect1 = function () {
console.log(arguments);
moved(rect1)
};
var moveRect2 = function() {
console.log(arguments);
moved(rect2);
}
var watchRect1 = function () {
console.log(arguments);
watchmousedown(moveRect1)
};
var watchRect2 = function () {
console.log(arguments);
watchmousedown(moveRect2)
};
rect1.addEventListener("mousedown", watchRect1);
rect2.addEventListener("mousedown", watchRect2);
window.addEventListener("mouseup", function() {
removeEventListener("mousemove", moveRect1);
removeEventListener("mousemove", moveRect2);
});
function watchmousedown(moverec) {
if (event.which == 1) {
lastX = event.pageX;
addEventListener("mousemove", moverec);
event.preventDefault(); // Prevent selection
}
}
function moved(rec) {
if (event.which == 1) {
var dist = event.pageX - lastX;
var newWidth = Math.max(10, rec.offsetWidth + dist);
rec.style.width = newWidth + "px";
lastX = event.pageX;
}
}
Edit: removed a line that didn't do anything
I am drawing a line with Raphael. I have a mousedown event where I store the starting position. While the mouse is down, if the user moves it, I have a mousemove event where I keep drawing the line as the mouse moves.
Now when the mouse button is released, the line should stop. This does not happen and line keeps going on if the mouse moves even though button is released. This line must stop on mouseup. If the user does mousedown again, it should begin a new line.
I have tried many combinations with the unmouse* events, but I am missing something here.
JSFiddle at: http://jsfiddle.net/zaphod013/P33FA/5/
(This is my first date with JS/Raphael. So if you think I am totally off track here, please tell me so)
var g_masterPaper;
var g_startX;
var g_startY;
var g_line;
function initDrawing() {
g_masterPaper = Raphael(10,10,700,500);
var masterBackground = g_masterPaper.rect(10,10,600,400);
masterBackground.attr("fill", "#eee");
var drawit = function(event) {
x = event.pageX - 10;
y = event.pageY - 10;
var linepath = ("M"+g_startX+" "+g_startY+" L"+x+" "+y);
g_line.attr("path", linepath);
};
var startit = function (event) {
g_startX = event.pageX - 10;
g_startY = event.pageY - 10;
g_line = g_masterPaper.path("M"+g_startX+" "+g_startY+" L"+g_startX+" "+g_startY);
masterBackground.mousemove(drawit);
};
masterBackground.mousedown(startit);
masterBackground.mouseup(function (event) {
this.unmousedown(startit);
this.unmousemove(drawit);
});
return g_masterPaper;
}
window.onload = function () {
var paper=initDrawing();
paper.text(15,475,'Use your mouse to draw.').attr({fill:'#ff0000', 'font-size':24, 'stroke-width':1,'text-anchor':'start' });
}
I think you're on track and mostly looks fine, I would possibly just simplify your handlers, and not keep removing/adding them, it keeps handlers hard to track and debug. So I would just have one handler for down/up/move...
Edit:
jsfiddle here or here which gets around other elements capturing the mouseup event and stopping it working properly.
var drawit = function(event) {
event.preventDefault();
x = event.pageX - 10;
y = event.pageY - 10;
var linepath = ("M"+g_startX+" "+g_startY+" L"+x+" "+y);
if( g_line ) { g_line.attr("path", linepath) };
};
var startit = function (event) {
event.preventDefault();
g_startX = event.pageX - 10;
g_startY = event.pageY - 10;
g_line = g_masterPaper.path("M"+g_startX+" "+g_startY+" L"+g_startX+" "+g_startY);
};
var finish = function ( event ) {
g_line = '';
}
The app works wonderfully on desktop, but not on mobile. When you click DONE, the app will open a new window and show you the output of the drawings, but on iOS, all the coordinates are 0,0... so it looks like the points simply are not being saved in mobile devices.
The problem is most likely either at lines 109 to 111 or lines 171 to 184 of the JS which I am including below:
The section that handles the touch events:
$(trackingLayer).on('mousedown touchstart', function(e) {
e.originalEvent.preventDefault();
isTracking = true;
curMouseX = curMouseY = -1;
if (curTool === "draw") {
var o = {};
o.painLevel = curPainLevel;
o.path = [];
DrawPoints.push(o);
}
}).on('mousemove touchmove', function(e) {
e.originalEvent.preventDefault();
trackMoveMouse($(this), e);
}).on('mouseup mouseleave touchend', function(e) {
e.originalEvent.preventDefault();
isTracking = false;
});
And the area that records the points:
var canvasOffset = ID.offset(); //or $(this).offset(); if you really just want the current element's offset
curMouseX = e.pageX - canvasOffset.left;
curMouseY = e.pageY - canvasOffset.top;
if (curMouseX !== -1 && prevMouseX !== -1) {
var o = {};
o.x = curMouseX / curZoom;
o.y = curMouseY / curZoom;
DrawPoints[DrawPoints.length - 1].path.push(o);
//log("Shapes Recorded: " + DrawPoints.length);
drawImage();
}
I have set up a jsfiddle for this: http://jsfiddle.net/nbernhard/dSED8/
Any help would be appreciated.
Thanks!
How to make a element draggable without using jQuery UI?
I have this code:
<script type="text/javascript">
function show_coords(event)
{
var x=event.clientX;
var y=event.clientY;
var drag=document.getElementById('drag');
drag.style.left=x;
drag.style.top=y
}
</script>
<body style="height:100%;width:100%" onmousemove="show_coords(event)">
<p id="drag" style="position:absolute">drag me</p>
</body>
The problem is that I want to drag while the user the pressing the mouse button. I tried onmousedown but results were negative.
It will be quite easy as you get the concept.
function enableDragging(ele) {
var dragging = dragging || false, //Setup a bunch of variables
x, y, Ox, Oy,
enableDragging.z = enableDragging.z || 1,
current;
ele.onmousedown = function(ev) { //When mouse is down
current = ev.target;
dragging = true; //It is dragging time
x = ev.clientX; //Get mouse X and Y and store it
y = ev.clientY; // for later use.
Ox = current.offsetLeft; //Get element's position
Oy = current.offsetTop;
current.style.zIndex = ++enableDragging.z; //z-index thing
window.onmousemove = function(ev) {
if (dragging == true) { //when it is dragging
var Sx = ev.clientX - x + Ox, //Add the difference between
Sy = ev.clientY - y + Oy; // 2 mouse position to the
current.style.top = Sy + "px"; // element.
current.style.left = Sx + "px";
return false; //Don't care about this.
}
};
window.onmouseup = function(ev) {
dragging && (dragging = false); //Mouse up, dragging done!
}
};
}
enableDragging(document.getElementById("drag")); //draggable now!
var ele = document.getElementsByTagName("div");
for(var i = 0; i < ele.length; i++){ //Every div's is draggable
enableDragging(ele[i]); // (only when its "position"
} // is set to "absolute" or
// "relative")
http://jsfiddle.net/DerekL/NWU9G/
The reason why your code is not working is because the <div> will always follow where your cursor goes, and you are not actually dragging it. The top left corner will always follow your cursor, and this is not we wanted.
UPDATE
Now if you only want a grabber or something similar, just change this part of the script:
ele.onmousedown = function(ev) {
current = ev.target;
to
var grabber = document.createElement("div");
grabber.setAttribute("class", "grabber");
ele.appendChild(grabber);
grabber.onmousedown = function(ev) {
current = ev.target.parentNode;
Now you can only click on the grabber to start the dragging process.
http://jsfiddle.net/DerekL/NWU9G/7/