Image Comparison Slider Containers Won't Flex Wrap - javascript

Here's a link to my codepen: https://codepen.io/Bryandbronstein/pen/NLVQjB
So this is a strange issue and I'm at the end of my rope with this one. I've been learning a bit more about CSS and Javascript, and decided to try out an image comparison slider I found on W3C's website. It works perfectly as a single element, however I want to have a full gallery of these. Yet no matter what I try, they don't seem to want to obey any of the flex rules I set for their parent container. You'll notice in the codepen that one comparison container is hidden behind another. Any ideas?
function initComparisons() {
var x, i;
/*find all elements with an "overlay" class:*/
x = document.getElementsByClassName("img-comp-overlay");
for (i = 0; i < x.length; i++) {
/*once for each "overlay" element:
pass the "overlay" element as a parameter when executing the compareImages function:*/
compareImages(x[i]);
}
function compareImages(img) {
var slider, img, clicked = 0, w, h;
/*get the width and height of the img element*/
w = img.offsetWidth;
h = img.offsetHeight;
/*set the width of the img element to 50%:*/
img.style.width = (w / 2) + "px";
/*create slider:*/
slider = document.createElement("DIV");
slider.setAttribute("class", "img-comp-slider");
/*insert slider*/
img.parentElement.insertBefore(slider, img);
/*position the slider in the middle:*/
slider.style.top = (h / 2) - (slider.offsetHeight / 2) + "px";
slider.style.left = (w / 2) - (slider.offsetWidth / 2) + "px";
/*execute a function when the mouse button is pressed:*/
slider.addEventListener("mousedown", slideReady);
/*and another function when the mouse button is released:*/
window.addEventListener("mouseup", slideFinish);
/*or touched (for touch screens:*/
slider.addEventListener("touchstart", slideReady);
/*and released (for touch screens:*/
window.addEventListener("touchstop", slideFinish);
function slideReady(e) {
/*prevent any other actions that may occur when moving over the image:*/
e.preventDefault();
/*the slider is now clicked and ready to move:*/
clicked = 1;
slider.style.border = "0";
/*execute a function when the slider is moved:*/
window.addEventListener("mousemove", slideMove);
window.addEventListener("touchmove", slideMove);
}
function slideFinish() {
/*the slider is no longer clicked:*/
clicked = 0;
slider.style.border = "3px solid white";
}
function slideMove(e) {
var pos;
/*if the slider is no longer clicked, exit this function:*/
if (clicked == 0) return false;
/*get the cursor's x position:*/
pos = getCursorPos(e)
/*prevent the slider from being positioned outside the image:*/
if (pos < 0) pos = 0;
if (pos > w) pos = w;
/*execute a function that will resize the overlay image according to the cursor:*/
slide(pos);
}
function getCursorPos(e) {
var a, x = 0;
e = e || window.event;
/*get the x positions of the image:*/
a = img.getBoundingClientRect();
/*calculate the cursor's x coordinate, relative to the image:*/
x = e.pageX - a.left;
/*consider any page scrolling:*/
x = x - window.pageXOffset;
return x;
}
function slide(x) {
/*resize the image:*/
img.style.width = x + "px";
/*position the slider:*/
slider.style.left = img.offsetWidth - (slider.offsetWidth / 2) + "px";
}
}
}
html, body {
background-color: #333333;
margin: 0;
padding: 0;
}
* {box-sizing: border-box;}
.gallery_text {
color: white;
font-family: Abel, Helvetica, sans-serif;
font-size: 1.7rem;
text-align: center;
line-height: 1.8em;
}
.row{
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.img-comp-container{
position: relative;
flex: 50%;
}
.img-comp-overlay{
border-right: 2px solid rgba(51,51,51, .5) ;
}
.img-comp-img {
position: absolute;
width: auto;
height: auto;
overflow: hidden;
}
.img-comp-img img {
vertical-align: middle;
}
.img-comp-slider {
position: absolute;
z-index: 9;
cursor: ew-resize;
width: 40px;
height: 40px;
transform: rotate(136deg);
background-color: #333333;
opacity: .8;
border-radius: 10%;
border: 3px solid white;
}
<body onload="initComparisons();">
<div class="row">
<div class="img-comp-container" >
<div class="img-comp-img">
<img src="https://images.pexels.com/photos/162389/lost-places-old-decay-ruin-162389.jpeg?cs=srgb&dl=black-and-white-dark-building-162389.jpg&fm=jpg" width="500" height="450">
</div>
<div class="seperator"></div>
<div class="img-comp-img img-comp-overlay">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSslfAcWKXuMxBpzcJC5ZUyFqMOb2Jtd12x4kBUGG9mTe3KeMJz" width="500" height="450">
</div>
</div>
<div class="img-comp-container">
<div class="img-comp-img">
<img src="https://images.pexels.com/photos/162389/lost-places-old-decay-ruin-162389.jpeg?cs=srgb&dl=black-and-white-dark-building-162389.jpg&fm=jpg" width="500" height="450">
</div>
<div class="seperator"></div>
<div class="img-comp-img img-comp-overlay">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSslfAcWKXuMxBpzcJC5ZUyFqMOb2Jtd12x4kBUGG9mTe3KeMJz" width="500" height="450">
</div>
</div>
<div class="img-comp-container">
<div class="img-comp-img">
<img src="https://images.pexels.com/photos/162389/lost-places-old-decay-ruin-162389.jpeg?cs=srgb&dl=black-and-white-dark-building-162389.jpg&fm=jpg" width="500" height="450">
</div>
<div class="seperator"></div>
<div class="img-comp-img img-comp-overlay">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSslfAcWKXuMxBpzcJC5ZUyFqMOb2Jtd12x4kBUGG9mTe3KeMJz" width="500" height="450">
</div>
</div>
</div>
</body>

The images won't wrap because all children of .img-comp-container were absolutely positioned. This collapsed all the flex elements so that the flex wrap wouldn't work.
Either make one of more of the children of .img-comp-container relative or static, or set a width and height to .img-comp-container.
Here are the changes I made to the CSS:
.img-comp-container{
position: relative;
flex: 50%;
}
.img-comp-img {
position: relative;
width: auto;
height: auto;
overflow: hidden;
}
.img-comp-overlay {
border-right: 2px solid rgba(51, 51, 51, 0.5);
position: absolute;
top: 0;
left: 0;
}
See this codepen fork of your pen for a working solution.

Related

Keep mouse within a div which mouves if mouse toches inside border

I'm trying to build a sort of crosshair which is surrounded by a circle that zooms an image to shoot more precisely. The behavior I want is that crosshair which is also my mouse pointer can move inside of the circle and once it touches the edge of my circle from the inside it moves it to the wanted position. For now, I can only move my circle having crosshair fixed in the middle. Could you please help me to have it moving within my circle?
jQuery(document).ready(function() {
var onBoxX = 0, onBoxY = 0;
var circleWidth = 120;
var circleHeight = 120;
var circleBorderWidth = 1;
var boxWidth = 500;
var boxHeight = 500;
var circleLeft = 0;
var circleTop = 0;
$(box).mousemove(function(event){
// console.log(event);
onBoxX = event.clientX;
onBoxY = event.clientY;
circleLeft = (onBoxX - circleWidth / 2 - circleBorderWidth)/ boxWidth * 100
circleTop = (onBoxY - circleHeight / 2 - circleBorderWidth)/ boxWidth *100
$("#circle").css({left: circleLeft+'%', top: circleTop+'%'});
});
$(circle).mousemove(function(event){
console.log("circle mousemove",event.offsetX, event.offsetY);
});
})
body{
margin:0px;
padding:0px;
font-family: 'Roboto', sans-serif;
}
.box{
width:500px;
height:500px;
background:#000000;
position:relative;
cursor:crosshair;
overflow: hidden;
}
.circle {
position: relative;
background: black;
border: solid 1px #ccc;
width:120px;
height:120px;
border-radius: 50%;
}
.crosshair{
position: absolute;
background-color: white;
width:20px;
height:20px;
left:41.5%;
top:41.5%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="box" class="box">
<div id="circle" class="circle">
<div id="crosshair" class="crosshair"></div>
</div>
</div>
I refactored it a bit and added code to detect when cursor is outside of circle.
jQuery(document).ready(function () {
var cursorX = 0,
cursorY = 0;
var circleRadius = 60;
var circleX = 0;
var circleY = 0;
function updateCursorCoords(x, y) {
cursorX = x;
cursorY = y;
}
function updateCircleCoords() {
// First define if cursor is inside circle
var distX = Math.abs(circleX + circleRadius - cursorX);
var distY = Math.abs(circleY + circleRadius - cursorY);
var dist = Math.sqrt(Math.pow(distY, 2) + Math.pow(distX, 2));
var cursorIsInside = dist < circleRadius;
// And update its position only when cursor is outside of circle
if (!cursorIsInside) {
circleX = cursorX - circleRadius;
circleY = cursorY - circleRadius;
}
}
function drawCircle() {
$("#circle").css({ left: circleX + "px", top: circleY + "px" });
}
$(box).mousemove(function (event) {
updateCursorCoords(event.clientX, event.clientY);
updateCircleCoords();
drawCircle();
});
});
body {
margin:0px;
padding:0px;
font-family: 'Roboto', sans-serif;
}
.box {
width:500px;
height:500px;
background:#000000;
position:relative;
cursor:crosshair;
overflow: hidden;
}
.circle {
position: relative;
background: black;
border: solid 1px #ccc;
width:120px;
height:120px;
border-radius: 50%;
box-sizing: border-box;
}
.crosshair {
position: absolute;
background-color: white;
width:20px;
height:20px;
left:41.5%;
top:41.5%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="box" class="box">
<div id="circle" class="circle">
<div id="crosshair" class="crosshair"></div>
</div>
</div>

Is there any way to fit a slide Nav in splitter?

I am trying to fit a slide nav on the right side of the splitter, which is able to split when dragging the separator based on the width of the right side. https://jsfiddle.net/74bewsdu/
I tried modifying the width to auto as well as the z-index, it still doesn't work well.
index
<div class="splitter">
<div id="first">
<iframe src="{{ route('child') }}" style="width:100%; height:100%" frameBorder="0">
Your browser isn't compatible
</iframe>
</div>
<div id="separator"></div>
<div id="second">
<div id="mySidenav" class="sidenav"></div>
<div style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</div>
</div>
</div>
</div>
javascript
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
}
css
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
You could get the offsetWidth of the right side div (#second) plus the offsetWidth of the separator, and set the sliding nav width to that value. If you don't want to completely overlap the menu button, you could subtract it by the width of the menu button (or some arbitrary constant).
Example (see comments in lines between /* added */ and /* end added */ areas in the snippet below). Update: I also added code to check to see if the slider nav is open. Now, if you drag the slider when the side nav is open, it should be dynamically resized.
let navIsOpen = false; // variable to keep track of if the slider nav is open
function openNav() {
/* added */
// calculate width of right side div + separator
let width = second.offsetWidth + separator.offsetWidth;
// uncomment below line to subtract a value so the slider doesn't obscure the menu button/text
//width = width - 95;
document.getElementById("mySidenav").style.width = width + "px";
navIsOpen = true; // slider nav is open
/* end added */
}
// function is used for dragging and moving
function dragElement(element, direction) {
var md; // remember mouse down info
const first = document.getElementById("first");
const second = document.getElementById("second");
element.onmousedown = onMouseDown;
element.onmousedown = onMouseDown;
function onMouseDown(e) {
//console.log("mouse down: " + e.clientX);
md = {
e,
offsetLeft: element.offsetLeft,
offsetTop: element.offsetTop,
firstWidth: first.offsetWidth,
secondWidth: second.offsetWidth
};
first.style.pointerEvents = 'none';
document.onmousemove = onMouseMove;
document.onmouseup = () => {
//console.log("mouse up");
document.onmousemove = document.onmouseup = null;
}
}
function onMouseMove(e) {
//console.log("mouse move: " + e.clientX);
var delta = {
x: e.clientX - md.e.clientX,
y: e.clientY - md.e.clientY
};
if (direction === "H") // Horizontal
{
// prevent negative-sized elements
delta.x = Math.min(Math.max(delta.x, -md.firstWidth),
md.secondWidth);
element.style.left = md.offsetLeft + delta.x + "px";
first.style.width = (md.firstWidth + delta.x) + "px";
second.style.width = (md.secondWidth - delta.x) + "px";
}
/* added */
if (navIsOpen) { // check if slider nav is open, if so resize
openNav();
}
/* end added */
}
}
dragElement(document.getElementById("separator"), "H");
.splitter {
width: 100%;
height: 300px;
display: flex;
}
#separator {
cursor: col-resize;
background-color: #aaa;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='30'><path d='M2 0 v30 M5 0 v30 M8 0 v30' fill='none' stroke='black'/></svg>");
background-repeat: no-repeat;
background-position: center;
width: 10px;
height: 100%;
/* prevent browser's built-in drag from interfering */
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#first {
background-color: #dde;
width: 20%;
height: 100%;
min-width: 10px;
}
#second {
background-color: #eee;
width: 80%;
height: 100%;
min-width: 10px;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
<div class="splitter">
<div id="first">
<iframe src="{{ route('child') }}" style="width:100%; height:100%" frameBorder="0">
Your browser isn't compatible
</iframe>
</div>
<div id="separator"></div>
<div id="second">
<div id="mySidenav" class="sidenav"></div>
<div style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</div>
</div>
</div>

Custom cursors in HTML

I'm creating a custom cursor for a site. I've gotten two divs centered to the cursor when the mouse moves but when I hover on an anchor tag the position of the background cursor is off. I've tried using pageX and pageY to center it in the for loop but it doesn't seem to work. Help?
Here is my HTML:
<div class="cursor"></div>
<div class="cursor-bg"></div>
CSS:
.cursor{
height:10px;
width:10px;
border-radius:50%;
position:absolute;
background: #fff;
z-index: 100;
}
.cursor-bg{
height:30px;
:30px;
border-radius:50%;
position:absolute;
background: $lightCursor-bg;
transition-duration: 400ms;
transition-timing-function: ease-out;
}
.expand{
width: 100px;
height: 100px;
position: absolute;
border:solid 1px #fff;
background: rgba(255,255,255, 0);
}
JS:
(function(){
var cursor = document.querySelector('.cursor');
var cursorBg = document.querySelector('.cursor-bg');
var navLinks = document.querySelectorAll('a');
document.addEventListener('mousemove', e => {
cursor.style.left = (e.pageX - 5) + 'px';
cursor.style.top = (e.pageY - 5) + 'px';
cursorBg.style.left = (e.pageX - 15) + 'px';
cursorBg.style.top = (e.pageY -15) + 'px';
});
for (var i = 0; i < navLinks.length; i++) {
var singleLink = navLinks[i];
singleLink.addEventListener('mouseover', e => {
cursorBg.classList.add("expand");
cursorBg.style.left = (e.pageX - 50) + 'px';
cursorBg.style.left = (e.pageY - 50) + 'px';
})
singleLink.addEventListener('mouseout', e => {
cursorBg.classList.remove("expand");
})
}
})();
You can use the css cursor property for this:
cursor: url(https://example.com/your-image.png), auto
Demo:
div {
width: 200px;
height: 200px;
background: dodgerblue;
padding: 10px;
}
.custom-cursor {
background: red;
cursor: url('https://i.imgur.com/ng6jKDk.png'), auto
}
p {
font-family: sans-serif;
text-align: center;
font-size: 36px;
}
<div class="custom-cursor">
<p>Custom Cursor in this div only!</p>
</div>
<div>
<p>Not in this div!</p>
</div>
If you want the cursor to apply to the entire page, just add the css to the body.
CSS cursor property

In css, How do you display an image that is hidden when you hover over a visibe image?

I have to make an image appear in the right hand corner over the mouse image once my mouse cursor reaches the piece of cheese showing on the screen. I have the code for the image to appear over the mouse image, which I used display: none to hide. What should I do to make the image appear over the mouse image, once I have reached the piece of cheese in the top left corner with the cursor? I think I should be able to use the hover property, but I am not sure how to achieve my goal with it. Any tips or suggestions would be appreciated.
<style>
#myCanvas { border: #333 10px solid;
position: relative;
}
body { padding: 50px; }
#cheese { position: absolute;
padding-left: 10px;
}
#mouse { position: absolute;
padding-top: 390px;
padding-left: 520px;
}
#line { position: absolute;
padding-left: 90px;
padding-top: 90px;
}
#text1 { position: absolute;
padding-top: 450px;
padding-left: 130px;
}
#text2 { position: absolute;
padding-top: 500px;
padding-left: 110px;
}
#img { position: absolute;
display: none;
padding-top: 390px;
padding-left: 525px;
}
</style>
<body>
<p>
<div id="cheese">
<img src="cheese 2.jpg" alt="cheese" width="120" height="120">
</div>
</p>
<div id="mouse">
<img src="ballet mouse.jpg" alt="Angelina Ballerina" width="190" height="220">
</div>
<div id="line">
<img src="316151-200.png" alt="Pathway" width="480" height="350">
</div>
<div id="text1">
<img src="help.png" alt="text" width="350" height="50">
</div>
<div id="text2">
<img src="find.png" alt="text" width="400" height="55">
</div>
<div id="img">
<a href="#"><img src="MouseEventImg.jpg" alt="Celebrate!" width="190" height="220">
</div>
<canvas id="myCanvas" width="700px" height="600px"></canvas>
<script>
var canvas = document.querySelector("#myCanvas");
var context = canvas.getContext("2d");
var canvasPos = getPosition(canvas);
var mouseX = 670;
var mouseY = 570;
canvas.addEventListener("mousemove", setMousePosition, false);
function setMousePosition(e) {
mouseX = e.clientX - canvasPos.x;
mouseY = e.clientY - canvasPos.y;
}
function update() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(mouseX, mouseY, 30, 0, 2 * Math.PI, true);
context.fillStyle = "#eab4e4";
context.fill();
requestAnimationFrame(update);
}
update();
//make mouse position values accurate
function getPosition(el) {
var xPos = 0;
var yPos = 0;
while (el) {
if (el.tagName == "BODY") {
//deal with browser quirks with body/window/document and pg scroll
var xScroll = el.scrollLeft || document.documentElement.scrollLeft;
var yScroll = el.scrollTop || document.documentElement.scrollTop;
xPos += (el.offsetLeft - xScroll + el.clientLeft);
yPos += (el.offsetTop - yScroll + el.clientTop);
} else {
//for all other non-BODY elements
xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft);
yPos += (el.offsetTop - el.scrollTop + el.clientTop);
}
el = el.offsetParent;
}
return {
x: xPos,
y: yPos
};
}
</script>
</body>
If I understand your issue correctly, this is a simple way to achieve this:
Make some container with cheese:
<div class='something'>
<div class='some-cheese'></div>
</div>
If you hover over that container, show the cheese:
.something {
width: 100px;
height: 100px;
background: #000;
}
.something .some-cheese {
width: 50px;
height: 50px;
background: #FF0;
opacity: 0;
transition: opacity 1s;
}
.something:hover .some-cheese {
opacity: 1;
}

