my dragitem initially appears in the upper left. I want to give a space of 100 pixels from the top and left at the opening. but I have to do this with interactjs own code, not css. because if i do it with css the scroll setting is broken
interact('.dragitem')
.draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
autoScroll: true,
listeners: {
move: dragMoveListener
}
})
function dragMoveListener (event) {
var target = event.target
var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
}
window.dragMoveListener = dragMoveListener
.drag-container {
width:1000px;
height:1000px;
background:red;
}
.dragitem {
width:100px;
height:100px;
background:blue;
}
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>
<div class="drag-container">
<div class="dragitem">drag me</div>
</div>
You have to edit the starting position in style, data-x and data-y directly in HTML
<div class="dragitem" style="transform: translate(100px, 100px);" data-x="100" data-y="100">drag me</div>
interact('.dragitem')
.draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
autoScroll: true,
listeners: {
move: dragMoveListener
}
})
function dragMoveListener (event) {
var target = event.target
var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
}
window.dragMoveListener = dragMoveListener
.drag-container {
width:1000px;
height:1000px;
background:red;
}
.dragitem {
width:100px;
height:100px;
background:blue;
}
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>
<div class="drag-container">
<div class="dragitem" style="transform: translate(100px, 100px);" data-x="100" data-y="100">drag me</div>
</div>
Related
Hello I'm searching "Object Layout library" its working on JavaScript.
I want to implement function for my web app like these feature below (look at this link).
https://imgur.com/mJq3HiV
I already searched information but I couldn't find a good module. Do you know a library something like that?
Okay, you are looking for interact.js here is the npm link.
Read the docs to learn, see the snippet bellow to see if is that what you want.
function dragMoveListener(event) {
var target = event.target
// keep the dragged position in the data-x/data-y attributes
var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)'
// update the posiion attributes
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
}
window.onload = () => {
interact('.resize-drag')
.resizable({
// resize from all edges and corners
edges: { left: true, right: true, bottom: true, top: true },
listeners: {
move(event) {
var target = event.target
var x = (parseFloat(target.getAttribute('data-x')) || 0)
var y = (parseFloat(target.getAttribute('data-y')) || 0)
// update the element's style
target.style.width = event.rect.width + 'px'
target.style.height = event.rect.height + 'px'
// translate when resizing from top or left edges
x += event.deltaRect.left
y += event.deltaRect.top
target.style.webkitTransform = target.style.transform =
'translate(' + x + 'px,' + y + 'px)'
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height)
}
},
modifiers: [
// keep the edges inside the parent
interact.modifiers.restrictEdges({
outer: 'parent'
}),
// minimum size
interact.modifiers.restrictSize({
min: { width: 100, height: 50 }
})
],
inertia: true
})
.draggable({
listeners: {
// call this function on every dragmove event
move: dragMoveListener,
// call this function on every dragend event
end(event) {
var textEl = event.target.querySelector('p')
textEl && (textEl.textContent =
'moved a distance of ' +
(Math.sqrt(Math.pow(event.pageX - event.x0, 2) +
Math.pow(event.pageY - event.y0, 2) | 0))
.toFixed(2) + 'px')
}
},
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
]
})
}
.resize-drag {
background-color: #29e;
color: white;
font-size: 20px;
font-family: sans-serif;
border-radius: 8px;
padding: 20px;
touch-action: none;
width: 120px;
/* This makes things *much* easier */
box-sizing: border-box;
}
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>
<div class="resize-drag">
Resize from any edge or corner
</div>
How can I jump a resized div to next row when the resize is constrained on the parent div like below (fullcalendar like thing).
Update.This code is dependent on InteractJS (http://interactjs.io/)
interact(resizeDiv)
.resizable({
edges: { left: true, right: true, bottom: false, top: false },
restrictEdges: {
endOnly: true,
outer: '.month'
},
restrictSize: {
min: { width: 80, height: 3 },
max: {height: 3}
},
inertia: true,
})
.on('resizemove', function (event) {
var target = event.target,
x = (parseFloat(target.getAttribute('data-x')) || 0),
y = (parseFloat(target.getAttribute('data-y')) || 0);
target.style.width = event.rect.width + 'px';
target.style.height = event.rect.height + 'px';
x += event.deltaRect.left;
y += event.deltaRect.top;
target.style.webkitTransform = target.style.transform =
'translate(' + x + 'px,' + y + 'px)';
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height);
var onTopElement = document.elementFromPoint(event.clientX, event.clientY);
let calendarArea = document.getElementById('calendarArea');
console.log(event.clientY, target.offsetTop);
})
Example - Fullcalendar:
Fullcalendar logic is simple, it will create a new div on next row rather than using the same div which you are resizing and apply resize(for fullcalendar, it uses JQuery resize event) event on the new div. I think its technically impossible to use the same div(same dom element) on the two rows which you are trying to do.
I have a div which I want to resize from all sides and corners, i.e. nw, n, ne, e, w, sw, s, se. I have tried jquery ui's resizable plugin but in my code that is not working. I have removed complexity from my code and placed it in a very basic fiddle.
I have tried to resize only north-west corner of a div and put that logic in fiddle. Logic seems correct to me but mouse interaction is working in a weird way.
Can you guys tell me what am I doing wrong here? If I get it correct for top left corner I can manage for the remaining ones. Thanks.
HTML:
<div id="box">
<div id="nw"></div>
<div id="n"></div>
<div id="ne"></div>
<div id="w"></div>
<div id="e"></div>
<div id="sw"></div>
<div id="s"></div>
<div id="se"></div>
</div>
<p class="one"></p>
<p class="two"></p>
CSS:
#box{border:1px solid #000;width:100px;height:100px;background-color:red;position:absolute;top:100px;left:100px}
#box > div{height:10px;width:10px;background-color:#000;position:absolute}
#nw{top:-5px;left:-5px;cursor:nw-resize}
#n{top:-5px;left:45px;cursor:n-resize}
#ne{top:-5px;right:-5px;cursor:ne-resize}
#w{top:45px;left:-5px;cursor:w-resize}
#e{top:45px;right:-5px;cursor:e-resize}
#sw{bottom:-5px;left:-5px;cursor:sw-resize}
#s{bottom:-5px;left:45px;cursor:s-resize}
#se{bottom:-5px;right:-5px;cursor:se-resize}
p{margin-top:250px;font-size:8px}
JS:
$(function(){
var mousepress = false;
$("#box > div").mousedown(function(e){
mousepress = true;
});
$("#box > div").mousemove(function(e){
if(mousepress) {
var boxX = $("#box").position().left;
var boxY = $("#box").position().top;
var boxW = $("#box").width();
var boxH = $("#box").height();
var x = boxX - e.pageX;//$(this).position().left;
var y = boxY - e.pageY;//$(this).position().top;
$("p.two").append("x: "+x+"<br />");
$(this).css({
"top":y+"px",
"left":x+"px"
});
$("#box").css({
"top":(boxY+y-5)+"px",
"left":(boxX+x-5)+"px",
"width":(boxW+x)+"px",
"height":(boxH+y)+"px",
});
}
});
$("#box > div").mouseup(function(){
mousepress = false;
});
});
**JSFIDDLE: **http://jsfiddle.net/ashwyn/v8qoLj76/2/
I didn't quite understand how you calculated the size and position of the box, without knowing which of the inside divs the user pressed.
I have changed it to use the mouse event position.
I also moved the mousemove and mouseup events to the document, because when dragging using the mouse, it may move faster then the DOM and got out of the box.
I also changed positions of inside divs to use 50% so it will always be in the middle. You may need to add a bit of margin to have it better centered. (See north vs south - I added margin-left to one of them)
This works fine for me.
http://jsfiddle.net/v8qoLj76/4/
var prev_x = -1;
var prev_y = -1;
var dir = null;
$("#box > div").mousedown(function(e){
prev_x = e.clientX;
prev_y = e.clientY;
dir = $(this).attr('id');
});
$(document).mousemove(function(e){
if (prev_x == -1)
return;
var boxX = $("#box").position().left;
var boxY = $("#box").position().top;
var boxW = $("#box").width();
var boxH = $("#box").height();
var dx = e.clientX - prev_x;
var dy = e.clientY - prev_y;
//Check directions
if (dir.indexOf('n') > -1) //north
{
boxY += dy;
boxH -= dy;
}
if (dir.indexOf('s') > -1) //south
{
boxH += dy;
}
if (dir.indexOf('w') > -1) //west
{
boxX += dx;
boxW -= dx;
}
if (dir.indexOf('e') > -1) //east
{
boxW += dx;
}
$("#box").css({
"top":(boxY)+"px",
"left":(boxX)+"px",
"width":(boxW)+"px",
"height":(boxH)+"px",
});
prev_x = e.clientX;
prev_y = e.clientY;
});
$(document).mouseup(function(){
prev_x = -1;
prev_y = -1;
});
Is it something that you need (see the snippet below)?
$(function() {
var ORIGINAL_TOP = 100, ORIGINAL_LEFT = 100, ORIGINAL_WIDTH = 100, ORIGINAL_HEIGHT = 100, OFFSET = 5;
$('.top').css({top: (ORIGINAL_TOP - OFFSET) + 'px'});
$('.left').css({left: (ORIGINAL_LEFT - OFFSET) + 'px'});
$('.bottom').css({top: (ORIGINAL_TOP + ORIGINAL_HEIGHT - OFFSET) + 'px'});
$('.right').css({left: (ORIGINAL_LEFT + ORIGINAL_WIDTH - OFFSET) + 'px'});
$('.control-element').css({height: (2 * OFFSET) + 'px', width: (2 * OFFSET) + 'px'});
var moveMiddleControls = function(top, left, width, height) {
['top', 'bottom'].forEach(function(coordinate) {
$('#' + coordinate).css({left: (left + width / 2 - OFFSET) + 'px'});
});
['left', 'right'].forEach(function(coordinate) {
$('#' + coordinate).css({top: (top + height / 2 - OFFSET) + 'px'});
});
};
var resizeBox = function(top, left, width, height) {
$('#box').css({
top: top + 'px',
left: left + 'px',
width: width + 'px',
height: height + 'px'
});
};
var updateStatus = function(top, left, width, height) {
$('#status-top').html(Math.round(top));
$('#status-left').html(Math.round(left));
$('#status-width').html(Math.round(width));
$('#status-height').html(Math.round(height));
};
var updatePosition = function(top, left, width, height) {
resizeBox(top, left, width, height);
moveMiddleControls(top, left, width, height);
updateStatus(top, left, width, height);
};
var update = function() {
updatePosition(
$('#top').position().top + OFFSET,
$('#left').position().left + OFFSET,
$('#right').position().left - $('#left').position().left,
$('#bottom').position().top - $('#top').position().top
);
};
update();
var activeElement;
$('.control-element').mousedown(function(e) {
activeElement = this;
e.preventDefault();
return false;
});
$(document).mousemove(function(e) {
if(activeElement !== undefined) {
['top', 'bottom'].forEach(function(className) {
if($(activeElement).hasClass(className)) {
$('.' + className).css({top: e.pageY + 'px'});
}
});
['left', 'right'].forEach(function(className) {
if($(activeElement).hasClass(className)) {
$('.' + className).css({left: e.pageX + 'px'});
}
});
update();
}
});
$(document).mouseup(function() {
activeElement = undefined;
});
});
#box {
border:1px solid #000;
background-color:red;
position: fixed;
}
.control-element {
background-color: #000;
position: fixed;
}
#top-left {
cursor: nw-resize;
}
#top {
cursor:n-resize;
}
#top-right {
cursor:ne-resize;
}
#left {
cursor:w-resize;
}
#right {
cursor:e-resize;
}
#bottom-left {
cursor:sw-resize;
}
#bottom {
cursor:s-resize;
}
#bottom-right {
cursor: se-resize;
}
.status {
position:fixed;
right: 5px;
bottom: 10px;
width: 80px;
height: 80px;
z-index: 999;
font-size:8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="box"></div>
<div id="top-left" class="control-element top left"></div>
<div id="top" class="control-element top"></div>
<div id="top-right" class="control-element top right"></div>
<div id="right" class="control-element right"></div>
<div id="bottom-right" class="control-element bottom right"></div>
<div id="bottom" class="control-element bottom"></div>
<div id="bottom-left" class="control-element bottom left"></div>
<div id="left" class="control-element left"></div>
<div class="status">
<div>top: <span id="status-top"></span>px</div>
<div>left: <span id="status-left"></span>px</div>
<div>width: <span id="status-width"></span>px</div>
<div>height: <span id="status-height"></span>px</div>
</div>
I'm have trouble with cloning an object using interact.js. I can do drag and drop, but there is no way to get clone from the objects.
I put here drag and drop code. Can someone modify it to clone objects?
#drag-1, #drag-2 {
width: 20%;
height: 10%;
min-height: 6.5em;
margin: 10%;
background-color: #29e;
color: white;
border-radius: 0.75em;
padding: 4%;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
}
#drag-me::before {
content: "#" attr(id);
font-weight: bold;
}
top:35px; left:40px; width:50px; height:50px;
z-index:99; background-color:#44ebfa;
}
<html>
<head>
<title>test 1 </title>
<!--<script type="text/javascript" src="d3-js/d3.min.js"></script>-->
<script type="text/javascript" src="www.googledrive.com/host/0B4A7r4wXVSe-SDdVdlNtbnhFZ2s"></script>
<link rel="stylesheet" type="text/css" href="test1_css1.css">
</head>
<body>
<script>
// target elements with the "draggable" class
interact('.draggable')
.draggable({
// enable inertial throwing
inertia: true,
// keep the element within the area of it's parent
restrict: {
restriction: "parent",
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
// call this function on every dragmove event
onmove: dragMoveListener,
// call this function on every dragend event
onend: function (event) {
var textEl = event.target.querySelector('p');
textEl && (textEl.textContent =
'moved a distance of '
+ (Math.sqrt(event.dx * event.dx +
event.dy * event.dy)|0) + 'px');
}
});
function dragMoveListener (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
// this is used later in the resizing demo
window.dragMoveListener = dragMoveListener;
</script>
<div id="drag-1" class="draggable">
<p> You can drag one element </p>
</div>
<div id="drag-2" class="draggable">
<p> with each pointer </p>
</div>
</body>
</html>
Try this code sample
interact('.draggable').draggable({
inertia: true,
restrict: {
restriction: "#visualizer-panel",
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
onmove: function (event) {
var target = event.target;
var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
target.style.webkitTransform =
target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
},
onend: function(event) {
console.log(event);
}
}).on('move', function (event) {
var interaction = event.interaction;
if (interaction.pointerIsDown && !interaction.interacting() && event.currentTarget.getAttribute('clonable') != 'false') {
var original = event.currentTarget;
var clone = event.currentTarget.cloneNode(true);
var x = clone.offsetLeft;
var y = clone.offsetTop;
clone.setAttribute('clonable','false');
clone.style.position = "absolute";
clone.style.left = original.offsetLeft+"px";
clone.style.top = original.offsetTop+"px";
original.parentElement.appendChild(clone);
interaction.start({ name: 'drag' },event.interactable,clone);
}
});
The desired result that I'm looking for is for the red square to follow the mouse smoothly, and not flicker back to the original position. Basically, I want to click the red square, drag it to an area, and then release to have that be the new location. Why is it flickering, and how can I achieve a simple drag and follow?
html
<div style="height:500px; width:500px; background-color:#ccc;">
<div id="custom-front" style="width:100%; height:100%;">
<div id="custom-content" style="z-index:200; position:absolute; text-align:center; background-color:red; width:50px; height:50px;">
</div>
</div>
js
window.onload = addListeners();
function addListeners(){
document.getElementById('custom-content').addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
}
function mouseUp()
{
window.removeEventListener('mousemove', divMove, true);
}
function mouseDown(e){
window.addEventListener('mousemove', divMove, true);
}
function divMove(e){
document.getElementById('custom-content').style.top = e.offsetY + 'px';
document.getElementById('custom-content').style.left = e.offsetX + 'px';
}
https://jsfiddle.net/703kc43a/1/
i have just changed your javascript code, may be this help you, check this....
interact('.draggable')
.draggable({
// enable inertial throwing
inertia: true,
// keep the element within the area of it's parent
restrict: {
restriction: "parent",
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
// call this function on every dragmove event
onmove: dragMoveListener,
// call this function on every dragend event
onend: function (event) {
var textEl = event.target.querySelector('p');
textEl && (textEl.textContent =
'moved a distance of '
+ (Math.sqrt(event.dx * event.dx +
event.dy * event.dy)|0) + 'px');
}
});
function dragMoveListener (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
// this is used later in the resizing demo
window.dragMoveListener = dragMoveListener;
<script src="http://code.interactjs.io/interact-1.2.4.min.js"></script>
<div style="height:500px; width:500px; background-color:#ccc;">
<div id="custom-front" style="width:100%; height:100%;">
<div id="custom-content" class="draggable" style="z-index:5; position:absolute; text-align:center; background-color:red; width:50px; height:50px;">
</div>
</div>
</div>