Published
Edited
Oct 31, 2020
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
// FOLLOW HERE
// The idea is to:
// drag the background to create a new Item. At drag start, the item is created, and a resize interaction is started on that item immediately in order to set its size.
// Then, we also want to add drag behavior on the items in order to move them, and resize behavior to resize them

const less = `
& {
height: 300px;
overflow: hidden;
}

.item {
background-color: #29e;
color: #fff;
font-size: 1.2em;
border-radius: 4px;
padding: 2%;
margin: 5%;
-webkit-user-select: none;
user-select: none;
-ms-touch-action: none;
touch-action: none;
}
`;

const div = scoped([], less, { wrapperIdPrefix: 'create-resize' });
const divId = div.getAttribute('id');

interact(`#${divId}`).draggable({
//manualStart: true,
hold: 1000,
listeners: {
move(event) {
//.on('move', function(event) {
var interaction = event.interaction;
// if the pointer was moved while being held down
// and an interaction hasn't started yet
if (interaction.pointerIsDown && !interaction.interacting()) {
const container = event.currentTarget;
const newItem = container.appendChild(
html`<div class="item">new item</div>`
);

const x = container.offsetLeft + event.offsetX - newItem.offsetLeft;
const y = container.offsetTop + event.offsetY - newItem.offsetTop;
newItem.setAttribute('data-x', x);
newItem.setAttribute('data-y', y);
newItem.style.webkitTransform = newItem.style.transform =
'translate(' + x + 'px, ' + y + 'px)';

// attach listeners
interact(newItem).draggable({
manualStart: false,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
inertia: true,
listeners: {
// call this function on every dragmove event
move(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);
}
}
});

// start a drag interaction targeting the clone
interaction.start({ name: 'drag' }, event.interactable, newItem);
}

event.preventDefault();
}
}
});

invalidation.then(() => {
interact(`#${divId}`).unset();
interact(`#${divId} .item`).unset();
});
return div;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more