change mouse trail script

I found this cool Codepen Mouse Trail script. How can I change it that it only works inside a div, and that it uses an image (of a cursor) instead the css-code (like it is 1996)? Tnx!
https://codepen.io/tomhodgins/pen/bgRVKL
var coord = new Array(50)
function update(e){
var x = e.clientX || e.touches[0].clientX
var y = e.clientY || e.touches[0].clientY
coord.push([x,y])
coord.shift()
EQCSS.apply()
}
document.addEventListener('mousemove',update)
document.addEventListener('touchmove',update)
#element '[data-dot]' {
$root, $this {
cursor: none;
}
$this {
width: 30px;
height: 30px;
background: white;
border: 2px solid black;
border-radius: 100%;
border-top-left-radius: 0;
position: fixed;
left: eval("coord[50-(getAttribute('data-dot')*5)][0]")px;
top: eval("coord[50-(getAttribute('data-dot')*5)][1]")px;
opacity: calc(eval("10 - getAttribute('data-dot')") / 10);
}
}
<aside data-cursor>
<div data-dot=10></div>
<div data-dot=9></div>
<div data-dot=8></div>
<div data-dot=7></div>
<div data-dot=6></div>
<div data-dot=5></div>
<div data-dot=4></div>
<div data-dot=3></div>
<div data-dot=2></div>
<div data-dot=1></div>
</aside>

Categories