Detect if mouse is leaving browser window with button pressed - javascript

I'm using Kinetic.js for some dragging in my canvas and I'm trying to detect if the mouse leaves the browser window. Only difference is that I also want it to trigger when a mouse button is pressed while moving out.
This thread pretty much solves the question but if you press the left mouse button while moving out it doesn't work: Link
For me it seems that the mouseout event is being ignored as long as the left mouse button is pressed. I've done a test here. Any ideas?

You can set an isDown flag when the mouse is pressed.
Then clear the isDown flag when the mouse is released.
And track mouseout + the isDown flag to see if user is leaving with mouse pressed
Here's the jQuery version:
var isDown=false;
$(stage.getContent()).on('mousedown',function(e){ isDown=true; });
$(stage.getContent()).on('mouseup',function(e){ isDown=false; });
$(stage.getContent()).on('mouseout',function(e){
console.log(isDown);
isDown=false;
});
Here's code and a Fiddle: http://jsfiddle.net/m1erickson/ZjKGS/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.0.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:400px;
height:400px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
var isDown = false;
$(stage.getContent()).on('mousedown', function (e) {
isDown = true;
});
$(stage.getContent()).on('mouseup', function (e) {
isDown = true;
});
$(stage.getContent()).on('mouseout', function (e) {
if(isDown){
$("#indicator").text("Moved out and mouse was pressed");
}else{
$("#indicator").text("Moved out and mouse was not pressed");
}
isDown = false;
});
layer.draw();
}); // end $(function(){});
</script>
</head>
<body>
<p>Move mouse out of kinetic stage</p>
<p>Indicator will tell if mouse was also pressed</p>
<p id="indicator">Indicator</p>
<div id="container"></div>
</body>
</html>

Related

How to cancel a drag (on dragenter)

I'm on classic javascript and i want to cancel a drag on enter in a specific div.
in HTML :
<!-- Element i want to drag -->
<div id="draggableElement" draggable="true"></div>
<!-- Element which cancels the drag on enter -->
<div id="specificDiv"></div>
in JS :
document.addEventListener("dragenter", event=> {
if (event.target.id == "specificDiv") {
// Cancel the drag
}
}, false);
I already search on the web but i didn't find a solution, however i found some js libraries but it's too much for the only thing i want to do.
Thanks by advance.
EDIT :
More precisly i want, at least, undisplay the draged image by entering in my specific div to see this one.
So i've already tried to hide the draged image but it doesn't work on dragenter (only in dragstart).
in JS :
let dragged;
document.addEventListener("dragstart", event=> {
dragged = event;
}, false);
document.addEventListener("dragenter", event=> {
if (event.target.id == "specificDiv") {
// Hide the dragged image or cancel the drag
event.dataTransfer.setDragImage(new Image(), 0, 0); // Doesn't work
dragged.dataTransfer.setDragImage(new Image(), 0, 0); // Doesn't work too
}
}, false);
Okay so you want to hide the dragged element when enters over renderCanvas but WITHOUT releasing mouse button am I right?
If so, you have to know that is not possible to modifying drag-ghost-image without releasing mouse button. In that case you can simulate a custom Drag&Drop and hide the dragged element when its position is in range with the other element:
let specificDiv = document.getElementById('specificDiv');
let renderCanvas = document.getElementById('renderCanvas');
//Catches target position
rect = renderCanvas.getBoundingClientRect();
rectX = rect.left;
rectY = rect.top;
//Release dragged element
let released;
document.addEventListener('mouseup', ()=>{
released = true;
})
//Drag element
specificDiv.addEventListener('mousedown', (ev) => {
released = false;
specificDiv.addEventListener('mousemove', (e)=>{
if(!released) {
//Collects actual mouse position while dragging
x = e.clientX
y = e.clientY
//Moves dragged element
specificDiv.style.left = (x-80) + 'px';
specificDiv.style.top = (y-80) + 'px';
//Hides dragged element when is over the other
if(y > rectY) {
specificDiv.style.opacity="0"
}
}
})
})
#specificDiv {
position: relative;
background-color: red;
height: 10em;
width: 10em;
}
#renderCanvas {
background-color: blue;
height: 20em;
width: 20em;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="css/styles.css" rel="stylesheet">
</head>
<body>
<!-- Div element you want to drag-->
<div id="specificDiv">DRAGGED ELEMENT</div>
<!-- Div element who cancels the drag on enter -->
<div id="renderCanvas">TARGET ELEMENT</div>
<script src="js/main.js"></script>
</body>
</html>
You'll have to adapt rectX and rectY to your specific divs position.
The following would be a solution to allow dropping on a div and on another div don't allow dropping:
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
const target = document.querySelector("#dragtarget");
const notarget = document.querySelector("#nodragtarget");
const dragged = document.querySelector("#dragitem");
target.addEventListener("dragover", allowDrop);
target.addEventListener("drop", drop);
dragged.addEventListener("dragstart", drag)
div[draggable] {
height: 3rem;
width: 3rem;
background: yellow;
}
div#dragtarget {
height: 5rem;
width: 5rem;
border: 1px solid green;
}
div#nodragtarget {
height: 5rem;
width: 5rem;
border: 1px solid red;
}
<div id="dragitem" draggable="true"></div>
<div id="dragtarget"></div>
<div id="nodragtarget"></div>
did my answer worked for you? I am quite curious

