How to create a new element, then drag it with interactjs? - javascript

What I'm trying to do, is create an element from a none-draggable element. Then start dragging the new element from there.
I've seen the examples, and managed to replicate the examples from Interact.js where you clone and drag an already draggable element in Interact.js. But that's not what I'm doing here.
interact('.drag-drop')
.draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
autoScroll: true,
onmove: dragMoveListener
})
function createDragDropElement(event){
var element = document.createElement('div');
element.className = 'drag-drop';
element.text = 'Drop me!';
element.style.position = 'absolute';
element.style.left = event.pageX + 'px';
element.style.top = event.pageY + 'px';
document.body.appendChild(element);
//here is where I'd like to transfer the drag over to the newly created element.
}
I've managed to create the element just fine. However, I'm having trouble automatically dragging it. After creation, I need to release the mouse and start a new drag on the element. What I'd like to happen though, is that I start dragging the element immediately rather than having to re-click on it.

Related

Gojs React+HTML drag ,disbale drop location to already existing nodes

div.addEventListener("drop", event => {
// prevent default action
// (open as link for some elements in some browsers)
event.preventDefault();
// Dragging onto a Diagram
if (div === myDiagram.div) {
var can = event.target;
var pixelratio = myDiagram.computePixelRatio();
// if the target is not the canvas, we may have trouble, so just quit:
if (!(can instanceof HTMLCanvasElement)) return;
var bbox = can.getBoundingClientRect();
var bbw = bbox.width;
if (bbw === 0) bbw = 0.001;
var bbh = bbox.height;
if (bbh === 0) bbh = 0.001;
var mx = event.clientX - bbox.left * ((can.width / pixelratio) / bbw) - dragged.offsetX;
var my = event.clientY - bbox.top * ((can.height / pixelratio) / bbh) - dragged.offsetY;
var point = myDiagram.transformViewToDoc(new go.Point(mx, my));
myDiagram.startTransaction('new node');
myDiagram.model.addNodeData({
location: point,
text: event.dataTransfer.getData('text'),
color: "lightyellow"
});
myDiagram.commitTransaction('new node');
// remove dragged element from its old location
if (remove.checked) dragged.parentNode.removeChild(dragged);
}
// If we were using drag data, we could get it here, ie:
// var data = event.dataTransfer.getData('text');
}, false);
Am using HTML drag and drop , and dropping to Canvas (GOJS) Area.
So far working fine , am able to drag elements from one component( giving draggable="true") to the elements and dropping to another component using onDrop function and onDragOver function , and once dropped , am constructing new nodes
Everything working as expected , i have 2 queries basically
I dont want to drag elements to overlap already existing nodes. Meaning whenever i am dragging and entering to drop area i can see green + sign and now I am able to drop to the already existing nodes (imagine already 3 nodes are there for some diagram) , so that it will overlap , some how i NEED to restrict and show X sign when it overlap already existing nodes and should NOT allow to drop on other nodes
When i dragged and dropped element , is there any way i can highlight node , giving impression its the newly added node.
I am taking reference from this url
https://github.com/NorthwoodsSoftware/GoJS/blob/master/samples/htmlDragDrop.html
Can anyone help me with it

Chrome extension click bot in webGL

I am trying to develop a chrome plugin that will record a series of click and play them back
I have seen that you can simulate a click on a DOM element but the problem is in my case, I only have a webGL canvas and the buttons are not directly accessible
I have managed to get the user's click position using this :
document.onclick = function(e)
{
var x = e.pageX;
var y = e.pageY;
console.log(x + " " + y)
//browser.runtime.sendMessage({"message": "open_new_tab", "url": "aze"});
};
But I haven't found anything to use these positions to perform a click action on the page
If I understand your question properly, you want to simulate a click on the webpage?
JavaScript has the click() method exposed for all elements:
element.click()
If you don't know the element, but just the positions:
document.elementFromPoint(x, y).click()
You can dispatch a mouse click at a specific position:
const = (x, y) => {
const ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x,
'screenY': y
})
const el = document.elementFromPoint(x, y);
el.dispatchEvent(ev);
}
All the above should be done via Content Script within the extension.

How to offset createjs button helpers' hit area?

