I am new to css and html and I do not know much about javascript. I found this js code on code pen, it works fine except on touchscreen. how do I get the contents of my div to scroll on touchscreen? Probably adding some code in the script to detect the touchsreen and disable the mousemove and replace the overflow: hidden with overflow-x: auto but I have no idea how to do this.
Thank you
$(function() {
$(window).load(function() {
var $gal = $("#scrolling-wrapper"),
galW = $gal.outerWidth(true),
galSW = $gal[0].scrollWidth,
wDiff = (galSW / galW) - 1, // widths difference ratio
mPadd = 60, // mousemove Padding
damp = 20, // Mmusemove response softness
mX = 0, // real mouse position
mX2 = 0, // modified mouse position
posX = 0,
mmAA = galW - (mPadd * 2), // the mousemove available area
mmAAr = (galW / mmAA); // get available mousemove didderence ratio
$gal.mousemove(function(e) {
mX = e.pageX - $(this).parent().offset().left - this.offsetLeft;
mX2 = Math.min(Math.max(0, mX - mPadd), mmAA) * mmAAr;
});
setInterval(function() {
posX += (mX2 - posX) / damp; // zeno's paradox equation "catching delay"
$gal.scrollLeft(posX * wDiff);
}, 10);
});
});
#scrolling-wrapper {
white-space: nowrap;
max-width: 960px;
height: 425px;
overflow: hidden;
}
#musees {
background-image: url('https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_BG.jpg');
width: 2600px;
height: 425px;
}
.muse1 {
left: 55px;
top: 90px;
}
.muse2 {
left: 340px;
top: -15px;
}
.muse3 {
left: 575px;
top: 75px;
}
.muse4 {
left: 750px;
top: 20px;
}
.muse5 {
left: 1175px;
top: 75px;
}
.muse6 {
left: 1510px;
top: 75px;
}
.muse7 {
left: 1640px;
top: 15px;
}
.muse8 {
left: 1885px;
top: 55px;
}
.muse9 {
left: 2155px;
top: 55px;
}
/* A wrapper for your images to transition */
.transition-wrapper {
position: relative;
display: inline-block
}
/* Position each image and apply a transition */
.transition-wrapper img {
position: absolute;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
/* Automatically hide an image during hover (to reveal the other one) */
.transition-wrapper img:last-of-type:hover {
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="scrolling-wrapper">
<div id="musees">
<a class="transition-wrapper muse1" href="SallesID.php?Type_No=33&ID_Article=5&SalleID=1">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle01Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle01.png">
</a>
<a class="transition-wrapper muse2" href="SallesID.php?Type_No=33&ID_Article=6&SalleID=2">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle02Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle02.png">
</a>
<a class="transition-wrapper muse3" href="SallesID.php?Type_No=33&ID_Article=7&SalleID=3">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle03Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle03.png">
</a>
<a class="transition-wrapper muse4" href="SallesID.php?Type_No=33&ID_Article=8&SalleID=4">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/images/ExpoVirtuel_Salle04Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle04.png">
</a>
<a class="transition-wrapper muse5" href="SallesID.php?Type_No=33&ID_Article=14&SalleID=5">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle05Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle05.png">
</a>
<a class="transition-wrapper muse6" href="SallesID.php?Type_No=33&ID_Article=15&SalleID=6">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle06Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle06.png">
</a>
<a class="transition-wrapper muse7" href="SallesID.php?Type_No=33&ID_Article=16&SalleID=7">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle07Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle07.png">
</a>
<a class="transition-wrapper muse8" href="SallesID.php?Type_No=33&ID_Article=22&SalleID=8">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle08Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle08.png">
</a>
<a class="transition-wrapper muse9" href="SallesID.php?Type_No=33&ID_Article=98&SalleID=28">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle09Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle09.png">
</a>
</div>
</div>
<script src="js/script.js"></script>
You need a similar event to the one you sense here:
$gal.mousemove(function(e) {
mX = e.pageX - $(this).parent().offset().left - this.offsetLeft;
mX2 = Math.min(Math.max(0, mX - mPadd), mmAA) * mmAAr;
});
but things are a little different on a touch screen - largely because humans have several fingers and the touch events need to be able to tell you how many are on the screen. You are only interested in the user moving along the gallery so the first setting in the touchmove event will be the one you are interested in.
e.touches[0].clientX
I am not very familiar with jQuery and can't see that it has a touchmove method in the same way that it has a mousemove, so here is a suggestion using addEventListener. The snippet is working for me on an iPad IOS 14.
$(function() {
$(window).load(function() {
var $gal = $("#scrolling-wrapper"),
galW = $gal.outerWidth(true),
galSW = $gal[0].scrollWidth,
wDiff = (galSW / galW) - 1, // widths difference ratio
mPadd = 60, // mousemove Padding
damp = 20, // Mmusemove response softness
mX = 0, // real mouse position
mX2 = 0, // modified mouse position
posX = 0,
mmAA = galW - (mPadd * 2), // the mousemove available area
mmAAr = (galW / mmAA); // get available mousemove didderence ratio
$gal.mousemove(function(e) {
mX = e.pageX - $(this).parent().offset().left - this.offsetLeft;
mX2 = Math.min(Math.max(0, mX - mPadd), mmAA) * mmAAr;
});
document.getElementById('scrolling-wrapper').addEventListener('touchmove',(function(e) {
mX = e.touches[0].clientX - $(this).parent().offset().left - this.offsetLeft;
mX2 = Math.min(Math.max(0, mX - mPadd), mmAA) * mmAAr;
}));
setInterval(function() {
posX += (mX2 - posX) / damp; // zeno's paradox equation "catching delay"
$gal.scrollLeft(posX * wDiff);
}, 10);
});
});
#scrolling-wrapper {
white-space: nowrap;
max-width: 960px;
height: 425px;
overflow: hidden;
}
#musees {
background-image: url('https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_BG.jpg');
width: 2600px;
height: 425px;
}
.muse1 {
left: 55px;
top: 90px;
}
.muse2 {
left: 340px;
top: -15px;
}
.muse3 {
left: 575px;
top: 75px;
}
.muse4 {
left: 750px;
top: 20px;
}
.muse5 {
left: 1175px;
top: 75px;
}
.muse6 {
left: 1510px;
top: 75px;
}
.muse7 {
left: 1640px;
top: 15px;
}
.muse8 {
left: 1885px;
top: 55px;
}
.muse9 {
left: 2155px;
top: 55px;
}
/* A wrapper for your images to transition */
.transition-wrapper {
position: relative;
display: inline-block
}
/* Position each image and apply a transition */
.transition-wrapper img {
position: absolute;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
/* Automatically hide an image during hover (to reveal the other one) */
.transition-wrapper img:last-of-type:hover {
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="scrolling-wrapper">
<div id="musees">
<a class="transition-wrapper muse1" href="SallesID.php?Type_No=33&ID_Article=5&SalleID=1">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle01Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle01.png">
</a>
<a class="transition-wrapper muse2" href="SallesID.php?Type_No=33&ID_Article=6&SalleID=2">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle02Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle02.png">
</a>
<a class="transition-wrapper muse3" href="SallesID.php?Type_No=33&ID_Article=7&SalleID=3">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle03Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle03.png">
</a>
<a class="transition-wrapper muse4" href="SallesID.php?Type_No=33&ID_Article=8&SalleID=4">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/images/ExpoVirtuel_Salle04Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle04.png">
</a>
<a class="transition-wrapper muse5" href="SallesID.php?Type_No=33&ID_Article=14&SalleID=5">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle05Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle05.png">
</a>
<a class="transition-wrapper muse6" href="SallesID.php?Type_No=33&ID_Article=15&SalleID=6">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle06Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle06.png">
</a>
<a class="transition-wrapper muse7" href="SallesID.php?Type_No=33&ID_Article=16&SalleID=7">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle07Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle07.png">
</a>
<a class="transition-wrapper muse8" href="SallesID.php?Type_No=33&ID_Article=22&SalleID=8">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle08Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle08.png">
</a>
<a class="transition-wrapper muse9" href="SallesID.php?Type_No=33&ID_Article=98&SalleID=28">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle09Glow.png">
<img src="https://www.pd6r.com/_DEV_charlesdaudelin/musees_test/images/ExpoVirtuel_Salle09.png">
</a>
</div>
</div>
<script src="js/script.js"></script>
Related
I am making a vanilla js carousel. I have laid out basic previous and next functionality using js along with html and css.
Now I tried to use css-animations (keyframes) to do left and right slide-in/slide-out animations but the code became messy for me. So here I am asking that what minimal changes would be needed to get the same animation effects in this implementation ?
Will you go for pure JS based or pure CSS based or a mix to do the same ?
My goal is get proper animation with minimal code.
(function () {
let visibleIndex = 0;
let carousalImages = document.querySelectorAll(".carousal__image");
let totalImages = [...carousalImages].length;
function makeNextVisible() {
visibleIndex++;
if (visibleIndex > totalImages - 1) {
visibleIndex = 0;
}
resetVisible();
renderVisible();
}
function makePrevVisible() {
visibleIndex--;
if (visibleIndex < 0) {
visibleIndex = totalImages - 1;
}
resetVisible();
renderVisible();
}
function resetVisible() {
for (let index = 0; index < totalImages; index++) {
carousalImages[index].className = "carousal__image";
}
}
function renderVisible() {
carousalImages[visibleIndex].className = "carousal__image--visible";
}
function renderCarousel({ autoplay = false, autoplayTime = 1000 } = {}) {
if (autoplay) {
[...document.querySelectorAll("button")].forEach(
(btn) => (btn.style.display = "none")
);
setInterval(() => {
makeNextVisible();
}, autoplayTime);
} else renderVisible();
}
renderCarousel();
// Add {autoplay:true} as argument to above to autplay the carousel.
this.makeNextVisible = makeNextVisible;
this.makePrevVisible = makePrevVisible;
})();
.carousal {
display: flex;
align-items: center;
}
.carousal__wrapper {
width: 500px;
height: 400px;
}
.carousal__images {
display: flex;
overflow: hidden;
list-style-type: none;
padding: 0;
}
.carousal__image--visible {
position: relative;
}
.carousal__image {
display: none;
}
<div class='carousal'>
<div class='carousal__left'>
<button onclick='makePrevVisible()'>Left</button>
</div>
<section class='carousal__wrapper'>
<ul class='carousal__images'>
<li class='carousal__image'>
<img src='https://fastly.syfy.com/sites/syfy/files/styles/1200x680/public/2018/03/dragon-ball-super-goku-ultra-instinct-mastered-01.jpg?offset-x=0&offset-y=0' alt='UI Goku' / width='500' height='400'/>
</li>
<li class='carousal__image'>
<img src='https://www.theburnin.com/wp-content/uploads/2019/01/super-broly-3.png' alt='Broly Legendary' width='500' height='400'/>
</li>
<li class='carousal__image'>
<img src='https://lh3.googleusercontent.com/proxy/xjEVDYoZy8-CTtPZGsQCq2PW7I-1YM5_S5GPrAdlYL2i4SBoZC-zgtg2r3MqH85BubDZuR3AAW4Gp6Ue-B-T2Z1FkKW99SPHwAce5Q_unUpwtm4' alt='Vegeta Base' width='500' height='400'/>
</li>
<li class='carousal__image'>
<img src='https://am21.mediaite.com/tms/cnt/uploads/2018/09/GohanSS2.jpg' alt='Gohan SS2' width='500' height='400'/>
</li>
</ul>
</section>
<div class='carousal__right'>
<button onclick='makeNextVisible()'>Right</button>
</div>
</div>
Updated codepen with feedback from the below answers and minor additional functionalities = https://codepen.io/lapstjup/pen/RwoRWVe
I think the trick is pretty simple. ;)
You should not move one or two images at the same time. Instead you should move ALL images at once.
Let's start with the CSS:
.carousal {
position: relative;
display: block;
}
.carousal__wrapper {
width: 500px;
height: 400px;
position: relative;
display: block;
overflow: hidden;
margin: 0;
padding: 0;
}
.carousal__wrapper,
.carousal__images {
transform: translate3d(0, 0, 0);
}
.carousal__images {
position: relative;
top: 0;
left: 0;
display: block;
margin-left: auto;
margin-right: auto;
}
.carousal__image {
float: left;
height: 100%;
min-height: 1px;
}
2nd step would be to calculate the maximum width for .carousal__images. For example in your case 4 * 500px makes 2000px. This value must be added to your carousal__images as part of the style attribute style="width: 2000px".
3rd step would be to calculate the next animation point and using transform: translate3d. We start at 0 and want the next slide which means that we have slide to the left. We also know the width of one slide. So the result would be -500px which also has to be added the style attribute of carousal__images => style="width: 2000px; transform: translate3d(-500px, 0px, 0px);"
That's it.
Link to my CodePen: Codepen for Basic Carousel with Autoplay
Try this. First stack all the images next to each other in a div and only show a single image at a time by setting overflow property to hidden for the div. Next, add event listeners to the buttons. When a bottom is clicked, the div containing the images is translated by -{size of an image} * {image number} on the x axis. For smooth animation, add transition: all 0.5s ease-in-out; to the div.
When someone clicks left arrow on the first image, the slide should display the last image. So for that counter is set to {number of images} - 1 and image is translated to left size * counter px.
For every click on the right arrow, the counter is incremented by 1 and slide is moved left. For every click on the left arrow, the counter is decremented by 1.
Slide.style.transform = "translateX(" + (-size * counter) + "px)"; this is the condition which is deciding how much the slide should be translated.
const PreviousButton = document.querySelector(".Previous-Button");
const NextButton = document.querySelector(".Next-Button");
const Images = document.querySelectorAll("img");
const Slide = document.querySelector(".Images");
const size = Slide.clientWidth;
var counter = 0;
// Arrow Click Events
PreviousButton.addEventListener("click", Previous);
NextButton.addEventListener("click", Next);
function Previous() {
counter--;
if (counter < 0) {
counter = Images.length - 1;
}
Slide.style.transform = "translateX(" + (-size * counter) + "px)";
}
function Next() {
counter++;
if (counter >= Images.length) {
counter = 0;
}
Slide.style.transform = "translateX(" + (-size * counter) + "px)";
}
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
.Container {
width: 60%;
margin: 0px auto;
margin-top: 90px;
overflow: hidden;
position: relative;
}
.Container .Images img {
width: 100%;
}
.Images {
transition: all 0.5s ease-in-out;
}
.Container .Previous-Button {
position: absolute;
background: transparent;
border: 0px;
outline: 0px;
top: 50%;
left: 20px;
transform: translateY(-50%);
filter: invert(80%);
z-index: 1;
}
.Container .Next-Button {
position: absolute;
background: transparent;
border: 0px;
outline: 0px;
top: 50%;
right: 20px;
transform: translateY(-50%);
filter: invert(80%);
z-index: 1;
}
.Container .Images {
display: flex;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://fonts.googleapis.com/css2?family=Cabin&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<title>Carousel</title>
</head>
<body>
<div class="Container">
<button class="Previous-Button">
<svg style = "transform: rotate(180deg);" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8.122 24l-4.122-4 8-8-8-8 4.122-4 11.878 12z"/></svg>
</button>
<button class="Next-Button">
<svg xmlns="http://www.w3.org/2000/svg" width = "24" height = "24" viewBox = "0 0 24 24"><path d="M8.122 24l-4.122-4 8-8-8-8 4.122-4 11.878 12z"/></svg>
</button>
<div class="Images">
<img src="https://source.unsplash.com/1280x720/?nature">
<img src="https://source.unsplash.com/1280x720/?water">
<img src="https://source.unsplash.com/1280x720/?rock">
<img src="https://source.unsplash.com/1280x720/?abstract">
<img src="https://source.unsplash.com/1280x720/?nature">
<img src="https://source.unsplash.com/1280x720/?trees">
<img src="https://source.unsplash.com/1280x720/?human">
<img src="https://source.unsplash.com/1280x720/?tech">
</div>
</div>
<script src="main.js"></script>
</body>
</html>
I'm trying to get the following effect:
Have a few bootstrap 4 cards displayed as a grid
When clicking on a button from inside a card, it should animate as follows:
rotate 180 degrees, get to a specific height/width (from 400px - 350px to entire screen) and position itself in the center of the screen.
For now, I know how to get the rotation with
rotateY(180deg)
when I click on a button:
$('#enlarge').on('click',
function() {
$('#kidCard').toggleClass("flipper");
});
having that rotation set in the flipper class, but I'm not able to get the rest of my desired animation.
Can someone help me with this?
Update:
My current html:
<div class="flip-container">
<div class="card text-white bg-primary mb-3 kid-card" id="kidCard">
<div class="card-header">
Child name: ...
<i class="fa fa-trash-o" aria-hidden="true" style="cursor: pointer"></i>
</div>
<div class="card-body kid-card-content">
<div class="kid-card-content-image">
<img src="~/Content/download.png" width="110" height="110"/>
</div>
<div class="kid-card-content-description">
<p class="card-text">
Age: ...
</p>
<p class="card-text">
Gender: ...
</p>
<p class="card-text">
Height: ...
</p>
<p class="card-text">
Weight: ...
</p>
</div>
</div>
<div class="card-footer">
<button class="btn btn-secondary" id="enlarge">Edit</button>
</div>
</div>
</div>
having js file:
$('#enlarge').on('click',
function() {
$('#kidCard').toggleClass("flipper");
});
and for now, this is my css file:
.flip-container .flipper {
transform: rotateY(180deg);
}
.flipper {
transition: 2s;
transform-style: preserve-3d;
position: relative;
}
In the transform I also tried translateY(calc(50vh - 50%)) translateX(calc(50vh - 50%)) in order to position it in the center of the screen, but it doesn't work.
SOLUTION:
I finally got it working with the following code (thank you all for contributing):
.js file:
$.fn.toggleZindex= function() {
const $this = $(this);
if($this.css("z-index")=="auto") {
$this.css("z-index", "99999");
}else {
$this.css("z-index", "auto");
}
return this;
};
$.fn.animateRotate = function(angle, duration, easing, startingDegree, complete) {
var args = $.speed(duration, easing, complete);
var step = args.step;
return this.each(function(i, e) {
args.complete = $.proxy(args.complete, e);
args.step = function(now) {
$.style(e, 'transform', 'rotateY(' + now + 'deg)');
if (step) return step.apply(e, arguments);
};
$({ deg: startingDegree}).animate({deg: angle}, args);
});
};
function getRotationDegrees(obj) {
const matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
if(matrix !== 'none') {
const values = matrix.split('(')[1].split(')')[0].split(',');
const a = values[0];
const b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));
} else { var angle = 0; }
return (angle < 0) ? angle + 360 : angle;
}
$('.editChildButton').on('click',
function () {
const idOfChild = $(this).attr('ChildId');
const tc = $(window).height() / 2 - $('.item').height() / 2 - $(this.closest('.item')).offset().top;
const lc = $(window).width() / 2 - $('.item').width() / 2 - $(this.closest('.item')).offset().left;
$(this.closest('.item')).toggleZindex();
const startingDegree = getRotationDegrees($(this.closest('.item')));
$(this.closest('.item')).animateRotate(startingDegree == 0 ? 180 : 0, 2000, 'swing', startingDegree);
$(this.closest('.item')).animate({
left: lc,
top: tc
}, 2000, function () {
$(this.closest('.item')).css({ position: 'fixed', left: $(this.closest('.item')).offset().left, top: $(this.closest('.item')).offset().top });
$(this.closest('.item')).animate({
left: 0,
top: 0,
width: '100vw',
height: '100vh'
},2000);
});
});
I don't know your specific situation but if you could find a way to use position: absolute, it would make it a lot easier when moving the cards around.
When positioning a div in the center of the screen, the important thing is to know how wide and high your element is at the moment of the transition. If your use case allows you to set those dimensions manually then you are set, you simply use:
left: calc(50% - manuallySetWidth);
top: calc(50% - manuallySetHeight);
but if you cannot manually set them then you need to find a alternate mechanism. To be honest, the variant I'm proposing here is something that uses a somewhat new addition to CSS (which is why it's very likely there are other simpler solutions for this) and here is apost that helped me getting started with those.
I commented the code to explain the proceedings
HIH
//set these vars to use them in css
$('#kidCard')[0].style.setProperty('--width', $('#kidCard').width()+'px');
$('#kidCard')[0].style.setProperty('--height', $('#kidCard').height()+'px');
$('#enlarge').on('click',
function() {
$('#kidCard').toggleClass("flipper");
$('body').toggleClass("shady");
});
body{
transition: 1s;
}
body.shady{
background: rgba(0,0,0,.8);
}
.flip-container .card {
left: 0;/*manually set each card's left and top in order for the translation to work smoothly, */
top: 0;/*if you have them in a grid you could use i and j to do this */
text-align: center;
border: 1px solid red;
transition: 1s;
position: absolute;
background: white;
}
.flip-container .card.flipper {
transform: rotateY(360deg);
left: calc(50% - var(--width)/2); /*use the variables set in js*/
top: calc(50% - var(--height)/2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flip-container">
<div class="card text-white bg-primary mb-3 kid-card" id="kidCard">
<div class="card-header">
Child name: ...
<i class="fa fa-trash-o" aria-hidden="true" style="cursor: pointer"></i>
</div>
<div class="card-body kid-card-content">
<div class="kid-card-content-image">
<img src="~/Content/download.png" width="110" height="110"/>
</div>
<div class="kid-card-content-description">
<p class="card-text">
Age: ...
</p>
<p class="card-text">
Gender: ...
</p>
<p class="card-text">
Height: ...
</p>
<p class="card-text">
Weight: ...
</p>
</div>
</div>
<div class="card-footer">
<button class="btn btn-secondary" id="enlarge">Edit</button>
</div>
</div>
</div>
In my opinion, to achieve such effect, CSS animations are not enough. The easiest way would be to change positioning to fixed, put card on middle and scale it as you want. Take a look on a DEMO.
Of course it is just example, for just one card, but it should work with multiple cards in various positions. On click card:
rotates 180deg (though I don't understand why 180),
move to center of viewport,
change size to fill all viewport,
animation works both ways.
HTML:
<div class="flip-container">
<div class="card text-white bg-primary mb-3 kid-card" id="kidCard">
<div class="card-header">
Child name: ...
<i class="fa fa-trash-o" aria-hidden="true" style="cursor: pointer"></i>
</div>
<div class="card-body kid-card-content">
<div class="kid-card-content-image">
<img src="~/Content/download.png" width="110" height="110"/>
</div>
<div class="kid-card-content-description">
<p class="card-text">
Age: ...
</p>
<p class="card-text">
Gender: ...
</p>
<p class="card-text">
Height: ...
</p>
<p class="card-text">
Weight: ...
</p>
</div>
</div>
<div class="card-footer">
<button class="btn btn-secondary" id="enlarge">Edit</button>
</div>
</div>
</div>
CSS:
.flip-container {
width: 400px;
}
.flip-container .flipper {
transform: rotateY(180deg);
}
.card {
transition-duration: 2s;
}
.movement {
transform: translate(-50%,-50%) rotateY(180deg);
}
JS:
var element = $('#kidCard');
var w = element.width();
var h = element.height();
$('#enlarge').on('click',
function() {
if(element.hasClass('movement')) {
element.removeClass('movement');
element.css({width: w, height: h, top: 0, left: 0});
} else {
var left = element.offset().left;
var top = element.offset().top;
element.css({position: 'fixed', left: left, top: top, width: w, height: h});
element.addClass('movement');
element.css({width: '100vw', height: '100vh', top: '50%', left: '50%'});
}
});
One possible way to do this is to set a width on your flipper class, then set the margins to auto. Setting a width value and margin:auto will center a block level element.
.flip-container .flipper {
transform: rotateY(180deg);
}
.flipper {
transition: 2s;
margin: auto;
width:400px;
height:400px;
transform-style: preserve-3d;
position: relative;
}
Here is a fiddle
Or if you would prefer a flex box solution something like this works:
.flip-container .flipper {
transform: rotateY(180deg);
}
.flipper {
transition: 2s;
transform-style: preserve-3d;
position: relative;
width:400px;
height:400px;
}
.body-flipper {
display:flex;
justify-content: center;
}
body, html{
width:100% !important;
height: 100% !important;
margin:0;
}
Here is a fiddle
If this is a duplicate apologies I could not find an answer.
I am making a Pure Javascript Slideshow and have nearly done it. However I am facing an issue i cannot seem to resolve.
I cannot get the images to fill the div with 100% width and 100% height. Which once done should slide all images separately, ultimately finishing my slideshow.
Steps taken to resolve:
I have played with the CSS, and changed the position styles between relative and absolute. I have added width:100%; to the divs. I have added in an extra style for the images - #slide li img {width:100%; height:100%}; Yet nothing seems to work. If #slide li img & #slide li & #slide all have width/height at 100% then the first image scales to 100% of the combined images width and height set in the Javascript, Which blows it way out of proportion and will only slide that one image.
I have tried setting the width/height separately in the javascript using document.getElementsByClassName, Yet it still does not fill the contaning div
Here is the code:
function Slide() {
ul = document.getElementById("slide");
liItems = ul.children;
liNumber = liItems.length;
imageNumber = 0;
sliderWidth = 0;
currImg = 0;
// Left + Right Arrows
leftArrow = document.getElementById("left");
rightArrow = document.getElementById("right");
for (i = 0; i < liNumber; i++) {
imageWidth = liItems[i].children[0].clientWidth;
sliderWidth += imageWidth;
imageNumber++;
}
// Set UL's Width as total width of all images in slider.
ul.style.width = parseInt(sliderWidth) + "px";
slider(ul);
function slider(ul) {
animate({
delay: 1000 / 60,
duration: 3000,
delta: function(p) {
return Math.max(0, -1 + 2 * p)
},
step: function(delta) {
ul.style.left = '-' + parseInt(currImg * imageWidth + delta * imageWidth) + "px";
},
callback: function() {
currImg++;
//Keep sliding if not last image
if (currImg < liNumber - 1) {
slider(ul);
}
// Slide back to first image, if last image
else {
leftPosition = (liNumber - 1) * imageWidth;
//after set seconds, call goback for first image
setTimeout(function() {
goBack(leftPosition)
}, 2000);
setTimeout(function() {
slider(ul)
}, 3000);
}
}
});
function goBack(leftPosition) {
currImg = 0;
setInterval(function() {
if (leftPosition >= 0) {
ul.style.left = '-' + parseInt(leftPosition) + "px";
leftPosition -= imageWidth;
}
}, 1000 / 60);
}
function animate(opts) {
start = new Date;
id = setInterval(function() {
timePassed = new Date - start;
progress = timePassed / opts.duration
if (progress > 1) {
progress = 1;
}
delta = opts.delta(progress);
opts.step(delta);
if (progress == 1) {
clearInterval(id);
opts.callback();
}
}, opts.delay || 1000 / 60);
}
}
}
window.onload = Slide;
#slidecontainer {
height: 100%;
width: 100%;
overflow: hidden;
}
#slide {
position: relative;
z-index: 0;
list-style-type: none;
padding: 0;
}
#slide li {
position: relative;
left: 0;
top: 4%;
margin: 0;
padding: 0;
float: left;
width: 25%;
/* Adjust this value within the range of images i.e 4 images = 25%, 5 images = 20% */
}
.slideimg {
width: 100%;
height: 100%;
}
<div id="slidecontainer">
<ul id="slide">
<li>
<img src="images/style.jpg" alt="1" class="slideimg" />
</li>
<li>
<img src="images/style1.jpg" alt="2" class="slideimg" />
</li>
<li>
<img src="images/style2.jpg" alt="3" class="slideimg" />
</li>
<li>
<img src="images/style3.jpg" alt="4" class="slideimg" />
</li>
</ul>
</div>
Please do not give a jquery solution, It needs to be Vanilla.
1. 100% height
If you want to scale things to 100% of the height of the window, you'll need to make sure enough (when using position: static) or all (when using position: relative) parent elements also use 100% of the height.
In a stack snippet, this means adding these rules to both html and body, and to all of your own elements.
2. 100% width
The width is a bit easier, because every display: block element will automatically fill up its parent. To be certain, you can just add a width: 100% rule to all of the previously mentioned elements.
The problem your css had, was that each float had a width of 25% relative to its parent, which only had a width of 100%. Changing this to 400% (the number of slides * 100), fixes the width.
Here's an example of just the full screen slides. Note:
I'd swap the tag and id selectors with class selectors if I were you
I'd use display: flex on the ul and flex-grow: 1 on the lis instead of float, but both will work.
html,
body,
#slidecontainer,
#slide,
li,
img {
width: 100%;
height: 100%;
}
* {
margin: 0;
padding: 0;
position: relative;
}
/* turn this rule on and scroll via js to slide */
#slidecontainer {
/* overflow-x: hidden; */
}
#slide {
width: 400%; /* (100 * slideCount) */
}
li {
float: left;
width: 25%; /* (100 / slideCount) */
list-style: none;
}
img {
display: block;
background: #efefef;
}
<div id="slidecontainer">
<ul id="slide">
<li>
<img src="images/style.jpg" alt="1" class="slideimg" />
</li>
<li>
<img src="images/style1.jpg" alt="2" class="slideimg" />
</li>
<li>
<img src="images/style2.jpg" alt="3" class="slideimg" />
</li>
<li>
<img src="images/style3.jpg" alt="4" class="slideimg" />
</li>
</ul>
</div>
Bonus: without javascript
Now, just for fun, here's an implementation without javascript :) It's quite some work to change the number of slides though, so I'd go with a hybrid approach or use a css pre-processor to generate the animation keyframes if I were you. (Only tested in chrome)
html, body, #slidecontainer {
width: 100%;
height: 100%;
overflow-x: hidden;
}
* {
padding: 0;
margin: 0;
position: relative;
box-sizing: border-box;
}
#slide {
position: relative;
width: 400%;
height: 100%;
display: flex;
animation-duration: 7s;
animation-name: slide;
animation-iteration-count: infinite;
}
#slide > li {
flex-grow: 1;
list-style: none;
}
.slideimg {
width: 100%;
height: 100%;
}
#keyframes slide {
0% {
transform: translate3d(0, 0, 0);
}
20% {
transform: translate3d(0, 0, 0);
}
25% {
transform: translate3d(-25%, 0, 0);
}
45% {
transform: translate3d(-25%, 0, 0);
}
50% {
transform: translate3d(-50%, 0, 0);
}
70% {
transform: translate3d(-50%, 0, 0);
}
75% {
transform: translate3d(-75%, 0, 0);
}
95% {
transform: translate3d(-75%, 0, 0);
}
}
<div id="slidecontainer">
<ul id="slide">
<li style="background: green;">
<img src="images/style.jpg" alt="1" class="slideimg" />
</li>
<li style="background: blue;">
<img src="images/style1.jpg" alt="2" class="slideimg" />
</li>
<li style="background: yellow;">
<img src="images/style2.jpg" alt="3" class="slideimg" />
</li>
<li style="background: red;">
<img src="images/style3.jpg" alt="4" class="slideimg" />
</li>
</ul>
</div>
Hi There,
I try to create very simple slider using Jquery scrollLeft() method .
I found some answers and i tried this one here .... but not working .... I'm still beginner in jquery and don't know why .
HTML
<div class="gallery-slider ">
<div class="images-preview">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
<img alt="" class="img-responsive" src="http://placehold.it/300">
</div>
<div class="controls">
<div class="right-arrow"><i class="fa fa-angle-left fa-3x"></i></div>
<div class="left-arrow"><i class="fa fa-angle-right fa-3x"></i></div>
</div>
</div>
CSS
.gallery-slider {
position: relative;
}
.gallery-slider .images-preview {
margin: auto;
height: 230px;
overflow: hidden;
}
.gallery-slider .images-preview img {
display: inline-block;
overflow: visible;
width: 410px;
margin: 10px 17px;
}
.gallery-slider .images-preview img, .controls {
height: 200px;
width: 26%;
}
/* Controls */
.controls {
position: absolute;
top: 10px;
width: 100%;
}
.right-arrow, .left-arrow {
display: inline-block;
padding: 62px;
background-color: rgba(255, 255, 255, 0.76);
position: absolute;
height: 100%;
cursor: pointer;
}
.right-arrow i, .left-arrow i{
margin: 23px 20px;
}
.left-arrow {
right: 0px;
}
.right-arrow {
left: 0px;
text-align: right;
}
jQuery
$(".left-arrow").click(function () {
var leftPos = $('.images-preview img').scrollLeft();
$(".images-preview img").animate({scrollLeft: leftPos - 100}, 1000);
});
$(".right-arrow").click(function () {
var leftPos = $('.images-preview img').scrollLeft();
$(".images-preview img").animate({scrollLeft: leftPos + 100}, 1000);
});
So Any help ?!
Thanks in advance
Fiddle here
Update:
also i need it to return to scrollleft():0 at the end of scrolling
What you are asking for is simple but full of issues. These issues makes things complicated.
I have made images-preview position absolute. It allows you to
scroll by controlling the left(css). Couldnt get the scrollLeft to
work. Dont know why. If anyone do, i would love to know.
Need to calculate the number of img inside the images-preview. Allow you to add or delete images.
var active is added to prevent clicking too fast.
javascript:
var target = $('.images-preview');
//get the total number of images
var total = $('.images-preview img').length;
//calculate the width of the image-preview
var width = total * 300 + total * 40;
var c = 1;
// 80 is to center the image-preview
var originalLeft = 80;
// 300 is the image size, 40 is the total margin (this is how many px image-preview
// would have to move left for one image
var totalImg = 300 + 40;
// startToEnd is the total width when you click left(arrow-right) on first image
var startToEnd = width -originalLeft -340;
var a = '';
//need this to prevent multiple clicks
var active = false;
//put in the width at page rendering
$(document)function(){
target.css('width', width);
});
$(".left-arrow").click(function () {
if (active === false){
if (c === total){
a = originalLeft;
c = 1;
}else{
a = '-='+totalImg;
c++;
}
//turn the active to true to prevent another animation from activating
active = true;
target.animate(
{left: a},
{duration:500,
//turn the active off after animation is complete
complete: function(){
active = false;
}
});
}
});
$(".right-arrow").click(function () {
if (active === false){
if (c === 1){
a = '-'+startToEnd;
c = total;
}else{
a = '+='+totalImg;
c--;
}
active = true;
target.animate(
{left: a},
{duration:500,
complete: function(){
active = false;
}
});
}
});
css:
.gallery-slider{
width:500px;
height:300px;
position:relative;
overflow:hidden;
}
.images-preview{
width:300px;
height:300px;
position:absolute;
left:80px;
}
.images-preview img{
width:300px;
height:300px;
position:relative;
float:left;
margin:0 20px;
}
.control{
width:100%;
height:100%;
position:relative;
}
.right-arrow, .left-arrow{
position:absolute;
padding:0 26px;
}
.right-arrow i, .left-arrow i{
line-height:300px;
}
.right-arrow{
left:0;
}
.left-arrow{
right:0;
}
Here is the demo: https://jsfiddle.net/ood26n7b/1/
I want to automatically scroll a div based on mouse position using jQuery.
If you see this fiddle here, you can see a number of images that are horizontally ordered in a div that is scrollable:
<div id="parent">
<div id="propertyThumbnails">
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
<img src="http://www.millport.org/wp-content/uploads/2013/05/Flower-festival.jpg" />
</div>
</div>
CSS:
#parent {
height: 300px;
width: 100%;
background: #ddd;
}
#propertyThumbnails {
background: #666;
height: 80px;
white-space: nowrap;
overflow: scroll;
}
#propertyThumbnails img {
width: 125px;
height: 80px;
display: inline-block;
margin: 3px;
margin-right: 0;
opacity: 0.6;
}
I found out that you can use $("#container").scrollLeft(position) to set the position of the scroller but I want to do it based on the mouse position of the parent. So that when the mouse is fully to the right hand side, the right most image displays, and when the mouse is fully left, the left most image displays.
How can I do this?
A slightly different way to achieve what you need:
jQuery(function($) {
$(window).load(function() {
var $gal = $("#propertyThumbnails"),
galW = $gal.outerWidth(true),
galSW = $gal[0].scrollWidth,
wDiff = (galSW / galW) - 1, // widths difference ratio
mPadd = 60, // Mousemove Padding
damp = 20, // Mousemove response softness
mX = 0, // Real mouse position
mX2 = 0, // Modified mouse position
posX = 0,
mmAA = galW - (mPadd * 2), // The mousemove available area
mmAAr = (galW / mmAA); // get available mousemove fidderence ratio
$gal.mousemove(function(e) {
mX = e.pageX - $(this).offset().left;
mX2 = Math.min(Math.max(0, mX - mPadd), mmAA) * mmAAr;
});
setInterval(function() {
posX += (mX2 - posX) / damp; // zeno's paradox equation "catching delay"
$gal.scrollLeft(posX * wDiff);
}, 10);
});
});
#parent {
position: relative;
margin: 0 auto;
width: 60%;
height: 260px;
}
#propertyThumbnails {
position: relative;
overflow: hidden;
background: #444;
width: 100%;
height: 262px;
white-space: nowrap;
}
#propertyThumbnails img {
vertical-align: middle;
height: 100%;
display: inline;
margin-left: -4px;
}
<div id="parent">
<div id="propertyThumbnails">
<img src="//placehold.it/600x400/0bf" />
<img src="//placehold.it/600x400/f0b" />
<img src="//placehold.it/600x400/0fb" />
<img src="//placehold.it/600x400/b0f" />
<img src="//placehold.it/600x400/bf0" />
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
where mPadd is the area (in PX, at the left and right border zone) without any sensitivity to prevent user frustrations :)
this should at least get you headed in the right direction.
var parent = $('#parent');
var img = $('img:first-child');
parent.on('mousemove', function(e) {
mouseX = e.pageX
img.css('margin-left',-mouseX/parent.width()*100);
});
http://jsfiddle.net/xWcXt/4/