I have a window that is draggable and I want to make the document that this window has to be independent and it can be dragged and when dropped the element is copied to where it was dragged and for it to also stay in the window. Basically when what is supposed to do is you drag the document out of the window into anywhere in your screen and when you stop dragging, the document is copied and you have a document on the window and one on your screen. The one on the screen can't be copied but can be dragged. How do I do it?
dragElement(document.getElementById("documento"));
dragElement(document.getElementById("docwindow"));
function dragElement(elmnt) {
var pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
// if present, the header is where you move the DIV from:
document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
} else {
// otherwise, move the DIV from anywhere inside the DIV:
elmnt.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
#janela,
#docwindow,
#BlueWindow {
position: absolute;
width: 40%;
height: 38%;
left: 100px;
}
#docwindowheader,
#BlueWindowheader {
height: 7%;
background: rgb(30, 87, 153);
/* Old browsers */
background: -moz-linear-gradient(top, rgba(30, 87, 153, 1) 0%, rgba(41, 137, 216, 1) 50%, rgba(32, 124, 202, 1) 51%, rgba(125, 185, 232, 1) 100%);
/* FF3.6-15 */
background: -webkit-linear-gradient(top, rgba(30, 87, 153, 1) 0%, rgba(41, 137, 216, 1) 50%, rgba(32, 124, 202, 1) 51%, rgba(125, 185, 232, 1) 100%);
/* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, rgba(30, 87, 153, 1) 0%, rgba(41, 137, 216, 1) 50%, rgba(32, 124, 202, 1) 51%, rgba(125, 185, 232, 1) 100%);
/* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#7db9e8', GradientType=0);
/* IE6-9 */
}
#closeDocs,
#closeBlue {
width: 15px;
height: 15px;
position: absolute;
border-radius: 100%;
top: 4.2%;
right: 1%;
z-index: 2;
}
#docsHeadTexto,
#JoanaPTexto {
color: black;
text-align: center;
text-shadow: 3px 2px grey;
font-size: 95%;
top: 25%;
}
#DocImg {
width: 20%;
height: 20%;
background-color: none;
padding: 5px;
}
img#DocImg {}
#bottomWindowDocs {
background-color:pink;
height: 80%;
border-bottom-left-radius: 5%;
border-bottom-right-radius: 5%;
}
#DocEx {
position: absolute;
top: 33%;
left: 4%;
font-size: 10px;
}
#DocEx {
z-index: 6;
}
<div class="janelas" id="docwindow">
<div id="docwindowheader">
<header class="windowTop">
<h1 id="docsHeadTexto">Documents</h1>
<img id="closeDocs" class="X" src="http://icons.iconarchive.com/icons/oxygen-icons.org/oxygen/256/Actions-dialog-close-icon.png" alt="X" onclick="closeMain()">
</header>
</div>
<div id="bottomWindowDocs">
<div class="documents">
<div id="documento">
<img id="DocImg" src="https://img.icons8.com/pastel-glyph/2x/file.png" alt="doc">
<h1 id="DocEx">Doc-example</h1>
</div>
</div>
<!----<div id="DocExemplo" S>
<header class="windowhead">
Documento exemplo
<img class="X" src="https://banner2.kisspng.com/20180402/dwe/kisspng-computer-icons-social-media-email-webmail-cancel-button-5ac240963875f3.0504665115226799582313.jpg" alt="X" onclick="closeMain()">
<button id="share">share</button>
<button id="back">back</button>
</header>
<div id="corpo">
<h4>Este é um exemplo de Documento</h4>
</div>
</div>-->
</div>
</div>
Just to illustrate the basic functionality using jQuery's draggable(), check this demo on jsFiddle.
Here's the JS you would need to allow dragging one element with children that may be dragged and dropped separately:
$('#doc-container').droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
cursor: 'move',
greedy: true,
drop: function(event, ui) {
console.log(ui);
$(ui.draggable).removeClass("out-of-box").addClass("in-box");
ui.draggable.detach().appendTo($(this));
}
});
$('#larger-drop-target').droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
cursor: 'move',
drop: function(event, ui) {
$(ui.draggable).removeClass("in-box").addClass("out-of-box");
ui.draggable.detach().appendTo($(this));
}
});
$("#doc-container, .draggable").draggable({});
My sample uses the following HTML layout:
<div id="larger-drop-target">
<div id="doc-container" class="ui-widget-header droppable">
<header class="windowTop">
<h1 id="docsHeadTexto">Documents</h1>
</header>
<div id="draggable" style="left:0;" class="draggable ui-widget-content">
Doc Example
</div>
</div>
</div>
and CSS Code:
#larger-drop-target {
width: 100%;
height: 100%;
}
.draggable {
width: 80px;
height: 80px;
padding: 5px;
position: absolute;
}
#doc-container {
height: 200px;
}
.in-box {
background: #FEE;
}
.out-of-box {
background: #EFE;
}
Some explanatory words:
droppable() defines those elements that may accept elements to be dragged onto. In the sample I could not use the HTML "body" element as this wouldn't work in a fiddle so I decided to wrap the #doc-container in the larger container #larger-drop-target. The .detach() and .attachTo() makes sure the element's parent is removed and assigned to the current drop target, otherwise child elements would still move with their parent even if they have been dropped outside of it.
draggable() defines those elements that may be dragged around.
the classes applied to the dropped elements are just for demonstration purpose; elements that have been dropped on the #doc-container appear red, those dropped outside of it are green.
the position: absolute for dragged elements was necessary as otherwise elements would constantly move around whenever one element was moved. If you need several "documents" in your container, give each a fitting left: X00px; style
Update 1:
You may clone each element as soon as it leaves the parent container and when dragged back remove it using class checks and .clone() / .remove():
$('#doc-container').droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
cursor: 'move',
greedy: true,
drop: function(event, ui) {
if (ui.draggable.hasClass('out-of-box')) {
ui.draggable.remove();
} else {
$(ui.draggable).removeClass("out-of-box").addClass("in-box");
ui.draggable.detach().appendTo($(this));
}
}
});
$('#larger-drop-target').droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
cursor: 'move',
drop: function(event, ui) {
if (ui.draggable.hasClass("in-box")) {
var clone = ui.draggable.clone();
clone.removeClass("in-box").addClass("out-of-box");
clone.detach().appendTo($(this)).draggable({});
ui.draggable.draggable({
revert: true
});
}
}
});
Here is a Fiddle showing the changed version.
Related
I am trying to create a custom cursor on a website (a blurry yellow spot). I created a div in HTML for the custom cursor and styled it in CSS. I gave the 'cursor: none' property to the body tag to hide the default cursor. I also put 'pointer-events: none' on the custom cursor div. Still, click events are not (or hardly) working on buttons (for example I cannot close a pop-up window with the close button). When I remove 'cursor: none', everything works fine, but the default cursor returns beside the yellow spot. Could you please help me in solving this? How could I remove the default cursor without affecting click events? Thank you in advance.
// move yellow spot as cursor
const moveCursor = (e) => {
const mouseY = e.clientY;
const mouseX = e.clientX;
const yellowSpot = document.querySelector(".yellow-spot");
yellowSpot.style.transform = `translate3d(${mouseX}px, ${mouseY}px, 0)`;
}
window.addEventListener('mousemove', moveCursor);
document.querySelector("input[type=button]").addEventListener("click", () => {
console.log("Button clicked");
});
*,
body {
cursor: none !important;
}
.yellow-spot {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 1.625rem;
height: 1.625rem;
border-radius: 50%;
background: #ffeb77;
box-shadow: 0 0 15px 5px #ffeb77;
pointer-events: none;
}
<div class="yellow-spot"></div>
<input type="button" value="Click Me">
The issue is that the actual cursor is at the top-left of the yellow spot, not in the middle, so it's easy to miss things when trying to click on them. You can see that if you remove the cursor: none rule:
// move yellow spot as cursor
const moveCursor = (e) => {
const mouseY = e.clientY;
const mouseX = e.clientX;
const yellowSpot = document.querySelector(".yellow-spot");
yellowSpot.style.transform = `translate3d(${mouseX}px, ${mouseY}px, 0)`;
}
window.addEventListener('mousemove', moveCursor);
document.querySelector("input[type=button]").addEventListener("click", () => {
console.log("Button clicked");
});
*,
body {
/* cursor: none !important; */
}
.yellow-spot {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 1.625rem;
height: 1.625rem;
border-radius: 50%;
background: #ffeb77;
box-shadow: 0 0 15px 5px #ffeb77;
pointer-events: none;
}
<div class="yellow-spot"></div>
<input type="button" value="Click Me">
To fix it, center the yellow spot over the cursor rather than moving it to the top-left (I also changed how the yellow spot is moved, but that's not the important thing):
const yellowSpot = document.querySelector('.yellow-spot');
// move the yellow spot to the mouse position
document.addEventListener('mousemove', function(e) {
// Make sure the *center* of the yellow spot is where the
// cursor is, not the top left
const {clientWidth, clientHeight} = yellowSpot;
yellowSpot.style.left = ((e.pageX - (clientWidth / 2)) + 'px');
yellowSpot.style.top = (e.pageY - (clientHeight / 2)) + 'px';
});
*,
body {
cursor: none !important;
}
.yellow-spot {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 1.625rem;
height: 1.625rem;
border-radius: 50%;
background: #ffeb77;
box-shadow: 0 0 15px 5px #ffeb77;
pointer-events: none;
}
<div class="yellow-spot"></div>
<button onclick="alert('test')">Click me</button>
Here's a version with the cursor showing so you can see how it's centered in the yellow spot now:
const yellowSpot = document.querySelector('.yellow-spot');
// move the yellow spot to the mouse position
document.addEventListener('mousemove', function(e) {
// Make sure the *center* of the yellow spot is where the
// cursor is, not the top left
const {clientWidth, clientHeight} = yellowSpot;
yellowSpot.style.left = ((e.pageX - (clientWidth / 2)) + 'px');
yellowSpot.style.top = (e.pageY - (clientHeight / 2)) + 'px';
});
*,
body {
/*cursor: none !important;*/
}
.yellow-spot {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 1.625rem;
height: 1.625rem;
border-radius: 50%;
background: #ffeb77;
box-shadow: 0 0 15px 5px #ffeb77;
pointer-events: none;
}
<div class="yellow-spot"></div>
<button onclick="alert('test')">Click me</button>
I have to create a div triangle which has a border and I also can change the background color and also this needs to be draggable.
How do I do it?
I tried clip-path: polygon(50% 0, 0 100%, 100% 100%);
and also with before after pseudo element but here is not an actual border which can be a problem ... Anyone can help?:) thanks
here is the solution (without border):
html:
<div class="arrow-up" id="arrow-up"></div>
css:
.arrow-up {
width: 0;
height: 0;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 100px solid green;
position: absolute;
}
JavaScript:
//Make the DIV element draggagle:
dragElement(document.getElementById("arrow-up"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
elmnt.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
/* stop moving when mouse button is released:*/
document.onmouseup = null;
document.onmousemove = null;
}
}
Triangle with border:
html:
<div class="arrow-up" id="arrow-up">
<div class="inside-triangle"></div>
</div>
css:
.arrow-up {
width: 0;
height: 0;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 70px solid green;
position: absolute;
}
.inside-triangle {
left: -60px;
top: 6px;
width: 0;
height: 0;
border-left: 60px solid transparent;
border-right: 60px solid transparent;
border-bottom: 60px solid blue;
position: absolute;
}
JavaScript:
//Make the DIV element draggagle:
dragElement(document.getElementById("arrow-up"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
elmnt.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
/* stop moving when mouse button is released:*/
document.onmouseup = null;
document.onmousemove = null;
}
}
Here is an idea with skew transformation:
.tri {
width: 100px;
height: 100px;
border-right: 5px solid;
border-bottom: 5px solid;
position: relative;
overflow: hidden;
transform: skewX(25deg);
}
.tri::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: 0;
left:0;
border-left: 5px solid;
transform: skewX(-45deg);
transform-origin:bottom right;
background:red;
}
*,*::before {
box-sizing:border-box;
}
<div class="tri"></div>
Another idea with multiple background where the trick is to stack two triangle shapes:
.tri {
width: 100px;
height: 100px;
background:
/*top one*/
linear-gradient(to top right ,red 49.2%,transparent 50%) calc(100% - 5px) 7px/calc(50.2% - 5px) calc(100% - 2 * 5px),
linear-gradient(to top left ,red 49.2%,transparent 50%) 5px 7px/calc(50.2% - 5px) calc(100% - 2 * 5px),
/*bottom one*/
linear-gradient(to top left ,#000 49.2%,transparent 50%) left/50.2% 100%,
linear-gradient(to top right,#000 49.2%,transparent 50%) right/50.2% 100%;
background-repeat:no-repeat;
}
<div class="tri"></div>
You can add CSS variables for better control:
.tri {
--border-color:#000;
--back-color:red;
--border:5px;
--c1:var(--back-color) 49.2%,transparent 50%;
--c2:var(--border-color) 49.2%,transparent 50%;
width: 100px;
height: 100px;
background:
/*top one*/
linear-gradient(to top right, var(--c1)) calc(100% - var(--border)) calc(1.25*var(--border))/calc(50.2% - var(--border)) calc(100% - 2 * var(--border)),
linear-gradient(to top left ,var(--c1)) var(--border) calc(1.25*var(--border))/calc(50.2% - var(--border)) calc(100% - 2 * var(--border)),
/*bottom one*/
linear-gradient(to top left ,var(--c2)) left/50.2% 100%,
linear-gradient(to top right,var(--c2)) right/50.2% 100%;
background-repeat:no-repeat;
}
<div class="tri"></div>
<div class="tri" style="--border:10px;--border-color:green;"></div>
<div class="tri" style="--border:15px;--back-color:blue;"></div>
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>
I'm using the "5 ways to customize the Google Maps Infowindow"
( code here : https://codepen.io/Marnoto/pen/xboPmG )
When clicking for the first time on the marker, the window opens, but the arrow don't move to the left (this appens not all the time, but very often).
Starting the second click, it's positioning correctly, as written in the JS :
// Moves the arrow 76px to the left margin.
iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'left: 76px !important;'});
Here is a pic of the problem
capture
And here is a pic of how it works when the style property is correctly applied
capture 2
Is there a way to fix this ??
Thank you!
Edit : THIS IS THE CODE
HTML
<body>
<div id="map-canvas"/>
</body>
CSS
#map-canvas {
margin: 0;
padding: 0;
height: 400px;
max-width: none;
}
#map-canvas img {
max-width: none !important;
}
.gm-style-iw {
width: 350px !important;
top: 15px !important;
left: 0px !important;
background-color: #fff;
box-shadow: 0 1px 6px rgba(178, 178, 178, 0.6);
border: 1px solid rgba(72, 181, 233, 0.6);
border-radius: 2px 2px 10px 10px;
}
#iw-container {
margin-bottom: 10px;
}
#iw-container .iw-title {
font-family: 'Open Sans Condensed', sans-serif;
font-size: 22px;
font-weight: 400;
padding: 10px;
background-color: #48b5e9;
color: white;
margin: 0;
border-radius: 2px 2px 0 0;
}
#iw-container .iw-content {
font-size: 13px;
line-height: 18px;
font-weight: 400;
margin-right: 1px;
padding: 15px 5px 20px 15px;
max-height: 140px;
overflow-y: auto;
overflow-x: hidden;
}
.iw-content img {
float: right;
margin: 0 5px 5px 10px;
}
.iw-subTitle {
font-size: 16px;
font-weight: 700;
padding: 5px 0;
}
.iw-bottom-gradient {
position: absolute;
width: 326px;
height: 25px;
bottom: 10px;
right: 18px;
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
}
JAVASCRIPT
/*
* 5 ways to customize the Google Maps infowindow
* 2015 - en.marnoto.com
* http://en.marnoto.com/2014/09/5-formas-de-personalizar-infowindow.html
*/
// map center
var center = new google.maps.LatLng(40.589500, -8.683542);
// marker position
var factory = new google.maps.LatLng(40.589500, -8.683542);
function initialize() {
var mapOptions = {
center: center,
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);
// InfoWindow content
var content = '<div id="iw-container">' +
'<div class="iw-title">Porcelain Factory of Vista Alegre</div>' +
'<div class="iw-content">' +
'<div class="iw-subTitle">History</div>' +
'<img src="http://maps.marnoto.com/en/5wayscustomizeinfowindow/images/vistalegre.jpg" alt="Porcelain Factory of Vista Alegre" height="115" width="83">' +
'<p>Founded in 1824, the Porcelain Factory of Vista Alegre was the first industrial unit dedicated to porcelain production in Portugal. For the foundation and success of this risky industrial development was crucial the spirit of persistence of its founder, José Ferreira Pinto Basto. Leading figure in Portuguese society of the nineteenth century farm owner, daring dealer, wisely incorporated the liberal ideas of the century, having become "the first example of free enterprise" in Portugal.</p>' +
'<div class="iw-subTitle">Contacts</div>' +
'<p>VISTA ALEGRE ATLANTIS, SA<br>3830-292 Ílhavo - Portugal<br>'+
'<br>Phone. +351 234 320 600<br>e-mail: geral#vaa.pt<br>www: www.myvistaalegre.com</p>'+
'</div>' +
'<div class="iw-bottom-gradient"></div>' +
'</div>';
// A new Info Window is created and set content
var infowindow = new google.maps.InfoWindow({
content: content,
// Assign a maximum value for the width of the infowindow allows
// greater control over the various content elements
maxWidth: 350
});
// marker options
var marker = new google.maps.Marker({
position: factory,
map: map,
title:"Porcelain Factory of Vista Alegre"
});
// This event expects a click on a marker
// When this event is fired the Info Window is opened.
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
// Event that closes the Info Window with a click on the map
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// *
// START INFOWINDOW CUSTOMIZE.
// The google.maps.event.addListener() event expects
// the creation of the infowindow HTML structure 'domready'
// and before the opening of the infowindow, defined styles are applied.
// *
google.maps.event.addListener(infowindow, 'domready', function() {
// Reference to the DIV that wraps the bottom of infowindow
var iwOuter = $('.gm-style-iw');
/* Since this div is in a position prior to .gm-div style-iw.
* We use jQuery and create a iwBackground variable,
* and took advantage of the existing reference .gm-style-iw for the previous div with .prev().
*/
var iwBackground = iwOuter.prev();
// Removes background shadow DIV
iwBackground.children(':nth-child(2)').css({'display' : 'none'});
// Removes white background DIV
iwBackground.children(':nth-child(4)').css({'display' : 'none'});
// Moves the infowindow 115px to the right.
iwOuter.parent().parent().css({left: '115px'});
// Moves the shadow of the arrow 76px to the left margin.
iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'left: 76px !important;'});
// Moves the arrow 76px to the left margin.
iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'left: 76px !important;'});
// Changes the desired tail shadow color.
iwBackground.children(':nth-child(3)').find('div').children().css({'box-shadow': 'rgba(72, 181, 233, 0.6) 0px 1px 6px', 'z-index' : '1'});
// Reference to the div that groups the close button elements.
var iwCloseBtn = iwOuter.next();
// Apply the desired effect to the close button
iwCloseBtn.css({opacity: '1', right: '38px', top: '3px', border: '7px solid #48b5e9', 'border-radius': '13px', 'box-shadow': '0 0 5px #3990B9'});
// If the content of infowindow not exceed the set maximum height, then the gradient is removed.
if($('.iw-content').height() < 140){
$('.iw-bottom-gradient').css({display: 'none'});
}
// The API automatically applies 0.7 opacity to the button after the mouseout event. This function reverses this event to the desired value.
iwCloseBtn.mouseout(function(){
$(this).css({opacity: '1'});
});
});
}
google.maps.event.addDomListener(window, 'load', initialize);
try the pixelOffset for the infowindow
for example: I moved my whole infowindow to the right of the marker:
var infowindow = new google.maps.InfoWindow({
content: $marker.html(),
pixelOffset: new google.maps.Size(175, 114),
maxWidth: '290',
});
the pixelOffset equals half of my maxWidth and double the height of my marker icon
then I also changed this line:
// Moves the infowindow to the right.
iwOuter.parent().parent().css({left: '0px', top: '0px'});
so the top left corner will be aligned to the right of the marker icon and in the CSS:
.gm-style .gm-style-iw{
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
padding: 0 !important;
overflow: visible !important;
}
I also exchanged the arrow thingy - adding an additional div inside my marker-wrap, which has the following style:
.marker-arrow {
position: absolute;
left: -30px;
top: 0;
width: 30px;
background: transparent;
border-top: 12px solid transparent;
border-right: 20px solid #ffffff;
border-bottom: 12px solid transparent;
height: 24px;
}
in addition I changed the styles for the arrow, so it doesn't appear anywhere visibly:
// Moves the shadow of the arrow to the left.
iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'left: 0px !important; top: 0px !important;'});
// Moves the arrow to the left.
iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'left: 0px !important; top: 0px !important;'});
// Changes the desired tail shadow color.
iwBackground.children(':nth-child(3)').find('div').children().css({'box-shadow': 'unset', 'z-index' : '0', 'background' : 'transparent'});
hope that helps ;-)
jsFiddle
You'll notice the containment options for the draggable are [7, 0, 40, 0], though I feel they should be [0, 0, 32, 0]. If you click on the button so it is in the "ON" position and drag the <div> (circle slider thing) around, you will notice that it goes to far left and not far enough right. I can't figure out why this is the case. Here is a picture of the problem, it is very slight.
This is what I am going for when you drag it around:
Thanks!
HTML:
<section></section>
<div></div>
CSS:
section {
background-image: url(http://www.rsadler.com/OnOff_slider_small.png);
width: 57px;
height: 25px;
margin: 0;
padding: 0;
}
section:hover{
cursor: pointer;
}
section.ON {
background-position: 82px 0px;
}
div {
background-image: url(http://www.rsadler.com/OnOff_slider_small.png);
background-position: 26px 0px;
position: relative;
height: 24px;
width: 25px;
margin: -25px 0px 0px 0px;
padding: 0;
}
div:hover {
cursor: pointer;
}
JS:
$(document).ready(function(){
$('section').click(function(){
if ($(this).hasClass('ON')) {
$(this).removeClass('ON');
$(this).next().slideLeft();
} else {
$(this).addClass('ON');
$(this).next().slideRight();
}
});
$('div').click(function(){
if ($(this).prev().hasClass('ON')) {
$(this).slideLeft();
$(this).prev().removeClass('ON');
} else {
$(this).slideRight();
$(this).prev().addClass('ON');
}
});
$('div').draggable({
axis: 'x',
containment: [7, 0, 40, 0] // why do I have to put 7 as the x1 value? It should be 0
});
});
jQuery.fn.slideRight = function() {
var o = $(this[0])
o.animate({
'left': '32px'
}, 300);
};
jQuery.fn.slideLeft = function() {
var o = $(this[0])
o.animate({
'left': '0'
}, 300);
};