I'm using a button helper to allow the clicking of a display box and text area. IF you hover over the box with your mouse only about 2/3 of the box is clickable.
And the selected area is allowed outside of the box on the right side. How do I set the clickable area correctly? Just the box is suppose to be clickable
Game Link to see example - grey directions box is on second page of link.
self.stage.addChild(titleText);
var directionsbox = new createjs.Container();
displaybox = new createjs.Shape();
displaybox.graphics.beginFill("gray").drawRoundRect(0, 0, 550, 350, 8);
displaybox.name = "DirectionsBox";
displaybox.x = 125;
displaybox.y = 120;
var label = new createjs.Text("\n" + gameData.Description + "\n\n\nDirections \n \nThere are 3 levels to complete. \nEach level gets a bit faster. \nYour high sccore will automataly be submited to the Arcade. \n\n\nClick here to start sorting.", "bold 20px Arial", "#FFFFFF");
label.textAlign = "center";
label.lineWidth = 550;
label.y = displaybox.y;
label.x = displaybox.x + 275
directionsbox.addChild(displaybox, label);
self.stage.addChild(directionsbox);
var helper = new createjs.ButtonHelper(displaybox, "out", "over", "down", false, displaybox, "hit");
helper.y = displaybox.y;
helper.x = displaybox.x + 275
displaybox.addEventListener("click", handleClick);
function handleClick(event) {
createjs.Sound.play("click");
self.stage.removeChild(directionsbox);
StartInteraction();
}
The issue with your hitArea is that you are using your instance as it's own hitArea explicitly. HitAreas are meant to automatically position to their content. Because your displaybox has an x/y already set, it is added to the hitArea's position, which has already been positioned relative to your visible displayBox.
In your example, you can just set the hitArea parameter of ButtonHelper to null. This will make the ButtonHelper use the actual visible content as the hitArea, which works fine. If you want to use an external instance, you can clone the DisplayBox, set it's x/y to 0, and use that.
// Just use null
var helper = new createjs.ButtonHelper(displaybox, "out", "over", "down", false, null, "hit");
// Use a new instance
var hitbox = displayBox.clone().set({x:0, y:0});
var helper = new createjs.ButtonHelper(displaybox, "out", "over", "down", false, hitbox, "hit");
Hope that helps.

.setCapture and .releaseCapture in Chrome

I have an HTML5 canvas based Javascript component that needs to capture and release mouse events. In the control the user clicks an area inside it and drags to affect a change. On PC I would like the user to be able to continue dragging outside of the browser and for the canvas to receive the mouse up event if the button is released outside of the window.
However, according to my reading setCapture and releaseCapture aren't supported on Chrome.
Is there a workaround?
An article written in 2009 details how you can implement cross-browser dragging which will continue to fire mousemove events even if the user's cursor leaves the window.
http://news.qooxdoo.org/mouse-capturing
Here's the essential code from the article:
function draggable(element) {
var dragging = null;
addListener(element, "mousedown", function(e) {
var e = window.event || e;
dragging = {
mouseX: e.clientX,
mouseY: e.clientY,
startX: parseInt(element.style.left),
startY: parseInt(element.style.top)
};
if (element.setCapture) element.setCapture();
});
addListener(element, "losecapture", function() {
dragging = null;
});
addListener(document, "mouseup", function() {
dragging = null;
}, true);
var dragTarget = element.setCapture ? element : document;
addListener(dragTarget, "mousemove", function(e) {
if (!dragging) return;
var e = window.event || e;
var top = dragging.startY + (e.clientY - dragging.mouseY);
var left = dragging.startX + (e.clientX - dragging.mouseX);
element.style.top = (Math.max(0, top)) + "px";
element.style.left = (Math.max(0, left)) + "px";
}, true);
};
draggable(document.getElementById("drag"));
The article contains a pretty good explanation of what's going on, but there are a few gaps where knowledge is assumed. Basically (I think), in Chrome and Safari, if you handle mousemove on the document then, if the user clicks down and holds the mouse, the document will continue receiving mousemove events even if the cursor leaves the window. These events will not propagate to child nodes of the document, so you have to handle it at the document level.
Chrome supports setPointerCapture, which is part of the W3C Pointer events recommendation. Thus an alternative would be to use pointer events and these methods.
You might want to use the jquery Pointer Events Polyfill to support other browsers.

HTML5 drag and drop element over div with Hammer.js drag events

