Keep parallax fixed but change image on scroll? - javascript

I have a div where I want to change the image and text when I scroll on it. I have gotten some of the way but I cant figure out how to keep the "parallax-row" fixed, but act like its scrolling? I have a code pen link to help below.
MY GOAL : When you scroll anywhere in the parallax-window everything should stick, but the image and text changes. I have seen some cool image effects using parallax so thats why I am learning it.
codepen
<html>
<body>
<!---------PARALLAX------->
<div class="parallax-window">
<div class="parallax-container">
<div class="parallax-row">
<div class="parallax-image-container">
<img src="https://cdn.pixabay.com/photo/2016/11/18/19/07/happy-1836445_1280.jpg" alt="">
</div>
<div class="parallax-text">
<h1>Title 1</h1>
<h3>This is a description.
</h3>
<div class="mouseicon">
<div class="mousewheel"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
CSS
/*PARALLAX */
.parallax-container::-webkit-scrollbar {
display: none;
}
.parallax-window {
position: relative;
height: 400px;
width: 100vw;
overflow-y: scroll;
overflow-x: hidden;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.parallax-container {
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: column;
height: 1000px;
background-color: rgb(221, 221, 221);
}
.parallax-row {
display: flex;
justify-content: flex-start;
align-items: center;
height: 400px;
width: 100%;
}
.parallax-image-container {
display: block;
height: inherit;
}
.parallax-image-container img {
height: inherit;
}
.parallax-text {
height: inherit;
display: flex;
flex-direction: column;
align-items: left;
justify-content: center;
padding: 0em 4em;
}
.mouseicon {
margin: 1em;
display: flex;
justify-content: center;
width: 40px;
height: 65px;
border: solid 2px black;
border-radius: 50px;
}
.mousewheel {
width: 10px;
height: 20px;
background-color: black;
border-radius: 50px;
animation: scroll 1.5s infinite;
}
#keyframes scroll {
0% {
transform: translateY(0px);
opacity: 0.5;
}
100% {
transform: translateY(5px);
}
}
JS
//-------PARALLAX SCROLL-------- //
const parallaxContainer = document.querySelector(".parallax-window");
const parallaxImage = document.querySelector(".parallax-image-container img");
parallaxContainer.scrolltop = 0;
const parallaxText = document.querySelector(".parallax-text h1")
var scrollHandler = function () {
var newImageUrl = parallaxImage.src;
var scrollTopParallax =
parallaxContainer.scrollTop || parallaxContainer.scrollTop;
if (scrollTopParallax > 100) {
newImageUrl =
"https://cdn.pixabay.com/photo/2016/11/29/07/16/balancing-1868051__480.jpg";
parallaxText.innerHTML = "Title 2"
}
if (scrollTopParallax < 100) {
newImageUrl =
"https://cdn.pixabay.com/photo/2016/11/18/19/07/happy-1836445_1280.jpg";
parallaxText.innerHTML = "Title 1"
}
parallaxImage.src = newImageUrl;
console.log("new: " + parallaxImage.src);
};
parallaxContainer.addEventListener("scroll", scrollHandler);

I have updated my codepen with my own answer. essentially creating an overlay to scroll on and then changing the elements based on that invisible overlays scroll position. see link to codepen above.

Related

Full width div triggered by onclick

My sandbox on JSFIDDLE
When 'OPEN' is clicked, the content div should expand to full width, but it ended up expanding by 100px width like on the red box. I tried to set width: 100%, in the gray box div and it didn't work.
In the .content class, I had the width set to 100vw without margin: 0 auto and it expanded 100% width to the right side, not screen-fulled size.
[]
I'm testing this function before I deploy it on my website.
jQuery -
$(".openit").on("click", function() {
$(".expandBG").toggleClass("content");
$(".openit").hide();
$(".closeit").show();
$(".text").delay(500).fadeIn();
});
$(".closeit").on("click", function() {
$(".expandBG").toggleClass("content");
$(".openit").show();
$(".closeit").hide();
$(".text").hide();
});
HTML -
<div class="wrapper">
<div class="back">BG
<div class="expandBG">
<div class="openit">OPEN</div>
<div class="flex-col">
<div class="closeit">CLOSE</div>
<div class="content text" style="display: none;">
<div>(CONTENT HERE)</div>
</div>
</div>
</div>
</div>
</div>
CSS -
body {
background-color: #000;
}
.wrapper {
width: 100%;
margin: 0 auto;
text-align: center;
border: solid red 1px;
}
.back {
position: relative;
color: #fff;
width: 110px;
height: 110px;
background-color: red;
margin: 0 auto;
text-align: center;
display: block;
}
.expandBG {
display: block;
width: 100px;
height: 100px;
transition: ease 0.3s;
background-color: #192D38;
overflow: hidden;
margin: 0 auto;
bottom: 0;
text-align: center;
font-family: sans-serif;
color: #fff;
position: relative;
}
.flex-col {
flex-direction: column;
}
.openit {
display: block;
text-align: center;
height: 100%;
cursor: pointer;
margin: 0 auto;
}
.closeit {
display: block;
text-align: center;
cursor: pointer;
width: 100%;
margin: 0 auto;
z-index: 1;
position: relative;
}
.text {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: -25px;
}
.content {
width: 100%;
height: 50vw;
position: relative;
margin: 0 auto;
}
It's because of the div with a class name back. increase the width of that div to 100% when opneit is clicked and then back to its original size when closeit is clicked.
// add this to your CSS file
.w-full {
width: 100%
}
then include these two lines in your javaScript file
$(".openit").on("click", function() {
$(".back").addClass("w-full"); // This line has been added to your code.
$(".expandBG").toggleClass("content");
$(".openit").hide();
$(".closeit").show();
$(".text").delay(500).fadeIn();
});
$(".closeit").on("click", function() {
$(".back").removeClass("w-full"); // This line has been added to your code.
$(".expandBG").toggleClass("content");
$(".openit").show();
$(".closeit").hide();
$(".text").hide();
});

