I'm trying to decrease he opacity of an image while scrolling.
It should be like fade out
var scrollPercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
if(scrollPercent < 0.25){
var myImage3 = document.getElementById('wheat-image-main3');
myImage3.style.opacity = '1'
}
if(scrollPercent > 0.25){
var myImage3 = document.getElementById('wheat-image-main3');
myImage3.style.opacity = '0'
}
You just have to wrap it in a scroll event listener and it'll work:
const myImage3 = document.getElementById('wheat-image-main3');
document.addEventListener('scroll', (e) => {
var scrollPercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
if(scrollPercent < 0.25){
myImage3.style.opacity = '1'
}
if(scrollPercent > 0.25){
myImage3.style.opacity = '0'
}
})
body {
height: 200vh;
}
#wheat-image-main3 {
transition: opacity 125ms ease-in-out;
opacity: 1;
}
<img id="wheat-image-main3" src="//placehold.it/200/200" alt="">
You need to add scroll event listener.
addEventListener("scroll", (event) => {
if(scrollPercent < 0.25){
var myImage3 = document.getElementById('wheat-image-main3');
myImage3.style.opacity = '1'
}
if(scrollPercent > 0.25){
var myImage3 = document.getElementById('wheat-image-main3');
myImage3.style.opacity = '0'
}
})
You have to listen the scroll events to get this work. Below is an example, but you can achieve this working with CSS class as well and classList property.
const img = document.querySelector('.image')
document.addEventListener('scroll', (e) => {
if(this.scrollY >= 100) {
img.style.opacity = "0.5"
}
else {
img.style.opacity = "1"
}
})
<img src="" height="500" class="image" />
Related
I've created the following functionality where an image is fixed on the left while scrolling the content and the quote appears for a few pixels.
It's working all right, the only problem is that I'd like to add this many times on the same page and, as it is, it just works with the first image.
The second one is not fixed while scrolling and the quote maintains hidden...
How can I make run this function for every image?
This is a working example
HTML:
<section id="cont_quote" class="maxwidth">
<article class="cont_q hasImage">
<p>Content</p>
<img class="alignleft img_quote" src="/large.jpg" alt="" width="433" height="553" />
<blockquote>
<h3>Why this training plan works</h3>
</blockquote>
<p>Content</p>
</article>
</section>
JS:
// Stick image on scroll
$(window).on('load resize', function () {
if ($(window).width() >= 769) {
var $element = $('#cont_quote');
var $follow = $element.find('.img_quote');
var followHeight = $element.find('.img_quote').outerHeight();
var height = $element.outerHeight() - 300;
var window_height = $(window).height();
$(window).scroll(function () {
var pos = $(window).scrollTop();
var top = $element.offset().top;
// Check if element is above or totally below viewport
if (top + height - followHeight < pos || top > pos + window_height) {
return;
}
var offset = parseInt($(window).scrollTop() - top);
if (offset > 0) {
$follow.css('transform', 'translateY('+ offset +'px)');
}
})
}
});
// Quote show on viewport
function inViewport( element, viewport = { top: 0, bottom: innerHeight } ){
// Get the elements position relative to the viewport
var bb = element.getBoundingClientRect();
// Check if the element is outside the viewport
// Then invert the returned value because you want to know the opposite
return !(bb.top > viewport.bottom || bb.bottom < viewport.top);
}
var myViewport = { top: innerHeight * .5, bottom: innerHeight * .6 };
var myElement = document.querySelector( '#cont_quote blockquote' );
// Listen for the scroll event
document.addEventListener( 'scroll', event => {
// Check the viewport status
if( $(window).width() >= 600 ){
if( inViewport( myElement, myViewport ) && $('.cont_q').hasClass('hasImage') ) {
if( $(window).width() >= 769 ){
myElement.style.opacity = 1;
myElement.style.left = '-25%';
} else {
myElement.style.opacity = 1;
myElement.style.left = '-5%';
}
} else if( inViewport( myElement, myViewport )) {
if( $(window).width() >= 769 ){
myElement.style.opacity = 1;
myElement.style.left = '-15%';
} else {
myElement.style.opacity = 1;
myElement.style.left = '13%';
}
} else {
myElement.style.opacity = 0;
myElement.style.left = '-40%';
}
} else {
myElement.style.opacity = 1;
myElement.style.left = '5%';
}
});
I want to make a page scroll down slowly and smoothly. Well, the speed should actually adjustable. The user should also be able to scroll up manually while the script is scrolling down. First I tried this:
var autoScrollDelay = 1
var autoScrollSpeed = 1
var autoScrollTimer
function setAutoScroll(newValue) {
autoScrollSpeed = newValue ? newValue : autoScrollSpeed
if (autoScrollTimer) {
clearInterval(autoScrollTimer)
}
if (autoScrollDelay) {
autoScrollTimer = setInterval(function(){
window.scrollBy(0,autoScrollSpeed)
},autoScrollDelay)
}
}
setAutoScroll(1) // higher number = faster scrolling
But it was causing a very heavy CPU load and the slowest speed was too fast. And in addition to that manually scrolling up did not work properly while the code was running.
Then I tried:
var autoScrollDelay = 1
var autoScrollSpeed = 1
var autoScrollTimer
function setAutoScroll(newValue) {
autoScrollDelay = newValue ? newValue : autoScrollDelay //using autoScrollDelay instead of autoScrollSpeed
if (autoScrollTimer) {
clearInterval(autoScrollTimer)
}
if (autoScrollDelay) {
autoScrollTimer = setInterval(function(){
window.scrollBy(0,autoScrollSpeed)
},autoScrollDelay)
}
}
setAutoScroll(200) // higher number scrolls slower
But the scrolling was not smooth when setting it too slow (e.g. 200).
Then I tried:
$("html, body").animate({
scrollTop: $('html, body').get(0).scrollHeight,
}, 40000, "linear");
But again the CPU load was unreasonably high and scrolling up or down manually wasn't possible this way.
Is there a better way to do this?
Here is one possible implementation. The refresh rate is fixed, and corresponds to fps in the code below. To make sure that the speed is constant, I consider the time elapsed since the previous scroll when calculating the new scroll position. Manual scrolling is allowed (with the scroll bar, with the mouse wheel, or with touch on mobile devices) and taken into account by processing scroll, wheel and touchmove events. You can see the code at work in this codepen.
var fps = 100;
var speedFactor = 0.001;
var minDelta = 0.5;
var autoScrollSpeed = 10;
var autoScrollTimer, restartTimer;
var isScrolling = false;
var prevPos = 0, currentPos = 0;
var currentTime, prevTime, timeDiff;
window.addEventListener("scroll", function (e) {
// window.pageYOffset is the fallback value for IE
currentPos = window.scrollY || window.pageYOffset;
});
window.addEventListener("wheel", handleManualScroll);
window.addEventListener("touchmove", handleManualScroll);
function handleManualScroll() {
// window.pageYOffset is the fallback value for IE
currentPos = window.scrollY || window.pageYOffset;
clearInterval(autoScrollTimer);
if (restartTimer) {
clearTimeout(restartTimer);
}
restartTimer = setTimeout(() => {
prevTime = null;
setAutoScroll();
}, 50);
}
function setAutoScroll(newValue) {
if (newValue) {
autoScrollSpeed = speedFactor * newValue;
}
if (autoScrollTimer) {
clearInterval(autoScrollTimer);
}
autoScrollTimer = setInterval(function(){
currentTime = Date.now();
if (prevTime) {
if (!isScrolling) {
timeDiff = currentTime - prevTime;
currentPos += autoScrollSpeed * timeDiff;
if (Math.abs(currentPos - prevPos) >= minDelta) {
isScrolling = true;
window.scrollTo(0, currentPos);
isScrolling = false;
prevPos = currentPos;
prevTime = currentTime;
}
}
} else {
prevTime = currentTime;
}
}, 1000 / fps);
}
setAutoScroll(20);
The function from this article uses vanilla JS to implement smooth scrolling at various speeds. Here is a demo:
document.getElementById("scrollBottomButton").onclick = function() {
var duration = document.getElementById("bottomScrollDuration").value * 1000;
scrollIt(document.querySelector("#bottom-row"), duration, "easeOutQuad");
};
document.getElementById("scrollTopButton").onclick = function() {
var duration = document.getElementById("topScrollDuration").value * 1000;
scrollIt(document.getElementById("top-row"), duration, "easeOutQuad");
};
// thanks to https://pawelgrzybek.com/page-scroll-in-vanilla-javascript/
function scrollIt(destination, duration = 200, easing = "linear", callback) {
const easings = {
linear(t) {
return t;
},
easeOutQuad(t) {
return t * (2 - t);
}
};
const start = window.pageYOffset;
const startTime = "now" in window.performance
? performance.now()
: new Date().getTime();
const documentHeight = Math.max(
document.body.scrollHeight,
document.body.offsetHeight,
document.documentElement.clientHeight,
document.documentElement.scrollHeight,
document.documentElement.offsetHeight
);
const windowHeight =
window.innerHeight ||
document.documentElement.clientHeight ||
document.getElementsByTagName("body")[0].clientHeight;
const destinationOffset = typeof destination === "number"
? destination
: destination.offsetTop;
const destinationOffsetToScroll = Math.round(
documentHeight - destinationOffset < windowHeight
? documentHeight - windowHeight
: destinationOffset
);
if ("requestAnimationFrame" in window === false) {
window.scroll(0, destinationOffsetToScroll);
if (callback) {
callback();
}
return;
}
function scroll() {
const now = "now" in window.performance
? performance.now()
: new Date().getTime();
const time = Math.min(1, (now - startTime) / duration);
const timeFunction = easings[easing](time);
window.scroll(
0,
Math.ceil(timeFunction * (destinationOffsetToScroll - start) + start)
);
if (window.pageYOffset === destinationOffsetToScroll) {
if (callback) {
callback();
}
return;
}
requestAnimationFrame(scroll);
}
scroll();
}
// scroll testing
var middleHtml = [];
const schiller = "Nur Beharrung führt zum Ziel, Nur die Fülle führt zur Klarheit, Und im Abgrund wohnt die Wahrheit.".split(' ')
for(var i=0; i<schiller.length;i+=1){
middleHtml.push("<div class=' container row' id='scrolling'><h1 style='margin: 30rem 10rem 30rem 0;font-size: 3.5em;font-family: Helvetica, sans-serif;color: #fff;'>"+schiller[i]+"</h1></div>");
}
document.getElementById('middle').innerHTML = middleHtml.join('');
.container-fluid {
background: #e52d27;
background: -webkit-linear-gradient(to top, #b31217, #e52d27);
background: linear-gradient(to top, #b31217, #e52d27);
}
.container-fluid input, .container-fluid .btn {
border-radius: 0;
}
.btn {
background: rgba(210,200,200,0.95);
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class='container-fluid'>
<div class='row' id='top-row'>
<div class='col-sm-8'>
<input class='form-control' id='bottomScrollDuration' placeholder='Enter duration in seconds (4, 25, 40, etc...)' />
</div>
<div class='col-sm-4'>
<button class='btn' id='scrollBottomButton'>Scroll to bottom</button>
</div>
</div>
<div id='middle'>
</div>
<div class='row' id='bottom-row'>
<div class='col-sm-8'>
<input class='form-control' id='topScrollDuration' placeholder='Enter duration in seconds (4, 25, 40, etc...)' />
</div>
<div class='col-sm-4'>
<button class='btn' id='scrollTopButton'>Scroll to top</button>
</div>
</div>
</div>
See CodePen Demo
Update
You could try this if you just want to adjust the speed and keep a constant scrolling behavior:
function pageScroll(speed) {
window.scrollBy(0,1);
scrolldelay = setTimeout(pageScroll,speed);
}
And then call the function with a speed of your choice i.e.:
pageScroll(1);
I ran it in Chrome, and it didn't tax my CPU usage. The CPU does spike more when it's run in Firefox.
I need to reverse this code:
$(window).scroll(function () {
$('#portfolio-entrybox li').each(function (i) {
var oTop = $(this).offset().top;
var oHeight = $(this).outerHeight();
var wTop = $(window).scrollTop();
var wHeight = $(window).height();
if (oTop < wTop + wHeight) {
var diff = ((wTop + wHeight - oTop) / oHeight);
if (diff > 1) diff = 1;
else if (diff < 0) diff = 0;
$(this).css('opacity', diff);
}
});
});
I need the items to fade at the top instead of fading on the bottom. They should start with opacity 100% and as you scroll down the it changes to 0%. Same principal as this code instead just reversed.
Fiddle with live demo.
Here's how I did it:
Change your if-statement to this:
if (oTop < wTop) {
var diff = ((wTop - oTop) / oHeight);
if (diff >= 1) diff = 1;
else if (diff <= 0) diff = 0;
diff = 1 - diff;
$(this).css('opacity', diff);
}
Updated Fiddle.
The above solution doesn't seem to work right according to what my browser seems to be doing (check out http://i.imgur.com/5AbwOuY.png).
However, I also made an attempt at this which you can view here: http://jsfiddle.net/RrBEV/70/
$(window).scroll(function () {
$('#portfolio-entrybox li').each(function (i) {
var oTop = $(this).offset().top;
var oHeight = $(this).outerHeight();
var wTop = $(window).scrollTop();
var wHeight = $(window).height();
if (oTop + oHeight > wTop) {
var diff = ((oTop + oHeight - wTop) / oHeight);
if (diff > 1) diff = 1;
else if (diff < 0) diff = 0;
$(this).css('opacity', diff);
}
});
});
I did jquery slider using this tutorial
http://css-plus.com/2010/09/create-your-own-jquery-image-slider/
, where the pictures are sliding automatically, but just once. How can I make them circle in an infinite loop?
on-line example :
www.vytvarkajablonec.jecool.net/ati
I'd really appreciate your help!
Replace the JS code from tutorial for this:
$(document).ready(function () {
// Gallery
if (jQuery("#gallery").length) {
// Declare variables
var totalImages = jQuery("#gallery > li").length,
imageWidth = jQuery("#gallery > li:first").outerWidth(true),
totalWidth = imageWidth * totalImages,
visibleImages = Math.round(jQuery("#gallery-wrap").width() / imageWidth),
visibleWidth = visibleImages * imageWidth,
stopPosition = (visibleWidth - totalWidth);
jQuery("#gallery").width(totalWidth);
jQuery("#gallery-prev").click(function () {
if (jQuery("#gallery").position().left < 0 && !jQuery("#gallery").is(":animated")) {
jQuery("#gallery").animate({
left: "+=" + imageWidth + "px"
});
}
if (jQuery("#gallery").position().left === 0) {
jQuery("#gallery > li:last").prependTo($("#gallery"));
}
return false;
});
jQuery("#gallery-next").click(function () {
if (jQuery("#gallery").position().left > stopPosition && !jQuery("#gallery").is(":animated")) {
jQuery("#gallery").animate({
left: "-=" + imageWidth + "px"
});
}
if (jQuery("#gallery").position().left === stopPosition) {
jQuery("#gallery > li:first").appendTo($("#gallery"));
}
return false;
});
}
});
Just animate the gallary back to it's initial position if it is at the end of the gallary.
var oGallary = $('#gallery');
var gallarWidth = oGallary.width();
if(oGalary.position().left > stopPosition && oGallary.is(":animated") == false)
{
oGallary.animate({left : "-=" + imageWidth + "px"});
}
else if ( oGalary.position().left <= stopPosition && oGallary.is(":animated") == false )
{
oGallary.animate({left : "+=" + gallaryWidht + "px"}) // Get full length of the entire gallary
}
I'm trying to make 'dark' area when my modal window is opened. Here is what I wrote: the first function f_documentSize will return size of the window, the second one will make fullwindow div.
It works great but there are scrollbars (vertical and horizontal). When I scroll them the page makes bigger (free space). Why?
function f_documentSize () {
var n_scrollX = 0,
n_scrollY = 0;
if (typeof(window.pageYOffset) == 'number') {
n_scrollX = window.pageXOffset;
n_scrollY = window.pageYOffset;
}
else if (document.body && (document.body.scrollLeft || document.body.scrollTop )) {
n_scrollX = document.body.scrollLeft;
n_scrollY = document.body.scrollTop;
}
else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
n_scrollX = document.documentElement.scrollLeft;
n_scrollY = document.documentElement.scrollTop;
}
if (typeof(window.innerWidth) == 'number')
return [window.innerWidth, window.innerHeight, n_scrollX, n_scrollY];
if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight))
return [document.documentElement.clientWidth, document.documentElement.clientHeight, n_scrollX, n_scrollY];
if (document.body && (document.body.clientWidth || document.body.clientHeight))
return [document.body.clientWidth, document.body.clientHeight, n_scrollX, n_scrollY];
return [0, 0];
}
function f_putScreen (b_show) {
if (b_show == null && !window.b_screenOn)
return;
if (b_show == false) {
window.b_screenOn = false;
if (e_screen) e_screen.style.display = 'none';
return;
}
if (window.e_screen == null) {
window.e_screen = document.createElement("div");
e_screen.innerHTML = " ";
document.body.appendChild(e_screen);
e_screen.style.position = 'absolute';
e_screen.id = 'eScreen';
if (document.addEventListener) {
window.addEventListener('resize', f_putScreen, false);
window.addEventListener('scroll', f_putScreen, false);
}
if (window.attachEvent) {
window.attachEvent('onresize', f_putScreen);
window.attachEvent('onscroll', f_putScreen);
}
else {
window.onresize = f_putScreen;
window.onscroll = f_putScreen;
}
}
// set properties
var a_docSize = f_documentSize();
e_screen.style.left = a_docSize[2] + 'px';
e_screen.style.top = a_docSize[3] + 'px';
e_screen.style.width = a_docSize[0] + 'px';
e_screen.style.height = a_docSize[1] + 'px';
e_screen.style.zIndex = 1000;
e_screen.style.display = 'block';
}
Try setting the "modal background" DIV's display style to position:absolute and set its left, top, right, and bottom properties to 0. Also make sure its margin is 0.
#modalDiv {
position:absolute;
background-color: #CCCCCC;
-moz-opacity: 0.5;
opacity: 0.5;
filter:alpha(opacity=50);
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: 0;
z-index: 9999 /* where 10K is the dialog and 9999 > everything else */
}