TL;DR
I want to use HTML5 drag and drop of an element to a container with drag Hammer.js events. However, there are conflicts.
Detailed description:
As presented in the attached figure, I have two containers:
Left: container with draggable elements
Right: container with Hammer.js events, namely drag, dragstart and dragend.
I want to drag and drop elements from the left container to the right one.
However, while dragging, when entering on the right container, the Hammer.js dragstart event is activated. After dropping the element, I apply the drag event on the right container. However, the Hammer.js drag event is activated and it considers the deltaX and deltaY from the previous dragstart event.
Hammer.js is being used with preventDefault: true:
Hammer(this.container, {preventDefault: true}).on('dragstart', function (event) { ... }
I have already used event.preventDefault() and event.stopPropagation() on the dragstart of the draggable element, without success.
I have also partially solved the problem. In the dragstart event of the Hammer.js container, I have added the following verification, in order to check if the source element and the target are the same. However, the drag in the right container only works on the second action, since the first one is ignored.
if (event.gesture.startEvent.srcEvent.srcElement != event.gesture.target) {
return false;
}
Any idea on how to prevent Hammer.js events while dragging elements using the HTML5 drag and drop API?
I want to use flags as a last resort, since Hammer.js events should be developed by third-parties.
Thanks for your help.
Hammer.js events should only be captured if they have previously been bound.
Try using a case statement...(this is from an app that I built recently) I can case the statement then break out or return false etc to prevent things. Theoretically though, if I unbind or exclude the event "drag" it should work anyway.
<script>
var hammertime = Hammer(document.getElementById('image-wrapper'), {
transform_always_block: true,
transform_min_scale: window.initScale,
transform_max_scale: 1,
drag_block_horizontal: true,
drag_block_vertical: true,
drag_min_distance: 0
});
//console.log(hammertime);
var posX = window.calcLeft, posY = window.calcTop,
lastPosX = window.calcLeft, lastPosY = window.calcTop,
bufferX = 0, bufferY = 0,
scale = window.initScale, last_scale,
rotation = window.rotationNeeded, last_rotation, dragReady = 0;
hammertime.on('touch drag dragend transform release mouseleave transformend pinchin pinchout', function (ev) {
elemRect = document.getElementById('the-image');
manageMultitouch(ev);
});
function manageMultitouch(ev) {
var pinchDirection;
ev.stopPropagation();
//console.log(ev.type);
switch (ev.type) {
case 'touch':
last_scale = scale;
last_rotation = rotation;
break;
case 'drag':
posX = ev.gesture.deltaX + lastPosX;
posY = ev.gesture.deltaY + lastPosY;
break;
case 'pinchin':
console.log('pinchin');
pinchDirection = "in";
break;
case 'pinchout':
console.log('pinchout');
pinchDirection = "out";
break;
case 'transform':
rotation = window.rotationNeeded;// rotation + ev.gesture.rotation;//we can change this to snap rotation eventually.
//console.log('Last Scale: ', last_scale);
scale = Math.max(hammertime.options.transform_min_scale, Math.min(last_scale * ev.gesture.scale, 1));
var propsImage = document.getElementById('the-image').getBoundingClientRect();
//console.log(propsImage);
var propsBox = document.getElementById('image-wrapper').getBoundingClientRect();
//console.log(propsBox);
break;
case 'transformend':
console.log('We are finished transforming.');
//when they finish transforming, we need to determinw what the new left reset position would be.
var propsImage = document.getElementById('the-image').getBoundingClientRect();
var propsBox = document.getElementById('image-wrapper').getBoundingClientRect();
//window.calcLeft = Math.round(window.preBounds.left - propsImage.left);
//console.log(ev.type);
//if (pinchDirection = "out") {
window.calcLeft = Math.round(window.calcLeft + ((propsImage.width - propsBox.width) / 2));
//} else if (pinchDirection = "in") {
//window.calcLeft = Math.round(window.calcLeft - ((propsImage.width - propsBox.width) / 2));
//}
//window.calcTop = Math.round(window.calcTop + ((propsImage.top - propsBox.top) / 2));
//console.log(window.calcLeft);
break;
case 'dragend':
//console.log('We are finished dragging.');
//console.log(window.calcLeft);
lastPosX = posX;
lastPosY = posY;
checkBounds();
break;
case 'mouseleave':
//console.log('Release!', posX, posY);
//checkBounds();
break;
}
<script>

Categories

Resources