Draw multiple Rectangles with svg.draw.js

The issue was already posted here, but I think was never addressed. I need to create a new rect each time I click "Create SVG Rect" button. Hence drawing multiple rectangles.
<!DOCTYPE html>
<html lang="en">
<head><style>#test_slide { width: 500px; height: 500px; cursor: crosshair;border: solid;}</style></head><body>
<div id="test_slide"></div>
<button id="create_svg_rect" >Create SVG Rect</button>
<!--SCRIPT FILES-->
<script src="https://code.jquery.com/jquery-3.3.1.min.js" defer="defer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.7.1/svg.min.js" type="text/javascript" defer="defer"></script>
<script src="https://svgjs.dev/svg.draw.js/demo/svg.draw.min.js" type="text/javascript" defer="defer"></script>
<script>
document.getElementById("create_svg_rect").onclick = function() {
//SVG.on(document, 'DOMContentLoaded', function() {
var drawing = new SVG('test_slide').size('100%', '100%');
var rect = drawing.rect().attr('stroke-width',1).attr('fill','none');
drawing.on('mousedown', function(e){
rect.draw(e);
}, false);
drawing.on('mouseup', function(e){
rect.draw('stop', e);
console.log(rect.svg());
return;
}, false);
//});
};
</script>
</body></html>
In your code you were creating a whole new drawing and listeners everytime you click on the button. Thats not what you want.
Instead, just create one drawing (<svg>) and attach the listeners to it.
A click on the button only has to create a new rectangle.
To be able to access the rect-var in the listeners we have to define it in the outer scope. On click, we create a new rect and save it. On mousedown we start drawing and on mouseup we finish.
Here is working snippet:
document.addEventListener('DOMContentLoaded',() => {
let rect, drawing = new SVG('test_slide').size('100%', '100%');
drawing.on('mousedown', function(e){
rect && rect.draw(e);
});
drawing.on('mouseup', function(e){
if (rect) {
rect.draw('stop', e);
console.log(rect.svg());
rect = null;
}
});
document.getElementById("create_svg_rect").addEventListener('click', function() {
rect = drawing.rect().attr('stroke-width',1).attr('fill','none');
});
})
#test_slide { width: 500px; height: 160px; cursor: crosshair;border: solid;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.7.1/svg.min.js" type="text/javascript"></script>
<script src="https://svgjs.dev/svg.draw.js/demo/svg.draw.min.js" type="text/javascript"></script>
<div id="test_slide"></div>
<button id="create_svg_rect" >Create SVG Rect</button>
Since your code didnt use any jquery I removed it from the snippet.

Does Windows Store apps or HTML5 Drag and Drop support touch device?