Is there a frontface-visibility option in CSS?

CSS/JS beginner here, I'm following a webkit 3d-transforms guide and trying to apply a hidden front-face option for the ring-rotation part:
The "backfaces-visible" checkbox hides/shows the backface, could the opposite be implemented where the backface is visible and the front is hidden?
Edit:
With respect to the first comment, I'd like to clarify that the desired result should look like this (front planes are hidden while rotating):
(Front panels were erased with photo-editing, the rest are CSS changes. Mind the poorly edited left card)
Not 100% sure if this is what you are looking for, but If you don't use the backface-visiblity parameter at all, i.e. leave it at its default "visible" and if it has a non-transparent background, the backside will always cover the frontside, if its z-index or order in the HTML code is set that way.
My snippet below is derived from some older code I had at hand, in case you wonder. Press the button below the circle to trigger a turning animation.
function turn1() {
$('#front').css({transform: 'rotateY(180deg)'});
$('#back').css({transform: 'rotateY(360deg)'}).delay(2000).promise().then(turn2);
};
function turn2() {
$('#front').css({transform: 'rotateY(0deg)'});
$('#back').css({transform: 'rotateY(180deg)'}).delay(2000).promise().then(turn1);
};
$('#go').on('click', turn1);
.wrapper {
position: relative;
margin: 20px auto;
width: 180px;
height: 180px;
font-size: 36px;
perspective: 150px;
}
#front, #back {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 2s;
display: flex;
justify-content: center;
align-items: center;
}
#front {
background: green;
}
#back {
background: yellow;
transform: rotateY(180deg);
}
.x {
text-align: center;
}
button {
padding: 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="front">Front</div>
<div id="back">Back</div>
</div>
<div class="x"><button id="go">Press to rotate</button></div>
If you add backface-visibility: hidden to the otherwise unchanged code, you see both sides when rotating:
function turn1() {
$('#front').css({transform: 'rotateY(180deg)'});
$('#back').css({transform: 'rotateY(360deg)'}).delay(2000).promise().then(turn2);
};
function turn2() {
$('#front').css({transform: 'rotateY(0deg)'});
$('#back').css({transform: 'rotateY(180deg)'}).delay(2000).promise().then(turn1);
};
$('#go').on('click', turn1);
.wrapper {
position: relative;
margin: 20px auto;
width: 180px;
height: 180px;
font-size: 36px;
perspective: 150px;
}
#front, #back {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 2s;
display: flex;
justify-content: center;
align-items: center;
backface-visibility: hidden;
}
#front {
background: green;
}
#back {
background: yellow;
transform: rotateY(180deg);
}
.x {
text-align: center;
}
button {
padding: 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="front">Front</div>
<div id="back">Back</div>
</div>
<div class="x"><button id="go">Press to rotate</button></div>

How can I fix a Javascript Carousel left control that does not working?

I'm working on my own to create a post css stype for a blogspot.com template that I purchased recently. With so many tutorials, I made exactly what I want, but the carousel have the issue that does not properly with the left control. Can you help me?
I was searching on YouTube. Most of the code is a modification from something of someone else (I'm a Graphic Designer who barely know the basics of HTML).
Thanks a lot!
const carousel2 = document.querySelector('.carousel2');
const slider2 = document.querySelector('.slider2');
const next = document.querySelector('.next');
const prev = document.querySelector('.prev');
let direction;
next.addEventListener('click', function() {
direction = -1;
carousel2.style.justifyContent = 'flex-start';
slider2.style.transform = 'translate(-20%)';
});
prev.addEventListener('click', function() {
if (direction === -1) {
direction = 1;
slider2.appendChild(slider2.firstElementChild);
}
carousel2.style.justifyContent = 'flex-end';
slider2.style.transform = 'translate(20%)';
});
slider2.addEventListener('transitionend', function() {
// get the last element and append it to the front
if (direction === 1) {
slider2.prepend(slider2.lastElementChild);
} else {
slider2.appendChild(slider2.firstElementChild);
}
slider2.style.transition = 'none';
slider2.style.transform = 'translate(0)';
setTimeout(() => {
slider2.style.transition = 'all 0.5s';
})
}, false);
/*----------POST CAROUSEL SLIDER------------
---------------------------------------------------*/
.carousel-general-container {
max-width: 780px;
height: auto;
width: 100%;
margin: 0px auto;
padding-bottom: 20px;
}
/*--POST CAROUSEL 2--*/
.slider-container2 {
max-width: 100%;
height: auto;
width: 100%;
margin: 10px auto;
}
.carousel2 {
background: #fff;
border: 2px solid transparent;
border-radius: 6px;
width: 100%;
display: flex;
justify-content: flex-start;
overflow: hidden;
position: relative;
}
.slider2 {
display: flex;
height: 100%;
width: 500%;
flex-shrink: 0;
transition: all 0.5s;
}
.slider2 div {
flex-basis: 20%;
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
}
.slider2 div img {
height: auto;
width: 100%;
}
.controls2 button.next {
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
cursor: pointer;
outline: none;
color: white;
}
.controls2 button.prev {
position: absolute;
left: 20px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
cursor: pointer;
outline: none;
color: white;
}
.controls2 button i {
font-size: 40px;
}
/*---------------------------------------------END--*/
<!--POST CAROUSEL CONTAINER-->
<div class="carousel-general-container">
<!--POST CAROUSEL SLIDER 2-->
<div class="slider-container2">
<div class="carousel2">
<div class="slider2">
<div>
<img src="https://1.bp.blogspot.com/-u0J4VE6mIeA/XyOZayGTTAI/AAAAAAAAHjc/UWqc7cn13CU4lsoQ6YXtJTu0FCmbGxuKACPcBGAYYCw/s1024/Templates-para-LIBROS.jpg">
</div>
<div>
<img src="https://1.bp.blogspot.com/-ujMXEoNvpA0/XyXhGwza0YI/AAAAAAAAHkM/NGONl1zblm0ufze1a0DLoCdKSCY_dbgxgCPcBGAYYCw/s1000/graffiti2.jpeg">
</div>
</div>
<div class="controls2">
<button class="next"><i class="material-icons">keyboard_arrow_right</i></button>
<button class="prev"><i class="material-icons">keyboard_arrow_left</i></button>
</div>
</div>
</div>
</div>
This is the codepen.
Thanks a lot!
why don't You use an already existing carousel prefab?
Doing a carousel yourself might teach You a lot of things but It will take a lot of your time!
I personally reccomend You Slick.js!
It is fully personalizable and It is compatible with both desktops and mobiles.
Here is a quick tutorial on how to set It up ;)

css transform scale make cut off image

i'm trying to scale image double when click zoom-in button, and half image when click zoom-out button
My issue is, when click zoom-in button (so, image size is double)
and if it's size over than container, the left side of image (or top side of image) cut off.
what should i do?
same question here, CSS Transform scale scrolling issue ... but it's not a good idea.
because it also scale focus on 'top-left side' when zoom-out
image, so center alignment is impossible
(i want to apply transform: scale(..) using transform-origin: center)
the only way that i know is every time calculate image size, and apply margin for cut-off, but it is hard to apply
any idea please? :o
code look like this.
constructor() {
super()
this._refs = { ratio: 100 }
}
getImageStyle() {
return {
transform: scale(calc(${this.state.ratio} / 100)),
'transform-origin': 'center'
}
}
zoomIn() {
this.setState({ ratio: this.state.ratio + 25 })
}
zoomIn() {
this.setState({ ratio: this.state.ratio - 25 })
}
render() {
const { src } = this.props
return (
<div
className={styles.wrapper}
<img
style={this.getImageStyle()}
ref={(elem) => setRefToNode(this._refs, 'image', elem)}
className={styles.image}
src={src} />
</div>
)
}
and css.
.wrapper {
display: flex;
position: relative;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
overflow: scroll;
.image {
position: relative;
max-width: 100%;
max-height: 100%;
background-color: white;
}
}
Don't understand what the problem is.
Image doesn't cut off when transforming.
$("#zoom-in").on("click", function() {
$(".image").removeClass("zoom-out");
$(".image").addClass("zoom-in");
});
$("#zoom-out").on("click", function() {
$(".image").removeClass("zoom-in");
$(".image").addClass("zoom-out");
});
$("#zoom-off").on("click", function() {
$(".image").removeClass("zoom-in");
$(".image").removeClass("zoom-out");
});
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.wrapper {
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 100px;
border: 4px solid;
}
.wrapper .image {
position: relative;
width: 100%;
height: 100%;
background-color: rgba(255, 0, 0, 0.4);
border-radius: 50%;
transform-origin: center;
transition: transform ease .3s;
}
.wrapper .image.zoom-in {
transform: scale(2);
}
.wrapper .image.zoom-out {
transform: scale(0.5);
}
section {
position: fixed;
bottom: 0;
left: 0;
margin: 10px;
}
section button {
width: 30px;
height: 30px;
margin: 10px;
font-weight: bold;
font-size: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="image"></div>
</div>
<section>
<button id="zoom-out">−</button>
<button id="zoom-off">0</button>
<button id="zoom-in">+</button>
</section>

Slide up animation on up scroll based on div position

I'm trying to create a smoother transition by making the background for .header slide up rather than just disappear when the bottom of div "1" hits the top of the page and the .header background changes from white to transparent. I've tried to achieve this by adding class .BGupTranisition to the CSS and jQuery (//up scroll - else{) but this doesn't work? Could someone point out what I'm doing wrong here?? :-)
var lastScrollTop = 0;
$(window).on('scroll', function() {
var header = $('.header');
var stage0 = $('.stage-0');
var scrollTop = $(window).scrollTop();
if (scrollTop > lastScrollTop) {
// down scroll
if (scrollTop > stage0.offset().top + stage0.height()) {
header.addClass('hide');
}
} else {
// up scroll
if (scrollTop <= stage0.offset().top + stage0.height()) {
header.removeClass('headerBGchange headerLIchange');
} else {
header.removeClass('hide').addClass('headerBGchange headerLIchange BGupTranistion');
}
}
lastScrollTop = scrollTop;
});
.header {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
height: 80px;
-webkit-transition: top .5s ease;
transition: top .5s ease;
position: fixed;
width: 100%;
top: 0;
background-color: transparent;
overflow: hidden;
}
.header ul {
margin: 20px;
padding: 0;
}
.header ul li {
display: inline-block;
margin-right: 20px;
color: white;
}
.header ul li:last-child {
margin-right: 0;
}
.hide {
top: -80px;
}
.headerBGchange {
Background: white;
}
.BGupTranistion {
<!--slide back up animation-->
}
.header.headerLIchange ul li {
color: Blue;
}
.stage {
color: #fff;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
height: 100vh;
background-color: bisque;
font-size: 48px;
}
.stage-0 {
background: black;
}
.stage-1 {
background: #030202;
}
.stage-2 {
background: #060505;
}
.stage-3 {
background: #080707;
}
.stage-4 {
background: #0b0a09;
}
.stage-5 {
background: #0e0c0b;
}
.stage-6 {
background: #110e0e;
}
.stage-7 {
background: #141110;
}
.stage-8 {
background: #161312;
}
.stage-9 {
background: #191515;
}
.stage-10 {
background: #1c1817;
}
.stage-11 {
background: #1f1a19;
}
.stage-12 {
background: #221d1c;
}
.stage-13 {
background: #241f1e;
}
.stage-14 {
background: #272120;
}
.stage-15 {
background: #2a2422;
}
.stage-16 {
background: #2d2625;
}
.stage-17 {
background: #302827;
}
.stage-18 {
background: #322b29;
}
.stage-19 {
background: #352d2c;
}
.stage-20 {
background: #38302e;
}
.stage-21 {
background: #3b3230;
}
.stage-22 {
background: #3e3432;
}
.stage-23 {
background: #413735;
}
.stage-24 {
background: #433937;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="header">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="stage stage-0">1</div>
<div class="stage stage-2">3</div>
<div class="stage stage-4">5</div>
<div class="stage stage-6">7</div>
<div class="stage stage-8">9</div>
<div class="stage stage-10">11</div>
<div class="stage stage-12">13</div>
<div class="stage stage-14">15</div>
<div class="stage stage-16">17</div>
<div class="stage stage-18">19</div>
<div class="stage stage-20">21</div>
<div class="stage stage-22">23</div>
Note that background is a property of div that occupies the same area as the div itself. Having said that, you can't move out the div's background without moving the content of the div without playing around with the text property.
The solution to this is if you play around with vertical linear-gradient color in the .header { background: /* linear-gradient value here */ } or you can create another div with white background behind the div.header that slide up when you wanted to and make the div.header bacground transparent.
The first method would require you to calculate the value based on the scrolling value in your javascript.

Categories