Pop-up message does not appear next to cloned objects - javascript

I have a panel with 3 draggable objects and a background image. My JavaScript script (based on interact.js) allows dragging and dropping objects on top of a background image. All draggable objects are also cloneable. It means that each time I drag an original object from the panel, it gets cloned.
Now I want to add a pop-up functionality: when I click on an object, a pop-up message should appear. The problem is that the pop-up message appears next to the original object, but not the cloned one. I what that a pop-up message appears next to an object that I click on (excluding original ones). How can I do it? This is the piece of JavaScript code related to pop-ups:
function myFunction() {
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}
The whole code:
HTML (an example of a circle object that belongs to a class drag-base):
<div id="drag-base" class="popup draggable" onclick="myFunction()">
<span class="popuptext" id="myPopup">A Simple Popup!</span>
</div>
CSS:
#drag-base {
background: #d9534f;
color: #000000;
width: 35px;
height: 35px;
border-radius: 50%;
text-align: center;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
}
.dropzone {
background-color: #e9ebed;
padding: 10px;
width: 100%;
height: 600px;
overflow-y: scroll;
border: dashed 4px transparent;
float:left;
}
.drop-active {
border-color: #aaa;
}
.drop-target {
background-color: #3f5265;
color: #FFF;
border-color: #fff;
border-style: solid;
}
/* Popup container - can be anything you want */
.popup {
position: relative;
display: inline-block;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* The actual popup */
.popup .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 8px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -80px;
}
/* Popup arrow */
.popup .popuptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
/* Toggle this class - hide and show the popup */
.popup .show {
visibility: visible;
-webkit-animation: fadeIn 1s;
animation: fadeIn 1s;
}
/* Add animation (fade in the popup) */
#-webkit-keyframes fadeIn {
from {opacity: 0;}
to {opacity: 1;}
}
#keyframes fadeIn {
from {opacity: 0;}
to {opacity:1 ;}
}
JavaScript:
<script type="text/javascript">
// target elements with the "draggable" class
interact('.draggable').draggable({
inertia: true,
restrict: {
restriction: ".dropzone",
drag: document.getElementById('dropzone'),
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
autoScroll: true,
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.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);
}
})
.resizable({
edges: { left: true, right: true, bottom: true, top: true }
})
.on('resizemove', function (event) {
var target = event.target;
x = (parseFloat(target.getAttribute('data-x')) || 0),
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 = event.rect.width + '×' + event.rect.height;
});
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// Require a 50% element overlap for a drop to be possible
overlap: 0.50,
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active');
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
},
ondrop: function (event) {
//event.relatedTarget.textContent = 'Dropped';
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
$(".dropzone").html("<img src='https://s-media-cache-ak0.pinimg.com/originals/fb/d5/55/fbd5556e0e364b31166bebfce433c14e.jpg'>");
// When the user clicks on div, open the popup
function myFunction() {
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}
</script>

Use the class instead of the ID, and use DOM traversal to find the popup inside the element that was clicked. Pass the clicked element to the function:
<div id="drag-base" class="popup draggable" onclick="myFunction(this)">
<span class="popuptext" id="myPopup">A Simple Popup!</span>
</div>
and then use that in the function:
function myFunction(div) {
div.querySelector(".popuptext").classList.toggle("show");
}

Related

pdf.getPage(1).then(function(page) - How to display whole PDF (not only one page) with PDF.JS?

sample imageenter image description here
How to display the whole PDF (not just one page) with PDF.JS ?
I got the reference from the code here : https://codepen.io/ValerioEmanuele/pen/pGRZqe
but it only shows 1 page, can't display the whole pdf page ?
and i use library :
pdfjsLib.GlobalWorkerOptions.workerSrc =
'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.worker.min.js';
example index.php
<?php
$pdf = base64_encode(file_get_contents('tes2.pdf'));
?>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12" style="padding:10px">
<label>Xpos:</label>
<input type="text" id="Xpos" value="Xpos" readonly>
<label>Ypos:</label>
<input type="text" id="Ypos" value="Ypos" readonly>
</div>
</div>
<div class="row">
<div class="col-md-12" id="pdfManager" style="display:none">
<div class="row" id="selectorContainer">
<div class="col-fixed-605 col-md-9">
<div style="display:block;height:100px">
<img class="drag-drop dropped-out" data-x="0" data-y="0" src="ttd.png" style="width:150px;height: auto">
</div>
<div id="pageContainer" class="pdfViewer singlePageView dropzone nopadding" style="background-color:transparent">
<canvas id="the-canvas" style="border:1px solid black"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- parameters showed on the left sidebar -->
<input id="parameters" type="hidden" value='[{"idParametro":480,"descrizione":"RAPINA","valore":"X","nota":null},{"idParametro":481,"descrizione":"CAUSAL_G00","valore":"X","nota":null},{"idParametro":482,"descrizione":"A","valore":"A","nota":null},{"idParametro":483,"descrizione":"POSTA_REGISTRATA","valore":"X","nota":null},{"idParametro":484,"descrizione":"CD","valore":"CD","nota":null},{"idParametro":485,"descrizione":"DATA_ALERT","valore":"data alert","nota":null},{"idParametro":486,"descrizione":"UP","valore":"UP","nota":null},{"idParametro":488,"descrizione":"DATA_MP","valore":"DATA1","nota":null},{"idParametro":489,"descrizione":"AL_QUALITA","valore":"AL_QUALITA","nota":null},{"idParametro":490,"descrizione":"CAUSAL_G60","valore":"X","nota":null},{"idParametro":491,"descrizione":"DATA","valore":"DATA","nota":null},{"idParametro":492,"descrizione":"DATA_DENUNCIA","valore":"data denuncia","nota":null},{"idParametro":493,"descrizione":"DATA_SPEDIZIONE","valore":"data spedizione","nota":null},{"idParametro":494,"descrizione":"DATA_LAVORAZIONE","valore":"DATA_LAVORAZIONE","nota":null},{"idParametro":495,"descrizione":"NUMERO_FAX","valore":"NUMERO_FAX","nota":null},{"idParametro":496,"descrizione":"SMARRIMENTO","valore":"X","nota":null},{"idParametro":497,"descrizione":"STRUTT_ACCETTAZIONE","valore":"STRUTT_ACCETTAZIONE","nota":null},{"idParametro":498,"descrizione":"FURTO","valore":"X","nota":null},{"idParametro":499,"descrizione":"BARCODE","valore":"BARCODE","nota":null},{"idParametro":502,"descrizione":"CAUSA_MAGGIORE","valore":"X","nota":null},{"idParametro":503,"descrizione":"PACCHI","valore":"X","nota":null},{"idParametro":504,"descrizione":"TIPOLOGIA_EVENTO","valore":"TIPOLOGIA_EVENTO","nota":null},{"idParametro":505,"descrizione":"NOTE","valore":"NOTE","nota":null},{"idParametro":506,"descrizione":"DATA_RITROVAMENTO","valore":"data ritrovamento","nota":null},{"idParametro":507,"descrizione":"DATA_ACCETTAZIONE","valore":"DATA_ACCETTAZIONE","nota":null},{"idParametro":509,"descrizione":"AREA_LOGISTICA","valore":"AREA_LOGISTICA","nota":null},{"idParametro":511,"descrizione":"DA","valore":"DA","nota":null},{"idParametro":512,"descrizione":"DATA_DENUNCIA","valore":"DATA_DENUNCIA","nota":null},{"idParametro":513,"descrizione":"TIPOLOGIA_ALERT","valore":"TIPOLOGIA","nota":null},{"idParametro":515,"descrizione":"STRUTTURA_RILIEVO","valore":"STRUTTURA_RILIEVO","nota":null},{"idParametro":516,"descrizione":"STRUTTURA_DENUNCIA","valore":"STRUTTURA_DENUNCIA","nota":null},{"idParametro":517,"descrizione":"DISPACCIO","valore":"DISPACCIO","nota":null},{"idParametro":518,"descrizione":"CMP_CP","valore":"CMP_CP","nota":null},{"idParametro":520,"descrizione":"FURTO_EFFRAZIONE","valore":"X","nota":null}]' />
<!-- Below the pdf base 64 rapresentation -->
<input id="pdfBase64" type="hidden" value="<?php echo $pdf ?>" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/interact.js/1.2.9/interact.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.worker.min.js"></script>
<script src="script.js"></script>
</body>
</html>
example css.css
#messageContainer{
display:none;
}
#outer-dropzone {
height: 140px;
touch-action: none;
}
#inner-dropzone {
height: 80px;
}
.dropzone {
background-color: #ccc;
border: dashed 4px transparent;
border-radius: 4px;
margin: 10px auto 30px;
padding: 10px;
width: 100%;
transition: background-color 0.3s;
}
.drop-active {
border-color: #aaa;
}
.drop-target {
background-color: #29e;
border-color: #fff;
border-style: solid;
}
.drag-drop {
display: inline-block;
position:absolute;
z-index:999;
min-width: 40px;
padding: 0em 0.5em;
padding-left:0;
color: #fff;
background-color: #29e;
border: none;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
transition: background-color 0.3s;
line-height: 10px;
padding-right: 0 !important;
padding-left: 5px !important;
}
.drag-drop.can-drop {
color: #000;
background-color: transparent;
opacity:0.9;
/* IE 8 */
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
/* IE 5-7 */
filter: alpha(opacity=90);
/* Netscape */
-moz-opacity: 0.9;
/* Safari 1.x */
-khtml-opacity: 0.9;
}
.nopadding {
padding: 0 !important;
margin: 0 !important;
}
.circle {
width: 10px;
height: 10px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
background: #323c3c;
float: left;
display: inline-block;
margin-top: 1px;
margin-right: 2px;
}
.dropped-out{
display: block;
padding: .75rem 1.25rem;
margin-bottom: -1px;
background-color: #fff;
border: 1px solid rgba(0,0,0,.125);
width:200px;
color: black;
}
.col-fixed-240{
width:240px;
height:100%;
z-index:1;
}
.col-fixed-605{
margin-left:240px;
width:605px;
height:100%;
z-index:1;
}
.page-item{
cursor:pointer;
}
.pager{
margin-bottom:30px !important;
margin-top:0px !important;
margin-bottom: -31px !important;
}
.drag-drop.dropped-out .descrizione {
font-size: 12px !important;
}
#the-canvas{
height:842px;
width: 595px;
}
example script.js
var pdfData = atob($('#pdfBase64').val());
/*
* costanti per i placaholder
*/
var maxPDFx = 595;
var maxPDFy = 842;
var offsetY = 0;
'use strict';
// The workerSrc property shall be specified.
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.worker.min.js';
//
// Asynchronous download PDF
//
var loadingTask = pdfjsLib.getDocument({data: pdfData});
loadingTask.promise.then(function(pdf) {
//
// Fetch the first page
//
pdf.getPage(1).then(function(page) {
var scale = 1.0;
var viewport = page.getViewport(scale);
//
// Prepare canvas using PDF page dimensions
//
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
//
// Render PDF page into canvas context
//
var renderContext = {
canvasContext: context,
viewport: viewport
};
//page.render(renderContext);
page.render(renderContext).then(function() {
$(document).trigger("pagerendered");
}, function() {
console.log("ERROR");
});
});
});
/* The dragging code for '.draggable' from the demo above
* applies to this demo as well so it doesn't have to be repeated. */
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '.drag-drop',
// Require a 100% element overlap for a drop to be possible
overlap: 1,
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active');
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
draggableElement.classList.add('can-drop');
draggableElement.classList.remove('dropped-out');
//draggableElement.textContent = 'Dragged in';
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
event.relatedTarget.classList.remove('can-drop');
event.relatedTarget.classList.add('dropped-out');
//event.relatedTarget.textContent = 'Dragged out';
},
ondrop: function (event) {
//console.log(event);
},
ondropdeactivate: function (event) {
var dropzonePostion = $(event.target).position();
elementPosition = $(event.relatedTarget).position();
console.log(elementPosition.top +$(event.target).height());
x = elementPosition.left - dropzonePostion.left;
y = (dropzonePostion.top +$(event.target).height()) - (elementPosition.top + $(event.relatedTarget).height());
$('#Xpos').val(x);
$('#Ypos').val(y);
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
interact('.drag-drop')
.draggable({
inertia: false,
restrict: {
restriction: "#selectorContainer",
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
autoScroll: true,
// dragMoveListener from the dragging demo above
onmove: dragMoveListener,
});
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;
$(document).bind('pagerendered', function (e) {
$('#pdfManager').show();
});

Follow mouse on Hover of Div but only on Div

Not sure how to do this but I have the first part setup right via the codepen here
Not sure how to stop it from occurring unless you hover the black div. Basically I'm looking to have the normal mouse functionality until you hover this black div than fire the script/function. I'm also trying to achieve this without using any libraries and just JS.
Code Below
document.addEventListener("mousemove", function() {
myFunction(event);
});
var mouse;
var cursor = document.getElementById("cursor");
function myFunction(e) {
mouseX = e.clientX;
mouseY = e.clientY;
cursor.style.left = (mouseX - 55) + "px";
cursor.style.top = (mouseY - 55) + "px";
}
body {
background: #FFFDFA;
}
#cursor {
height: 100px;
width: 100px;
position: absolute;
backface-visibility: hidden;
z-index: 9999999;
cursor: none;
}
div {
background: black;
width: 200px;
height: 100px;
margin: 30px;
cursor: none;
}
<img src="https://www.figurefoundry.xyz/metal-cursor.svg" id="cursor"></img>
<div>
</div>
You can simply add the event listener to the div element. You also need to disable pointerEvents on the cursor element so that the mouse doesn't register as on top of the cursor rather than the div.
document.getElementById("div").addEventListener("mousemove", function() {
myFunction(event);
});
var mouse;
var cursor = document.getElementById("cursor");
function myFunction(e) {
mouseX = e.clientX;
mouseY = e.clientY;
cursor.style.left = (mouseX - 55) + "px";
cursor.style.top = (mouseY - 55) + "px";
}
body {
background: #FFFDFA;
}
#cursor {
height: 100px;
width: 100px;
position: absolute;
backface-visibility: hidden;
z-index: 9999999;
pointer-events: none; /* pointer-events: none is needed */
cursor: none;
}
div {
background: black;
width: 200px;
height: 100px;
margin: 30px;
cursor: none;
}
<img src="https://www.figurefoundry.xyz/metal-cursor.svg" id="cursor"></img>
<div id="div"></div> <!--add id-->
EDIT: If you want the cursor to disappear on mouseout:
document.getElementById("div").addEventListener("mousemove", function() {
myFunction(event);
});
var mouse;
var cursor = document.getElementById("cursor");
function myFunction(e) {
mouseX = e.clientX;
mouseY = e.clientY;
cursor.style.left = (mouseX - 55) + "px";
cursor.style.top = (mouseY - 55) + "px";
}
body {
background: #FFFDFA;
}
#cursor {
height: 100px;
width: 100px;
position: absolute;
backface-visibility: hidden;
z-index: 9999999;
pointer-events: none; /* pointer-events: none is needed */
cursor: none;
}
div {
background: black;
width: 200px;
height: 100px;
margin: 30px;
cursor: none;
}
<img src="https://www.figurefoundry.xyz/metal-cursor.svg" id="cursor" hidden></img>
<div id="div" onmouseenter="cursor.hidden = false" onmouseleave="cursor.hidden=true"></div> <!--make cursor invisible on leave and visible on enter-->

