Box-shadow positioned based on window scroll algorithm - javascript

I have this amateur function that changes the box-shadow on a group of elements based on the window.scrollTop position and element offset. When the user scrolls up or down from the photos, the box-shadow will move down or up respectively. So it gives the illusion of perspective. When these photo elements are in the center of the screen, the box-shadow is centered.
Right now it's not ideal and by that I mean it isn't very symmetrical and doesn't feel right. I know it because my "golden-ratio" (Not the actual Phy golden ratio, i just used this as a variable name) is just a random number. I know there is a way to use my variables to set this up properly I just can't come up with it. Looking for golden ratio (box-shadow vertical offset) to be from about -20 to 20, 0 when centered, seems to look okay.
So my question is can anyone optimize my algorithm so that the box-shadow changes as described above but more realistic?
This should only happen inside a certain vertical scroll window so
that this function isn't running while the photos are off the screen (already pretty much implemented)
The box-shadow change is subtle so there is not a HUGE shadow above or below it.
In my real code I have another function that changes the photos to be the same height as the width on window resize. Here I just have a fixed height of 160px.
Here is my code (modified to give a barebones example). Feel free to redo my function from scratch if that is cleaner.
var halfHeight;
var eleHalfHeight;
var scrollTop;
var photosOffset;
var profOffset
var distPhotos;
var goldenRatio;
$(window).scroll(function() {
halfHeight = $(window).height() / 2;
eleHalfHeight = $('.photo').height() / 2;
scrollTop = $(window).scrollTop();
photosOffset = $('.photos').offset().top - halfHeight + eleHalfHeight;
distPhotos = (photosOffset - scrollTop);
if (distPhotos < photosOffset && distPhotos > -photosOffset) {
goldenRatio = distPhotos / 25;
$('.photo-frame').css('box-shadow', '0px ' + (goldenRatio + 6) + 'px 4px 2px #c9c9c9');
};
});
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
display: flex;
align-items: center;
min-height: 500vh;
background-color: #fff;
}
.photos {
display: flex;
width: 100%;
justify-content: space-around;
margin-bottom: 60px;
background-color: #fff;
}
.photos .photo-frame {
width: 25%;
height: 160px;
border: 20px solid whitesmoke;
box-shadow: 0px 0px 4px 2px gray;
background-color: #000;
}
.photos .photo-frame .photo {
width: 100%;
background-color: #000;
z-index: 1;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<section class="photos">
<div class="photo-frame">
<div class="photo"></div>
</div>
<div class="photo-frame">
<div class="photo"></div>
</div>
<div class="photo-frame">
<div class="photo"></div>
</div>
</section>
</div>

Is it perfect™?
Nope.
Do I like it better than yours?
A little bit.
Will it help you?
I hope so, since I think it's easier to tweak — at least this was my intention. You tell me.
let wH = $(window).height(),
sO = 210, // shadowOffset (px); 50 => from -25 to +25
tO = 4, // topOffset (px) 0 => vertical symmetry,
lO = 4, // leftOffset (px) 0 => horizontal symmetry
moveshadow = function() {
let diff = $(window).scrollTop() - $(this).offset().top,
tOH = $(this)[0].offsetHeight,
should = (-diff < wH) && (diff < tOH),
factor = should ?
-((diff / wH + 1) / (1 + tOH / wH) - .5) * sO + tO :
0;
if (should) {
$(this).css({
"box-shadow": lO +"px " +
factor +
"px 8px -2px rgba(0,0,0,.1), " + lO + "px " +
(factor + sO / 20) +
"px 17px 4px rgba(0,0,0,.07), " + lO + "px " +
(factor - sO / 20) +
"px 22px 8px rgba(0,0,0,.06), " + lO/2 + "px " +
factor / 20 +
"px 21px 1px rgba(0,0,0,.12)"
})
}
};
$(window)
.on('resize', function() {
wH = $(window).height()
})
.on('scroll resize', function() {
$('.photo-frame').each(moveshadow)
})
body {
background-color: #fff;
text-align: center;
}
.wrapper {
padding: 120vh 30px;
}
.photos {
display: flex;
align-items: center;
justify-content: space-between;
}
.photo {
width: 20vw;
height: 32.36vw;
background-color: #eee;
}
.photo-frame {
padding: 20px;
border: 1px solid #eee;
box-sizing: border-box;
}
#media(min-width: 1000px) {
.wrapper {
width: 900px;
display: inline-block;
}
.photo {
width: 200px;
height: 323.6px;
background-color: #eee;
}
}
#media(min-width: 641px) {
.photo-frame:first-child { transform: translateY(-10vw) }
.photo-frame:last-child { transform: translateY(10vw) }
}
#media(max-width: 640px) {
.photos {
flex-direction: column;
}
.photo {
width: 60vw;
height: 37.08vw;
background-color: #eee;
}
.photo-frame {
margin: 7.5vw 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<section class="photos">
<div class="photo-frame">
<div class="photo"></div>
</div>
<div class="photo-frame">
<div class="photo"></div>
</div>
<div class="photo-frame">
<div class="photo"></div>
</div>
</section>
</div>
playground
:: }<(((*> ::)

Related

React horizontal Scrolling Section

So I want to have a specific scrolling section on my website, where while you scroll the wheel down (or drag the scrollbar down), the content scrolls sideways while the scrollbar on the right of the screen also moves down.
I googles like a ton yesterday for examples or packages, but didn´t find what I need - actually kind of. The best thing I found was this codepen:
https://codepen.io/alvarotrigo/pen/VwWMjVp
<div class="vertical-section">
Content above
</div>
<div class="sticky-container">
<main>
<section>
<h1>Beep</h1>
</section>
<section>
<h1>Boop</h1>
</section>
<section>
<h1>Boooom</h1>
</section>
<section>
<h1>The End</h1>
</section>
</main>
</div>
<div class="vertical-section">
Content Below
</div>
<div class="sticky-container">
<main>
<section>
<h1>Beep</h1>
</section>
<section>
<h1>Boop</h1>
</section>
<section>
<h1>Boooom</h1>
</section>
<section>
<h1>The End</h1>
</section>
</main>
</div>
-----------------------
<a href="https://alvarotrigo.com/blog/scroll-horizontally-with-mouse-wheel-vanilla-java/" target="_blank" class="read-article">
Read the article 👉
</a>
html,
body {
margin: 0;
font-family: sans-serif;
}
.vertical-section{
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
main {
overflow-x: hidden;
display: flex;
position: sticky;
top:0;
}
h1 {
margin: 0;
padding: 0;
}
section {
min-width: 50vw;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 4ch;
}
section:nth-child(even) {
background-color: teal;
color: white;
}
.read-article{
position: absolute;
top: 10px;
left: 10px;
z-index: 999;
color: #000;
background: white;
padding: 10px 20px;
border-radius: 10px;
font-family: arial;
text-decoration: none;
box-shadow: rgb(50 50 93 / 25%) 0 0 100px -20px, rgb(0 0 0 / 30%) 0 0 60px -15px;
}
.read-article:hover{
background: #d5d5d5;
box-shadow: rgb(50 50 93 / 25%) 0 0 100px -20px, rgb(0 0 0 / 30%) 0 0 60px 0px;
}
iframe[sandbox] .read-article{
display: none;
}
/**
* By Alvaro Trigo
* Follow me on Twitter: https://twitter.com/imac2
*/
(function(){
init();
var g_containerInViewport;
function init(){
setStickyContainersSize();
bindEvents();
}
function bindEvents(){
window.addEventListener("wheel", wheelHandler);
}
function setStickyContainersSize(){
document.querySelectorAll('.sticky-container').forEach(function(container){
const stikyContainerHeight = container.querySelector('main').scrollWidth;
container.setAttribute('style', 'height: ' + stikyContainerHeight + 'px');
});
}
function isElementInViewport (el) {
const rect = el.getBoundingClientRect();
return rect.top <= 0 && rect.bottom > document.documentElement.clientHeight;
}
function wheelHandler(evt){
const containerInViewPort = Array.from(document.querySelectorAll('.sticky-container')).filter(function(container){
return isElementInViewport(container);
})[0];
if(!containerInViewPort){
return;
}
var isPlaceHolderBelowTop = containerInViewPort.offsetTop < document.documentElement.scrollTop;
var isPlaceHolderBelowBottom = containerInViewPort.offsetTop + containerInViewPort.offsetHeight > document.documentElement.scrollTop;
let g_canScrollHorizontally = isPlaceHolderBelowTop && isPlaceHolderBelowBottom;
if(g_canScrollHorizontally){
containerInViewPort.querySelector('main').scrollLeft += evt.deltaY;
}
}
})();
This is pretty much exactly what I was looking for but I wonder:
If there isn´t a more intuitive package that does exactly this?
If this is really that "clean"
but mostly the problem here is, because there is an eventlistener on the window only for the mousewheel, which means when not scrolling down via the mouse wheel, but with the scrollbar at the right, it won´t work.
Do you have any more ideas, what you could use or is this actually as good as it can get?
Thanks!

Not able to make element stick to the bottom when offscreen in IE 11, just like in css sticky

I am trying to replicate the same behavior as in this
codepen in IE 11 (does not have css sticky)
I am able to detect when the item is offscreen at the start with:
if (
$(".main-content").height() + $(".main-content").offset().top <
$(".main-footer").offset().top
)
but then after it reaches the end of the scroll (in this case the page), I did not manage to check when it goes offscreen again. It is probably something simple as subtracting the scroll to figure out if the element is offscreen, I am just stuck...
Here is a codepen where I stuck am now.
IE doesn't support <main> so you can't use this tag in IE 11. You can monitor the scroll bar changes through JavaScript, and then change its class according to the position of the element.
Here is the code you can refer to:
$(document).scroll(function() {
var scroH = $(document).scrollTop();
var viewH = $(window).height();
var contentH = $(document).height();
$('.main-footer').addClass('main-footer1')
if (scroH > 100) {}
if (contentH - (scroH + viewH) <= 100) { // The height from the bottom is less than 100px
}
if (contentH <= (scroH + viewH + 100)) {
$('.main-footer').removeClass('main-footer1')
$('.main-footer').addClass('main-footer2')
} else {
$('.main-footer').addClass('main-footer1')
$('.main-footer').removeClass('main-footer2')
}
});
body {
color: #fff;
font-family: arial;
font-weight: bold;
font-size: 40px;
}
.main-container {
max-width: 600px;
margin: 0 auto;
border: solid 10px green;
padding: 10px;
margin-top: 40px;
}
.main-container * {
padding: 10px;
background: #aaa;
border: dashed 5px #000;
}
.main-container *+* {
margin-top: 20px;
}
.main-header {
height: 50px;
background: #aaa;
}
.main-content {
min-height: 1000px;
}
.main-footer {
border-color: red;
}
.main-footer1 {
position: fixed;
bottom: 0px;
margin: 0 auto;
width: 570px;
}
.main-footer2 {
position: relative;
margin-top: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-container">
<header class="main-header">HEADER</header>
<div class="main-content">MAIN contentH</div>
<footer class="main-footer">footer</footer>
</div>
Result in IE 11:

Why need to decrease clientHeight from windowHeight while calculating scrollPercent?

I am trying to show how much a user has scrolled through the page a with progress bar and I have done it. But I have a little confusion here.
Here is the code that I found to calculate scrollPercent which works well
windowHeight = Math.max(
html.clientHeight,
html.scrollHeight,
html.offsetHeight,
body.scrollHeight,
body.offsetHeight
);
const scrolledPercent =
((html.scrollTop || body.scrollTop) / (windowHeight - html.clientHeight)) *
100;
Initially, I thought, to get the scrollPercent , I need to get the current scrollPosition and divide that number with the total height of the page and multiply by 100% . which is like normally how we get % of something.
const scrolledPercent =
((html.scrollTop || body.scrollTop) / windowHeight) * 100;
but this line doesnot worked as I expected . If I do this the progress bar wont reach 100% even if I scroll to end of the page. I don't understand why am I wrong here !
So, my question is why do we need to decrease the html.clientHeight from windowHeight ?
Thank you.
Demo here:
// --------------------------------------------
// variables
// --------------------------------------------
const html = document.documentElement,
body = document.body,
countryList = document.querySelector(".country__list");
scrollNavigated = document.querySelector(".scroll__navigated");
let windowHeight;
// --------------------------------------------
// function
// --------------------------------------------
async function prepareListOfCountries() {
let list = await fetch("https://restcountries.eu/rest/v2/all");
list = Array.from(await list.json());
let markup = list
.map((country, index) => {
return `<li class="country__item card">
<span class="country__name">${country.name}</span
><span class="country__capital">${country.capital}</span>
<a href="javascript:;" class="country__flag">
<img src= '${country.flag}'> </a>
</li>`;
})
.slice(0, 30)
.join(" ");
countryList.innerHTML = markup;
}
function updateScrolledStatus(e) {
windowHeight = Math.max(
html.clientHeight,
html.scrollHeight,
html.offsetHeight,
body.scrollHeight,
body.offsetHeight
);
const scrolledPercent =
((html.scrollTop || body.scrollTop) / (windowHeight - html.clientHeight)) *
100;
// const scrolledPercent =
// ((html.scrollTop || body.scrollTop) / windowHeight) * 100; // this line doesnot work
scrollNavigated.style.width = scrolledPercent + "%";
}
prepareListOfCountries();
// --------------------------------------------
// event-handler
// --------------------------------------------
window.addEventListener("scroll", updateScrolledStatus);
*::after,
*::before,
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #fff;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}
.container {
max-width: 980px;
margin: 0 auto;
}
.justify-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.items-center {
display: flex;
align-items: center;
}
.card {
background-color: #fff;
box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.054);
border-radius: 4px;
padding: 16px;
}
.country__flag img {
height: 100%;
width: 100%;
}
.header {
padding: 24px 0;
background-color: #333;
color: #f1f1f1;
position: -webkit-sticky;
position: sticky;
}
.content {
padding: 50px 0;
}
.content__form {
margin: 0 auto;
margin-bottom: 32px;
}
.content__search {
width: 50%;
padding: 12px 16px;
border-radius: 20px;
border: 1px solid #ddd;
transition: 0.2s;
}
.content__search:hover {
box-shadow: 0 1px 6px 0 rgba(32, 33, 36, 0.28);
}
.content__search:focus {
outline: none;
}
.country__list {
margin-top: 50px;
margin: 10px auto;
}
.country__item {
display: flex;
justify-content: space-between;
margin-bottom: 16px;
}
.country__name, .country__capital, .country__flag {
width: 33.33%;
}
.country__flag {
width: 32px;
height: 24px;
}
.scroll__navigator {
height: 2px;
margin: 0 auto 32px;
background-color: #333;
position: -webkit-sticky;
position: sticky;
top: 0;
}
.scroll__navigated {
display: block;
height: 100%;
width: 0;
background: orangered;
transition: 0.3s linear;
}
<body>
<header class="header">
<div class="container">
All countries list
</div>
</header>
<main class="content">
<div class="container">
<form class="content__form">
<input class="content__search" />
</form>
<div class="scroll__navigator">
<span class="scroll__navigated"></span>
</div>
<section class="country">
<ul class="country__list">
<li class="country__item card">
<span class="country__name">Nepal</span
><span class="country__capital">Kathmandu</span>
</li>
</ul>
</section>
</div>
</main>
</body>
As an example, say that the height of your client is 100px and the height of your whole page is 500px.
When the scroll position is 0px, you're able to see the first 100px of your site, so from 0px to 100px.
At scroll position 100px, you can see the range 100px to 200px, because you've moved the page, and therefore the visible range, on by 100px.
At scroll position 400px, you can therefore see the range 400px to 500px – in other words, you've scrolled to the bottom.
This demonstrates that the scrollable height of the page (400px) is less than the actual height of the page (500px), namely by the height of the client.
To get the percentage scrolled, you need to use the scrollable height, so it is necessary to subtract the height of the client from the height of the page to get a correct value, or you'll never be able to scroll to the bottom. It's not possible to scroll by 500px on a site that is only 500px long!

Parallax Issue in Javascript

I was creating a parallax effect in which the image and the text move in opposite direction to the movement of the mouse. That is happening inside an element called parallax-wrapper. But when I move out of the element I want the image and the text to return back to their original positions. I have tried to detect the mouse position outside the element but for some reason it not firing properly.
The codepen link is - https://codepen.io/rohitgd/pen/gRLNad?editors=1010
HTML
<div class="parallax-wrapper">
<div class="layer" data-mouse-parallax="0.1">
<img src="https://tympanus.net/Development/MorphingBackgroundShapes/img/1.jpg"/>
</div>
<div class="layer" data-mouse-parallax="0.3">REVERT</div>
</div>
CSS
body {
background-color:#fff;
padding: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.parallax-wrapper {
width: 500px;
height: 300px;
background-color:#0c0c0c;
position: relative;
overflow: hidden;
.layer {
width: 80%;
height: 80%;
position: absolute;
left: 30px;
text-align: center;
line-height: 300px;
font-size: 38px;
color:#FFF;
transition: all 200ms ease-out;
}
}
img {
width: 200px;
height: 200px;
position: relative;
top: 50px;
right: 70px;
}
Javascript
$(".parallax-wrapper").mousemove(function(e) {
var x = e.pageX - $(this).offset().left - $(this).width() / 2;
var y = e.pageY - $(this).offset().top - $(this).height() / 2;
$("*[data-mouse-parallax]").each(function() {
var factor = parseFloat($(this).data("mouse-parallax"));
x = -x * factor;
y = -y * factor;
$(this).css({ transform: "translate3d( " + x + "px, " + y + "px, 0 )" });
});
});
$(document).mouseleave(function(e) {
var target = $(e.target);
if( !target.is("div.layer")) {
alert('out of the element');
e.stopPropagation();
}
});
What I want is when the mouse is outside the parallax-wrapper the Image and the text return back to their original positions.
You're not resetting the transformations when your mouse leaves. You need to add this where you have the alert...
$(".parallax-wrapper").mouseleave(function(e) {
$("*[data-mouse-parallax]").each(function() {
$(this).css({ transform: "translate3d( 0, 0, 0 )" });
});
});
Note that the mouseleave event is triggered when the mouse leaves .parallax-wrapper, not document as you previously had it.
Here's a modified codepen...
https://codepen.io/anon/pen/ZyBgYJ
I think a selector was wrong. Here's a correct version or see code below.
To show better when you are inside/outside I change the background color, that's better than an alert. When you leave the wrapper (the black background) it flips correctly now.
Where RED is set you can reset the transform to the origin.
// Trying to replicate the effect here - https://tympanus.net/Development/MorphingBackgroundShapes/
$(".parallax-wrapper").mousemove(function(e) {
var x = e.pageX - $(this).offset().left - $(this).width() / 2;
var y = e.pageY - $(this).offset().top - $(this).height() / 2;
$(".parallax-wrapper").css("background-color", "#00ff00"); // <-- EXIT
// reset transform here
$("*[data-mouse-parallax]").each(function() {
var factor = parseFloat($(this).data("mouse-parallax"));
x = -x * factor;
y = -y * factor;
$(this).css({ transform: "translate3d( " + x + "px, " + y + "px, 0 )" });
});
});
// this is the selector I changed from "document" to ".parallax-wrapper"
$(".parallax-wrapper").mouseleave(function(e) {
var target = $(e.target);
if( !target.is("div.layer")) {
$(".parallax-wrapper").css("background-color", "#ff0000"); // <-- ENTER
e.stopPropagation();
}
});
body {
background-color:#fff;
padding: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.parallax-wrapper {
width: 500px;
height: 300px;
background-color:#0c0c0c;
position: relative;
overflow: hidden;
.layer {
width: 80%;
height: 80%;
position: absolute;
left: 30px;
text-align: center;
line-height: 300px;
font-size: 38px;
color:#FFF;
transition: all 200ms ease-out;
}
}
img {
width: 200px;
height: 200px;
position: relative;
top: 50px;
right: 70px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parallax-wrapper">
<div class="layer" data-mouse-parallax="0.1">
<img src="https://tympanus.net/Development/MorphingBackgroundShapes/img/1.jpg"/>
</div>
<div class="layer" data-mouse-parallax="0.3">REVERT</div>
</div>
Replace $(document).mouseleave with $(".parallax-wrapper").mouseleave.
$(".parallax-wrapper").mousemove(function(e) {
var x = e.pageX - $(this).offset().left - $(this).width() / 2;
var y = e.pageY - $(this).offset().top - $(this).height() / 2;
$("*[data-mouse-parallax]").each(function() {
var factor = parseFloat($(this).data("mouse-parallax"));
x = -x * factor;
y = -y * factor;
$(this).css({ transform: "translate3d( " + x + "px, " + y + "px, 0 )" });
});
});
$(".parallax-wrapper").mouseleave(function(e) {
alert('out of the element');
});
body {
background-color: #fff;
padding: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.parallax-wrapper {
width: 500px;
height: 300px;
background-color: #0c0c0c;
position: relative;
overflow: hidden;
}
.parallax-wrapper .layer {
width: 80%;
height: 80%;
position: absolute;
left: 30px;
text-align: center;
line-height: 300px;
font-size: 38px;
color: #FFF;
transition: all 200ms ease-out;
}
img {
width: 200px;
height: 200px;
position: relative;
top: 50px;
right: 70px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parallax-wrapper">
<div class="layer" data-mouse-parallax="0.1">
<img src="https://tympanus.net/Development/MorphingBackgroundShapes/img/1.jpg"/>
</div>
<div class="layer" data-mouse-parallax="0.3">REVERT</div>
</div>

How to create this range bar using JavaScript?

.range {-moz-box-sizing: border-box;box-sizing: border-box;-webkit-background-clip: padding-box;background-clip: padding-box;vertical-align: top;outline: none;line-height: 1;-webkit-appearance: none;-webkit-border-radius: 4px;border-radius: 4px;border: none;height: 2px;-webkit-border-radius: 0;border-radius: 0;-webkit-border-radius: 3px;border-radius: 3px;background-image: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd));background-image: -webkit-linear-gradient(#ddd, #ddd);background-image: -moz-linear-gradient(#50b1f9, #50b1f9);background-image: -o-linear-gradient(#ddd, #ddd);background-image: linear-gradient(#50b1f9,#50b1f9);background-position: left center;-webkit-background-size: 100% 2px;background-size: 100% 2px;background-repeat: no-repeat;overflow: hidden;height: 31px;}
.range::-moz-range-track {position: relative;border: none;background-color: #50b1f9;height: 2px;border-radius: 30px;box-shadow: none;top: 0;margin: 0;padding: 0;}
.range::-webkit-slider-thumb {cursor: pointer;-webkit-appearance: none;position: relative;height: 29px;width: 29px;background-color: #fff;border: 1px solid #ddd;-webkit-border-radius: 30px;border-radius: 30px;-webkit-box-shadow: none;box-shadow: none;top: 0;margin: 0;padding: 0;}
.range::-moz-range-thumb {cursor: pointer;position: relative;height: 15px;width: 15px;background-color:#fff;border: 1px solid #ddd;border-radius: 30px;box-shadow: none;margin: 0;padding: 0}
.range::-webkit-slider-thumb:before {position: absolute;top: 13px;right: 0px;left: -1024px;width: 1024px;height: 2px;background-color: #50b1f9;;content: '';margin: 0;padding: 0;}
.range:disabled {opacity: 0.3;cursor: default;pointer-events: none;}
<input type="range" class="range">
I have to make this range bar and when I slide the months will also change accordingly. I tried making it into css but for changing range I would need JavaScript.
var range = document.getElementById("range"),
progress = document.getElementById("progress"),
handle = document.getElementById("handle"),
valueBox = document.getElementById("value"),
movable = false,
offsetX = range.offsetLeft,
rangeWidth = range.offsetWidth,
handleWidth = handle.offsetWidth,
max = 100, left, mouseX, value;
function move(e) {
if ( movable === true ) {
left = e.clientX - offsetX;
handle.style.left = left - ( handleWidth / 2 ) + "px";
progress.style.width = left + "px";
if ( left >= rangeWidth ) {
handle.style.left = rangeWidth - ( handleWidth / 2 ) + "px";
progress.style.width = rangeWidth + "px";
} if ( left <= 0 ) {
handle.style.left = "-" + handleWidth / 2 + "px";
progress.style.width = "0px";
}
value = Number(parseFloat(progress.style.width) / ( rangeWidth / max )).toFixed(0);
valueBox.textContent = value;
}
};
function on(e) {
movable = true;
mouseX = e.clientX;
};
function off() {
movable = false;
};
handle.addEventListener("mousedown", on, false);
window.addEventListener("mousemove", move, false);
window.addEventListener("mouseup", off, false);
* { margin: 0; padding: 0; border: 0; outline: 0; }
body { background-color: #FF0000; }
#range {
width: 350px;
height: 14px;
background-color: #242424;
margin: 100px auto 15px;
border-radius: 50px;
position: relative;
}
#progress {
position: absolute;
top: 0;
left: 0;
height: 100%;
background-color: #00A79D;
border-radius: 50px;
}
#handle {
position: absolute;
top: -3px;
height: 20px;
width: 20px;
background-color: #eee;
border-radius: 50px;
cursor: pointer;
}
#handle:hover, #handle:active {
background-color: #ddd;
}
#value-box {
text-align: center;
font: 14px arial;
line-height: 35px;
color: #eee;
width: 170px;
height: 35px;
background-color: rgba(0, 0, 0, .2);
margin: auto;
border-radius: 2px;
}
<div id="range">
<div id="progress"></div>
<div id="handle"></div>
</div>
<div id="value-box">Range bar Value : <span id="value">0</span></div>
Check output in Snippet Also.
Finally Output :

Categories

Resources