I'm new to html5 and windows store app. I created a project which I want my image to be able to drag. First for mouse drag it's work just fine but then i tested it in touch device it's not working. Here is the image:
This one is tested on non-touch device and it work:
This one is tested on touch device and it doesn't work:
here is my html :
<!DOCTYPE html>
<html>
<head>
<script src="script.js"></script>
<title>Drag and Drop</title>
</head>
<body>
<div id="content">
<div id="Store" style="border: solid 1px white;"></div>
<div id="right" style="border: solid 1px white;">
<img id="img1" src="/image/bugimgS1.png" />
</div>
</div>
</body>
</html>
Here is my script:
(function () {
WinJS.UI.Pages.define('DragandDrop.html',
{
ready: function ()
{
define();
}
});
function get(ID) { return document.getElementById(ID); }
function create(tag) { return document.createElement(tag); }
function define()
{
var r = get('Store');
var img1 = get('img1');
img1.addEventListener('dragstart', _dragStart, false);
r.addEventListener('dragenter', function (e) { e.preventDefault(); });
r.addEventListener('dragover', function (e) { e.preventDefault(); });
r.addEventListener('drop', _dropped, false);
function _dragStart(e) {
e.dataTransfer.setData('Text', e.target.id);
}
function _dropped(e) {
e.preventDefault();
var data = e.dataTransfer.getData('Text');
r.appendChild(document.getElementById(data));
}
}
})();
Please I really need help to make this program work both on touch and non-touch devices. Thanks in Advance.
You'll need to use an MSGesture object to be able to support drag and drop via touch events. Other events such as onclick work seamlessly regardless of mouse pointer, touch, or digitized stylus. The drag events don't currently fire with touch. I've tested this in Chrome and IE.
There's a great demo here: http://ie.microsoft.com/testdrive/Browser/BrowserSurface/

Help me understand scrolling in javascript(jquery) terms

When you scroll, are you changing the position of something?
How can I change the position of the scroll? Specifically to match the cursors movement.
What I want to do is scroll the window when I click and drag with the cursor inside the window.
For example:
I have a 400px by 400px div with a 900px by 900px div inside of it. I want to scroll around by click and dragging. Note, I do NOT want to move the position of the inside div (easily doable with jQuery UI via draggable), just the scroll position. Moving the actual div position messes with my other javascript applications.
Any help would be appreciated! Thanks!
This should get you going with horizontal scrolling. Vertical would be similar, but with scrollTop().
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
var lastPageX;
$(document).ready(function() {
$("#inner").mousedown(function(e) {
// Reference to the drag pad
var inner = $(this);
// Position where mouse was pressed
lastPageX = e.pageX;
// Attach mouse move listener
$(inner).mousemove(function(e) {
var diff = lastPageX - e.pageX;
// Scroll based on the new curson position
$("#outer").scrollLeft($("#outer").scrollLeft() + diff);
lastPageX = e.pageX;
});
// Remove mouse move listener
$(window).mouseup(function() {
$(inner).unbind("mousemove");
});
return false;
});
});
</script>
<style>
#outer {
height: 400px;
width: 400px;
background-color: Lime;
overflow: scroll;
}
#inner {
height: 900px;
width: 900px;
background-color: Yellow;
}
</style>
</head>
<body>
<div id="outer">
<div id="inner">
</div>
</div>
</body>
</html>
Edit: Return false after the mousedown is handled to prevent firefox from grabbing the div.

Can I have a click and keyboard handler for RaphaelJS' canvas events?

I am new to RaphaelJS. I am trying to add click listener and keyboard listener to the canvas with no success. Can someone please explain how to use click listener and keyboard listener on Raphael. A small example will be of great help.
Thank you.
Here is a click and mouseover example, you can use more jQuery in there to simplify it but I just wanted to use the document ready function. Shouldn't be too much to add a keyboard event in there:
<html>
<head>
<script type="text/javascript" src="http://github.com/DmitryBaranovskiy/raphael/blob/master/raphael-min.js?raw=true"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
var paper = new Raphael(document.getElementById('canvas_container'), 500, 500);
var circ = paper.circle(250, 250, 40);
circ.node.onmouseover = function()
{
this.style.cursor = 'pointer';
};
circ.node.onclick = function()
{
circ.animate({opacity: 0}, 2000, function()
{
this.remove();
});
}
});
</script>
<style type="text/css">
#canvas_container
{
width: 500px;
border: 1px solid #aaa;
}
</style>
</head>
<body>
<div id="canvas_container"></div>
</body>
</html>

Categories

Resources