prevent click on hyperlink while dragging/holding

I have item div elements with anchor elements as children. The size of the anchor children stretches the parent item element.
I've made the item elements draggable with the library interact.js. The items get draggable when they are hold 300ms or longer. The problem is, that the anchor link of the item child get fired when the drag is released.
How can I prevent the child from firing the hyperlink when the parent element is held/dragged?
Here is a small example of the problem
let items = document.getElementsByClassName("item");
// add class .draggable to each item
for(var i = 0; i < items.length; i++)
{
items[i].classList.add("draggable");
}
// target elements with the "draggable" class
interact('.draggable').draggable({
autoScroll: true,
hold: 300,
// call this function on every dragmove event
onmove: dragMoveListener,
// call this function on every dragend event
onend: function (event) {
var target = event.target;
target.style.webkitTransform =
target.style.transform =
'translate(0px, 0px)';
target.setAttribute('data-x', 0);
target.setAttribute('data-y', 0);
}
});
// this function is calles on every dragmove event
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);
};
interact('.dropzone').dropzone({
ondropactivate: function (event) {
event.target.classList.add('drop-active');
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
draggableElement.classList.add('can-drop');
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
event.relatedTarget.classList.remove('can-drop');
},
ondrop: function (event) {
//delete Bookmark here!
event.relatedTarget.classList.add('drop-ok');
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
body {
background-color: #EDEFF3;
padding: 40px 48px;
}
.item {
display: inline-block;
margin: 8px;
background-color: RGBA(255, 255, 255, 1);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border-radius: 10px;
z-index: 999;
}
.item a {
position: relative;
display: inline-block;
border-radius: 10px;
line-height: 40px;
padding: 0 32px 0 48px;
font-weight: 400;
text-decoration: none;
font-size: 13px;
color: black;
font-size: 14px;
}
.item a .dott {
position: absolute;
top: 12px;
left: 20px;
height: 16px;
width: 16px;
background-color: tomato;
border-radius: 100%;
}
.item.can-drop a {
text-decoration: line-through;
}
.item.drop-ok {
display: none;
}
.category {
display: flex;
flex-wrap: wrap;
position: relative;
align-items: flex-start;
background-color: RGBA(127, 135, 147, 0.2);
margin: 16px;
padding: 8px;
}
.dropzone {
height: 20%;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
background-color: tomato;
opacity: 0;
}
.dropzone.drop-active {
opacity: 1;
}
.dropzone.drop-target {
background-color: #F15B52;
}
<script src="https://cdn.jsdelivr.net/npm/interactjs#1.3.4/dist/interact.min.js"></script>
<div class="category">
<div class="item">
<span class="dott"></span>bookmark
</div>
<div class="item">
<a href="https://www.google.com/">
<span class="dott"></span>
bookmark</a>
</div>
<div class="item">
<span class="dott"></span>bookmark
</div>
<div class="item">
<span class="dott"></span>bookmark
</div>
<div class="item">
<span class="dott"></span>bookmark
</div>
</div>
<div class="dropzone"></div>
Here is my current state at Codepen:
https://codepen.io/iamrbn/pen/pKGPMz
Perhaps not the most elegant solution but it works. My first attempt failed but I think I have something that works now. I created a flag system to keep track of events. Note that I added onstart to the draggable instance. I had to add a 300ms timeout to match the time of the hold. It seems onstart fired immediately on mousedown despite the 300ms hold. I'm not sure how that part of your library works ;)
Anyway, wait 300ms and then set a flag of drag. Note that the variable is global for reference. Check your project variable scope before implementing this. You might want to create a public object instead to keep the global from mixing things up.
I add a click event listener to each link. When the click fired, check the hold flag status. If it is a drag, prevent the event. Otherwise, proceed to register a click. Note: I tried adding this flag evaluator code to the onend method within the draggable instance but onend turns out to be a mouseup event which fires before click. Therefore, the evaluation needs to happen with a click event. The best way to do that within the scope is with adding a click event to each link.
Whew! Gosh, that took probably an hour. Let me know if it works :)
let items = document.getElementsByClassName("item");
// add class .draggable to each item
for (var i = 0; i < items.length; i++) {
items[i].classList.add("draggable");
items[i].children[0].addEventListener('click',function(e){
if(drag){
drag = false;
e.preventDefault()
}
});
}
var drag = false;
// target elements with the "draggable" class
interact('.draggable').draggable({
autoScroll: true,
hold: 300,
// call this function on every dragmove event
onstart: function(){
setTimeout(function(){
drag = true;
},300);
},
onmove: dragMoveListener,
// call this function on every dragend event
onend: function(event) {
var target = event.target;
target.style.webkitTransform =
target.style.transform =
'translate(0px, 0px)';
target.setAttribute('data-x', 0);
target.setAttribute('data-y', 0);
}
});
// this function is calles on every dragmove event
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);
};
interact('.dropzone').dropzone({
ondropactivate: function(event) {
event.target.classList.add('drop-active');
},
ondragenter: function(event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
draggableElement.classList.add('can-drop');
},
ondragleave: function(event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
event.relatedTarget.classList.remove('can-drop');
},
ondrop: function(event) {
//delete Bookmark here!
event.relatedTarget.classList.add('drop-ok');
},
ondropdeactivate: function(event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
body {
background-color: #EDEFF3;
padding: 40px 48px;
}
.item {
display: inline-block;
margin: 8px;
background-color: RGBA(255, 255, 255, 1);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border-radius: 10px;
z-index: 999;
}
.item a {
position: relative;
display: inline-block;
border-radius: 10px;
line-height: 40px;
padding: 0 32px 0 48px;
font-weight: 400;
text-decoration: none;
font-size: 13px;
color: black;
font-size: 14px;
}
.item a .dott {
position: absolute;
top: 12px;
left: 20px;
height: 16px;
width: 16px;
background-color: tomato;
border-radius: 100%;
}
.item.can-drop a {
text-decoration: line-through;
}
.item.drop-ok {
display: none;
}
.category {
display: flex;
flex-wrap: wrap;
position: relative;
align-items: flex-start;
background-color: RGBA(127, 135, 147, 0.2);
margin: 16px;
padding: 8px;
}
.dropzone {
height: 20%;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
background-color: tomato;
opacity: 0;
}
.dropzone.drop-active {
opacity: 1;
}
.dropzone.drop-target {
background-color: #F15B52;
}
<script src="https://cdn.jsdelivr.net/npm/interactjs#1.3.4/dist/interact.min.js"></script>
<div class="category">
<div class="item">
<span class="dott"></span>bookmark
</div>
<div class="item">
<a href="https://www.google.com/">
<span class="dott"></span> bookmark
</a>
</div>
<div class="item">
<span class="dott"></span>bookmark
</div>
<div class="item">
<span class="dott"></span>bookmark
</div>
<div class="item">
<span class="dott"></span>bookmark
</div>
</div>
<div class="dropzone"></div>

How can I prevent this material ripple animation from leaking out into other div?

In the following codepen, the creator has made a material ripple effect. However there is an issue where if I add another div right next to the original the ripple will leak into it.
What should I do to change to code so that the ripple will only be contained in the div that it was activated on?
I have tried editing the JS so that the click function only activates for divs with the class ".rippleDiv" but that did not work either.
Link to codepen http://codepen.io/Ruddy/pen/09052b957d82a17bd6ca70ac6663dd6a
HTML
<div class="rippleDiv">Button</div>
<div>Button 2</div>
CSS
div {
width: 220px;
height: 120px;
background: #222;
color: #fff;
text-align: center;
line-height: 120px;
font-size: 40px;
}
/* Ripple */
.ripple {
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.4);
transform: scale(0);
position: absolute;
opacity: 1;
}
.rippleEffect {
animation: rippleDrop .6s linear;
}
#keyframes rippleDrop {
100% {
transform: scale(2);
opacity: 0;
}
}
JS
$(".rippleDiv").click(function (e) {
// Remove any old one
$(".ripple").remove();
// Setup
var posX = $(this).offset().left,
posY = $(this).offset().top,
buttonWidth = $(this).width(),
buttonHeight = $(this).height();
// Add the element
$(this).prepend("<span class='ripple'></span>");
// Make it round!
if(buttonWidth >= buttonHeight) {
buttonHeight = buttonWidth;
} else {
buttonWidth = buttonHeight;
}
// Get the center of the element
var x = e.pageX - posX - buttonWidth / 2;
var y = e.pageY - posY - buttonHeight / 2;
// Add the ripples CSS and start the animation
$(".ripple").css({
width: buttonWidth,
height: buttonHeight,
top: y + 'px',
left: x + 'px'
}).addClass("rippleEffect");
});
The basic answer is that the 'ripple' element needs to be contained inside a div that has overflow:hidden set.
However to get this right, a number of small changes need to be made so that both the original button content, as well as the ripple itself, are correctly positioned, mainly using divs with the correct positioning attributes set.
So - here are the changes I made to get this to work: http://codepen.io/kitr/pen/xgLQpM
HTML:
<div>Button</div>
<div>Button 2</div>
CSS:
div {
width: 220px;
height: 120px;
background: #222;
color: #fff;
text-align: center;
line-height: 120px;
font-size: 40px;
position:relative;
overflow:hidden;
}
/* Ripple */
.ripple {
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.4);
transform: scale(0);
opacity: 1;
}
.rippleEffect {
animation: rippleDrop .6s linear;
position: absolute;
}
#keyframes rippleDrop {
100% {
transform: scale(2);
opacity: 0;
}
}
Javascript:
$("div").click(function (e) {
// Remove any old one
$(".ripple").remove();
// Setup
var posX = $(this).offset().left,
posY = $(this).offset().top,
buttonWidth = $(this).width(),
buttonHeight = $(this).height();
// Add the element
$(this).append("<div class='ripple'></div>");
// Make it round!
if(buttonWidth >= buttonHeight) {
buttonHeight = buttonWidth;
} else {
buttonWidth = buttonHeight;
}
// Get the center of the element
var x = e.pageX - posX - buttonWidth / 2;
var y = e.pageY - posY - buttonHeight / 2;
// Add the ripples CSS and start the animation
$(".ripple").css({
width: buttonWidth,
height: buttonHeight,
top: y + 'px',
left: x + 'px'
}).addClass("rippleEffect");
});

