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
Related
I'm using animation property CSS to animate the window when the user clicks maximize button. The window is created ONLY when the maximize button was clicked and the animation is working, but the problem is when I click the close button the window is doesn't animate. How can I animate when the close button is click?
JavaScript:
Show project image.
_showProjectImage(e) {
const btn = e.target.closest('.projects__maximize-btn');
if (!btn) return;
const { id } = btn.dataset;
const { image } = this._data.find(image => image.id === +id);
this._projectBox = e.target.closest('.projects__box');
const markup = this._generateProjectImage(image);
this._projectBox.insertAdjacentHTML('afterbegin', markup);
}
Hide project image.
_hideProjectImage(e) {
const btnClose = e.target.closest('.btn__close-window');
if (!btnClose) return;
this._projectBox.removeChild(this._projectBox.firstElementChild);
}
HTML Element:
_generateProjectImage(image) {
return `
<div class="projects__window">
<div class="projects__window-content">
<button class="projects__window-close btn__close-window">
<svg class="projects__window-icon">
<use
xlink:href="${icon}#icon-close"
></use>
</svg>
</button>
<div class="projects__window-box">
<img src="${image}" alt="" class="projects__window-image">
</div>
</div>
</div>
`;
}
CSS:
.projects {
&__window {
position: fixed;
inset: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 1000;
animation: window-animate 300ms linear;
}
}
#keyframes window-animate {
from {
transform: scale(0);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
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>
I have a dynamic slider with two buttons left and right.
that means for each slide, the slide parent width increases by 100%. 2 slides * 100% = 200%. In example class="slider"; width:'200%'
I want to center each slide's text in the middle of the page. But i want the text to slide not in just slides container, but in its parent-parent width (class='carousel' in example).
Code below, is example how the slider is looking right now.
JavaScript, you should ignore this. Implemented it, for the code to work.
document.addEventListener('DOMContentLoaded', function() { //Display function after HTML is loaded
const left = document.querySelector('.left');
const right = document.querySelector('.right');
var slider = document.getElementById('slider');
var leftImg = document.getElementById('left');
var rightImg = document.getElementById('right');
var sections = document.querySelectorAll('.slide').length; // get number of slides
var sectionIndex = 1;
slider.style.width = ' ' + 100 * sections + '%';
function changeOpacity() {
if (sectionIndex == 1) {
leftImg.style.opacity = '0.4';
} else {
leftImg.style.opacity = '1';
}
if (sectionIndex == sections) {
rightImg.style.opacity = '0.4';
} else {
rightImg.style.opacity = '1';
}
}
left.addEventListener('click', function() {
var leftImg = document.getElementById('left');
sectionIndex = (sectionIndex > 1) ? sectionIndex - 1 : 1;
slider.style.transform = 'translate(' + (sectionIndex - 1) * (-100 / sections) + '%)';
changeOpacity();
});
right.addEventListener('click', function() {
sectionIndex = (sectionIndex < sections) ? sectionIndex + 1 : sections;
slider.style.transform = 'translate(' + (sectionIndex - 1) * (-100 / sections) + '%)';
changeOpacity();
});
})
.slider-container {
padding: 25px 0px;
width: 40%;
margin: auto;
}
.slider-container .carousel {
overflow: hidden;
height: 260px;
width: 100%;
border:solid 2px black;
position:relative;
}
.slider-container .slider {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
height: 100%;
-webkit-transition: .5s;
transition: .5s;
}
.slider-container .slider .slide {
width: 100%;
}
.slider-container .arrow-container {
width: 70px;
position: absolute;
bottom: 0;
}
<div class="slider-container mobile-container text-left">
<div class="carousel relative">
<div id="slider" class="slider">
<div class="slide">
<div class="author d-flex flex-column">
<h3>Ken Ludden</h3>
<span class="regularText">Director, Margot Fonteyn Academy of Ballet</span>
</div>
</div>
<div class="slide">
<div class="author d-flex flex-column">
<h3>Ken Ludden</h3>
<span class="regularText">Director, Margot Fonteyn Academy of Ballet</span>
</div>
</div>
</div>
</div>
<div class="controls">
<div class="arrow-container d-flex justify-content-between ">
<div>
<button class="left" id="left" style="opacity: 0.4;">Left </button>
</div>
<div>
<button class="right" id="right">Right</button>
</div>
</div>
</div>
</div>
</div>
The Snippet below is what i want. But i should be centered, and i don't know how.
I have tried using fl
document.addEventListener('DOMContentLoaded', function() { //Display function after HTML is loaded
const left = document.querySelector('.left');
const right = document.querySelector('.right');
var slider = document.getElementById('slider');
var leftImg = document.getElementById('left');
var rightImg = document.getElementById('right');
var sections = document.querySelectorAll('.slide').length; // get number of slides
var sectionIndex = 1;
slider.style.width = ' ' + 100 * sections + '%';
function changeOpacity() {
if (sectionIndex == 1) {
leftImg.style.opacity = '0.4';
} else {
leftImg.style.opacity = '1';
}
if (sectionIndex == sections) {
rightImg.style.opacity = '0.4';
} else {
rightImg.style.opacity = '1';
}
}
left.addEventListener('click', function() {
var leftImg = document.getElementById('left');
sectionIndex = (sectionIndex > 1) ? sectionIndex - 1 : 1;
slider.style.transform = 'translate(' + (sectionIndex - 1) * (-100 / sections) + '%)';
changeOpacity();
});
right.addEventListener('click', function() {
sectionIndex = (sectionIndex < sections) ? sectionIndex + 1 : sections;
slider.style.transform = 'translate(' + (sectionIndex - 1) * (-100 / sections) + '%)';
changeOpacity();
});
})
.slider-container {
margin: auto;
padding: 25px 0px;
}
.slider-container .carousel {
overflow: hidden;
height: 260px;
width: 80%; /* the width i want */
border: solid 2px black; /* the border for your understading */
position: relative;
}
.slider-container .slider {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
height: 100%;
-webkit-transition: .5s;
transition: .5s;
}
.slider-container .slider .slide {
width: 100%;
}
.slider-container .comment {
max-width: 352px;
padding: 30px 0px;
}
.slider-container .arrow-container {
width: 70px;
position: absolute;
bottom: 0;
}
<div class="slider-container mobile-container text-left">
<div class="carousel relative">
<div id="slider" class="slider">
<div class="slide">
<div class="author d-flex flex-column">
<h3>Ken Ludden</h3>
<span class="regularText">Director, Margot Fonteyn Academy of Ballet</span>
</div>
</div>
<div class="slide">
<div class="author d-flex flex-column">
<h3>Ken Ludden</h3>
<span class="regularText">Director, Margot Fonteyn Academy of Ballet</span>
</div>
</div>
</div>
<div class="controls">
<div class="arrow-container d-flex justify-content-between ">
<div>
<button class="left" id="left" style="opacity: 0.4;">Left </button>
</div>
<div>
<button class="right" id="right">Right</button>
</div>
</div>
</div>
</div>
</div>
</div>
You can see in this snippet that text is sliding from a lot further right than the previous example.
I need to center the slide, because i want the same for left side.
I have tried using flex-column, align-items:center on class="slide". And it works fine, but the class="controls" aren't centering because they are position:absolute and i tried to putting them elsewhere, but it didnt work..
I really hope you guys did understand what i want and really hope that i recieve atleast some suggestions. This is my 1st question, sorry for long code.
Thank you anyway :)
Your carousel is 80% of the width, so if you want that to be centered, you can do: margin: 0 auto on the carousel class.
I have a situation that I'm trying to do, and I need your help because I do not have much experience with JavaScript.
First please take a look at this code where I was through ajax, parse from xml file into html. I set the picture as background of #clickMapFlashContainer, and prepend hotspots clickable circles into #clickAreas which results to get 5 clickable circles, which look like this: (screenshot) http://prntscr.com/d3v97y (Currently when we get to the site, site looks like this)
You'll notice that I have 5 different clickable circles with _clickable id and class circle. Each circle with _clickable id have onclick="onclick(id)" and this function should be executed onclick.
Below I have divs with same id but without _clickable and all of 5 have display: none... Display none needs to be changed to display block when click on corresponding id with _clickable circle.
However, there is one thing I must mention, in a situation when the div with class clickMapItem text is display block, background image from #clickMapFlashContainer should be visible as it is, it is only necessary to change the text below the image, but in situation when the div with class clickMapItem multiImageText is display block, background image from #clickMapFlashContainer should be display none because clickMapItem multiImageText contains a gallery and background should not be seen.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clickMap">
<div id="clickMapFlashContainer" style="background-image: url(../../../../../../linkableblob/internet_en/9492/image/steel_agg_bof_flash_en-image.jpg;); width: 560px; height: 560px; background-repeat: no-repeat;">
<div id="clickAreas">
<div id="clickMap_item_11024_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 11px; left: 219px; width: 76px; height: 76px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>
<div id="clickMap_item_11006_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 388px; left:
250px; width: 66px; height: 66px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>
<div id="clickMap_item_11004_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 155px; left:
189px; width: 135px; height: 135px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>
<div id="clickMap_item_10450_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 208px; left:
436px; width: 105px; height: 105px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>
<div id="clickMap_item_9510_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: 469px; left:
350px; width: 75px; height: 75px; opacity: 0.5; border-radius: 100%; cursor: pointer;">
</div>
<div id="clickMap_item_default" class="clickMapItem text">
<p>Due to long-standing contact with customers RHI has detailed knowledge of the requirements that steelworkers place on refractories. This is why RHI has been involved in the development of package and system solutions for many years und nowadays offers customized high-end solutions for basically all individual customer requirements.</p>
</div>
</div>
<!-- clickMap text -->
<div id="clickMap_item_9510" class="clickMapItem text" style="display: none;">
back
<p>text</p>
</div>
<!-- clickMap gallery -->
<div id="clickMap_item_10450" class="clickMapItem multiImageText" style="display: none;">
back
<p>text</p>
</div>
<!-- clickMap text -->
<div id="clickMap_item_11004" class="clickMapItem text" style="display: none;">
back
<p>text</p>
</div>
<!-- clickMap gallery -->
<div id="clickMap_item_11006" class="clickMapItem multiImageText" style="display: none;">
back
<p>text</p>
</div>
<!-- clickMap text -->
<div id="clickMap_item_11024" class="clickMapItem text" style="display: none;">
back
<p>text</p>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(function ($) {
$.ajax({
type: "GET",
url: 'steel_agg_bof_flash_en.xml',
dataType: "xml",
success: xmlParser
});
function xmlParser(xml) {
$(xml).find("basics").each(function () {
var img = $(this).find('imgpath').text();
$('#clickMapFlashContainer').css({
'background-image' : 'url(' + img + ')',
'width' : '560px',
'height' : '560px',
'background-repeat' : 'no-repeat',
});
});
$(xml).find("hotspot").each(function () {
var position = $(this).find('position').text();
var arr = position.split(",");
var hotspotid = $(this).find('hsid').text();
$('#clickAreas').prepend('<div id="'+ hotspotid +'_clickable" class="circle" onclick="changeStyle(id);" style="background: #004593; position: absolute; top: ' + arr[1] + 'px' + '; left: ' + arr[0] + 'px' +'; width: ' + Math.floor(arr[2]/3.28148) + 'px; height: '+ Math.floor(arr[2]/3.28148) + 'px; opacity: 0.5; border-radius: 100%; cursor: pointer;"></div>');
});
}
});
</script>
I found a solution and working properly, but this is JavaScript newbie code as you can see, please take a look and suggest what can be changed, because I think it is a messy code. Whether it is a good idea to use Array.prototype.slice.call to convert NodeList to an Array and then check whether the div contains one of these classes?
function changeStyle(hotspotid) {
var hotspot = hotspotid.replace('_clickable', '');
var hotspots = document.querySelectorAll(".clickMapItem.text, .clickMapItem.multiImageText"); // Return a NodeList
var nodesArray = Array.prototype.slice.call(hotspots, 0); //Convert NodeList to an Array
nodesArray.forEach(function(item) {
console.log(item);
});
var i;
for (i = 0; i < hotspots.length; i++) {
hotspots[i].style.display = "none";
}
if (hotspotid == "clickMap_item_10450_clickable" || hotspotid == "clickMap_item_11006_clickable") {
document.getElementById('clickMapFlashContainer').style.display = "none";
}
if (hotspots[0].style.display == "") {
document.getElementById(hotspot).style.display = '';
document.getElementById("clickMap_item_default").style.display = "none";
} else if (hotspots[1].style.display == "") {
document.getElementById("clickMapFlashContainer").style.display = "none";
}
};
function backClose() {
var sections = document.getElementsByClassName("clickMapItem");
var i;
for (i = 0; i < sections.length; i++) {
sections[i].style.display = "none";
}
document.getElementById('clickMapFlashContainer').style.display = "";
document.getElementById("clickMap_item_default").style.display = "";
}
}
I'm trying to create a slideshow type effect on the homepage of my app, but I am fairly new to JS and am having trouble with some of the intricacies. I have a working slideshow with delays and setTimeouts that looks like this:
<script>
setTimeout(function() {
$("#hero-image-index").fadeOut().empty();
}, 6000);
setTimeout(function() {
$("#slide-1").fadeOut(500);
}, 6000);
$('#slide-2').delay(6000).fadeIn(3000);
setTimeout(function() {
$("#slide-2").fadeOut(500);
}, 12000);
$('#slide-3').delay(12000).fadeIn(3000);
setTimeout(function() {
$("#slide-3").fadeOut(500);
}, 18000);
$('#slide-4').delay(18000).fadeIn(3000);
setTimeout(function() {
$("#slide-4").fadeOut(500);
}, 25000);
$('#slide-5').delay(25000).fadeIn(3000);
setTimeout(function() {
$("#slide-5").fadeOut(500);
}, 32000);
$('#slide-6').delay(32000).fadeIn(3000);
setTimeout(function() {
$("#slide-6").fadeOut(500);
}, 39000);
$('#slide-7').delay(39000).fadeIn(3000);
$('#hero-image-index-2').delay(39000).fadeIn(3000);
</script>
However, now the client wants a navigation so the user can go from slide to slide at will, which I have set up using ionicons on each "slide". Here's a sample "slide":
<div class="slide text-center" id="slide-1">
<h1 style="margin: 75px 0 40px 0; font-size: 52px; color: white; font-weight: bolder">Genetic Golf</h1>
<h2 style="color: white">We don't guess, we test to find what works best for you!</h2>
<div class="index-icon-box" style="color: white">
<i class="icon go-to-7 ion-chevron-left"></i>
<i class="icon go-to-1 ion-android-radio-button-on"></i>
<i class="icon go-to-2 ion-android-radio-button-off"></i>
<i class="icon go-to-3 ion-android-radio-button-off"></i>
<i class="icon go-to-4 ion-android-radio-button-off"></i>
<i class="icon go-to-5 ion-android-radio-button-off"></i>
<i class="icon go-to-6 ion-android-radio-button-off"></i>
<i class="icon go-to-7 ion-android-radio-button-off"></i>
<i class="icon go-to-2 ion-chevron-right"></i>
</div> <!-- index icon box -->
</div> <!-- slide 1 -->
I was hoping to do something with the JS like "if user doesn't click inside .index-icon-box then run the js as I already have it, but if they click on an .icon then do something like this:
<script>
$(document).ready(function() {
$(".go-to-1").click(function(){
$("#slide-1").show();
$("#slide-2").hide();
$("#slide-3").hide();
$("#slide-4").hide();
$("#slide-5").hide();
$("#slide-6").hide();
$("#slide-7").hide();
});
$(".go-to-2").click(function(){
$("#slide-1").hide();
$("#slide-2").show();
$("#slide-3").hide();
$("#slide-4").hide();
$("#slide-5").hide();
$("#slide-6").hide();
$("#slide-7").hide();
});
};
</script>
However, any way I attempt this just ends up breaking the part I do have working. Can any js-wizards straighten me out?
If your intent on doing this yourself without using a library, you might want to try the following.
First consider putting your slides together in a container, and overlaying
the icons to select the slide over them. Then keep track of the images using the indexes of both the slides and the containers. This provides for an easily edited slideshow setup.
A simple example is shown below, this should be in the neighborhood of what you are looking for.
jQuery(document).ready(function($) {
// Hides all images except for one, the one is given by an
// index. Also updates the controller.
function showSlide(index) {
$('.slides .slide').each(function(i) {
if (i == index) {
$(this).fadeIn(500);
} else {
$(this).fadeOut(500);
}
});
var spans = $('.controller span').removeClass('active');
spans.eq(index).addClass('active');
}
// Show only the first element and set an interval to
// continue to cycle through elements.
var index = 0;
showSlide(index);
var intervalFunc = function() {
index = index >= $('.slides .slide').length ? 0 : index + 1;
showSlide(index);
};
var interval = setInterval(intervalFunc, 6000);
// Handle clicks which will reset the interval to each time.
$('.controller span').click(function() {
// Set the current picture.
index = $(this).index();
showSlide(index);
// Reset the interval
clearInterval(interval);
interval = setInterval(intervalFunc, 6000);
});
});
.slideshow-contianer {
position: relative;
/* For Deomnstation purposes*/
width: 400px;
height: 200px;
margin: 2em;
}
.slides img {
width: 100%;
height: auto;
position: absolute;
left: 0;
top: 0;
}
.controller {
position: absolute;
bottom: 10px;
left: 0;
width: 100%;
-webkit-display: flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
}
.controller span {
width: 4px;
height: 4px;
border-radius: 50%;
border: 2px solid #ccc;
cursor: pointer;
margin: 10px;
/* Transition is a personal asthetic. */
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
.controller span.active,
.controller span:hover {
-webkit-transform: scale(1.5);
transform: scale(1.5);
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div class="slideshow-contianer">
<div class="slides">
<img class="slide" src="https://unsplash.it/400/200?random" />
<img class="slide" src="https://unsplash.it/400/200?random" />
<img class="slide" src="https://unsplash.it/400/200?random" />
<img class="slide" src="https://unsplash.it/400/200?random" />
<img class="slide" src="https://unsplash.it/400/200?random" />
</div>
<div class="controller">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>