Dragging DIV with JavaScript mouse events moves to quickly

Im trying to move the #frame-slider-thumb across the image. I had it working by just keeping track of the diff in mouseX position. But the problem was that if the thumb wasn't at 0 to begin with it would jump back to 0. Thus I added the curr variable in the logic to add the diff from its current position. Now it moves much to quickly though. I'm not sure why. Any help much appreciated.
Heres a codepen.
HTML
<div id="frame-slider">
<img id="frame-slider-background" src="http://imagej.1557.x6.nabble.com/file/n5009735/OCT_pre_segmented.png" alt="" />
<div id="frame-slider-track">
<div id="frame-slider-thumb">
<div class="top-half"></div>
<div class="bottom-half"></div>
</div>
</div>
</div>
JS
var mouseStartPosition = {};
var thumb = document.getElementById('frame-slider-thumb');
window.addEventListener("mousedown", mousedownThumb);
function mousedownThumb(e) {
mouseStartPosition.x = e.pageX;
// add listeners for mousemove, mouseup
window.addEventListener("mousemove", mousemoveThumb);
window.addEventListener("mouseup", mouseupThumb);
}
function mousemoveThumb(e) {
var curr = isNaN(parseFloat(thumb.style.left)) ? 0 : parseFloat(thumb.style.left);
var diff = -1 * (mouseStartPosition.x - e.pageX);
var newLeft = curr + diff;
thumb.style.left = newLeft + 'px';
}
function mouseupThumb(e) {
window.removeEventListener("mousemove", mousemoveThumb);
window.removeEventListener("mouseup", mouseupThumb);
}
CSS
html,
body {
width: 100%;
height: 100%;
}
#frame-slider {
height: 150px;
width: 50%;
position: relative;
}
#frame-slider-background {
width: 100%;
max-height: 100%;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-user-drag: none;
user-drag: none;
-webkit-touch-callout: none;
}
#frame-slider-track {
height: 100%;
width: 100%;
position: absolute;
top: 0;
}
#frame-slider-thumb {
position: absolute;
left: 0;
margin-left: -4px;
width: 8px;
height: 100%;
cursor: pointer;
}
#frame-slider-thumb .top-half {
background-color: rgba(0, 0, 255, 0.7);
height: 50%;
}
#frame-slider-thumb .bottom-half {
background-color: rgba(255, 0, 0, 0.7);
height: 50%;
}
Fixed by adding a thumbStart position to mousedownThumb. Basically diff isn't the difference in position from the last mousemove event, its the difference from the last mousemove event and the mousedown event.
var mouseStartPosition = {};
var thumbStart;
var thumb = document.getElementById('frame-slider-thumb');
window.addEventListener("mousedown", mousedownThumb);
function mousedownThumb(e) {
mouseStartPosition.x = e.pageX;
thumbStart = isNaN(parseFloat(thumb.style.left)) ? 0 : parseFloat(thumb.style.left);
// add listeners for mousemove, mouseup
window.addEventListener("mousemove", mousemoveThumb);
window.addEventListener("mouseup", mouseupThumb);
}
function mousemoveThumb(e) {
var diff = -1 * (mouseStartPosition.x - e.pageX);
var newLeft = thumbStart + diff;
thumb.style.left = newLeft + 'px';
}
function mouseupThumb(e) {
window.removeEventListener("mousemove", mousemoveThumb);
window.removeEventListener("mouseup", mouseupThumb);
}

Categories

Resources