Suppose I have 5 divs with 100vh height each in a container.
<div class="mycontainer" >
<div id="diview0" class="diview">0</div>
<div id="diview1" class="diview">1</div>
<div id="diview2" class="diview">2</div>
<div id="diview3" class="diview">3</div>
<div id="diview4" class="diview">4</div>
<div id="diview5" class="diview">5</div>
<div id="diview6" class="diview">6</div>
<div id="diview7" class="diview">7</div>
<div id="diview8" class="diview">8</div>
<div id="diview9" class="diview">9</div>
</div>
I scroll in that container but what happens is if a scroll up then it scrolls the div too much.
What I want is that it scroll a limited portion only.
For ex: if I scroll down 100px then it's good but on more than that(like 200 or 300) it should only scroll down 110px
same goes for scrolling up if I scroll up 100px then it's good but on more than that(like 200 or 300) it should only scroll up 110px.
Requirement is only of JavaScript. No jQuery or any other external library can be used.
How can I do it?
This is a way of doing it:
let maxS = 110;
let t = 2;
function isScrollable(x) {
let y = (Boolean(x))?"auto":"hidden";
document.documentElement.style.setProperty("overflow", y);
}
function timeoutScroll() {
let a = window.pageYOffset;
const temp = setInterval(function() {
if (window.pageYOffset >= a + maxS || window.pageYOffset <= a - maxS) {isScrollable(false)}},
100)
setTimeout(function() {isScrollable(true); clearInterval(temp)}, t*1000);
}
And the timeoutScroll function would stop scrolling the page for t seconds for more than maxS pixels
Related
I'm trying to implement an animation that switches images on scroll when it's wrapping div scrolls into the viewport. My problem is that the animation starts as soon as someone starts scrolling, so the animation is already at the end when #wrapper comes into viewport.
How to achieve that the animation starts when #wrapper scrolls into the viewport?
Unfortunately my JS/jQuery knowledge is very poor but this is what I got til now:
JSFiddle
HTML:
<div class="page_content_before_image_animation">
<p>lorem ipsum …</p>
</div>
<div id="load" data-images="19"></div>
<div id="wrapper">
<img class="sequenzbilder" src="https://twdp.de/sequence/1.jpg" width="600" height="661" />
</div>
JS:
var images = [];
for (i = 1; i <= $('#load').attr('data-images'); i++) {
images.push('https://twdp.de/sequence/' + i + '.jpg');
}
$(images).each(function() {
$('<img class="sequenzbilder" />')[0].src = this;
});
var totalImages = images.length;
var pageHeight = $(document).height() - $(window).height();
var scrollInterval = Math.floor(pageHeight / 140);
var viewport = $(window),
slowdown;
viewport.on('scroll', function() {
i = Math.floor($(this).scrollTop() / scrollInterval);
$('.sequenzbilder').attr('src', images[i]);
slowdown = Math.ceil(viewport.scrollTop() / 20);
});
I am trying to create a scrolling animation with 2 divs and 2 images.
For lack of a better explanation (as you might have guessed from the title) I have made a quick animation showcasing what I am trying to achieve.
here is a hosted version that I made earlier. I tried to create the effect with the help of parallax scrolling, but it's not quite what I want.
It's a Zeit Now deployment, so you can append /_src to the url and take a look at the source code.
Now I am not sure if this is even the correct way to create the animation and to be honest I wouldn't know any other way that I could approach this.
So I am not asking for a fully-fledged answer without any flaws (although it would be much appreciated), but rather a nudge in the right direction.
Made this quickly so there might be some issues, I tried to make the variables somehow general so you can play with things (check this fiddle)
const body = document.body,
html = document.documentElement;
const targetImg = document.querySelector('.second');
// our image's initial height
const imgHeight = targetImg.clientHeight;
// the final value for image height (at scroll end)
const imgTargetHeight = 0;
// total height of our document
const totalHeight = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
// visible window height
const windowHeight = window.innerHeight;
// starting scroll position we want to start calculations from (at this point and before, our image's height should equal its initial height 'imgHeight')
const fromScroll = 0;
// final scroll position (at this point and after, our image's height should equal 'imgTargetHeight')
const toScroll = totalHeight - windowHeight;
window.addEventListener('scroll', function() {
// get current scroll position, these multiple ORs are just to account for browser inconsistencies.
let scrollPos = window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop;
// force the scroll position value used in our calculation to be between 'fromScroll` and 'toScroll'
// In this example this won't have any
// effect since fromScroll is 0 and toScroll is the final possible scroll position 'totalHeight - windowHeight',
// but they don't have to be, try setting fromScroll = 100 and toScroll = totalHeight - windowHeight - 100 for example to see the difference.
// the next line is just a shorthand for:
// if (scrollPos <= fromScroll) {
// scrollPos = fromScroll;
// } else if (scrollPos >= toScroll) {
// scrollPos = toScroll;
// } else {
// scrollPos = scrollPos;
// }
scrollPos = scrollPos <= fromScroll ? fromScroll : (scrollPos >= toScroll ? toScroll : scrollPos);
// our main calculation, how much should we add to the initial image height at our current scroll position.
const value = (imgTargetHeight - imgHeight) * (scrollPos - fromScroll) / (toScroll - fromScroll);
targetImg.style.height = imgHeight + value + "px";
});
.container {
height: 200vh;
}
.img-container {
position: fixed;
width: 100vw;
height: 100vh;
text-align: center;
background: white;
overflow: hidden;
}
.second {
background: tomato;
}
img {
position: absolute;
left: 50vw;
top: 50vh;
transform: translate(-50%, -50%);
}
<div class="container">
<div class="img-container first">
<img src="https://fixedscrollingtest-takidbrplw.now.sh/luigi.png" alt="">
</div>
<div class="img-container second">
<img src="https://fixedscrollingtest-takidbrplw.now.sh/mario.png" alt="">
</div>
</div>
I'm trying to change the opacity of a DIV based on how much is visible (height-wise) in the window. For example if 50% of the DIV is visible in the window then the opacity should be .5
Here is what I've got, I know it's amateur and not optimal code. It's my math that is the problem. When the DIV is roughly 50% on the screen, with my calculations it comes out to around 80%
$(window).scroll(function () {
var block = $('.block')
var blockHeight = block.outerHeight();
var bottom_of_block = block.offset().top + blockHeight;
var blockOpacity = 0;
if (bottom_of_block < ($(window).height() + $(window).scrollTop())) {
// Sets opacity to 1 if div is completely on screen
blockOpacity = 1;
} else {
// This is the math that I cant figure out completely
blockOpacity = ($(window).height() + $(window).scrollTop()) / (bottom_of_block);
}
block.css('opacity', blockOpacity);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height: 500px"></div>
<div class="block" style="background: blue;height: 220px;width: 220px;"></div>
I think you need to calculate blockOpacity like this:
blockOpacity = ($(window).height() + $(window).scrollTop() - block.offset().top) / blockHeight;
I have a problem with dynamically added div's and adjusting parent's height according to dynamically added content.
So, I have a div called #full-content-wrap and it's width divided with two child elements. These element's are called .doubled-wrap-content-left and .doubled-wrap-content-right (let's call it left wrap and right wrap). So, then, I have a two links (or buttons, or whatever) so when I click on one of these links, javascript add a element .doubled-table dynamically to left or right wrap (according which link i clicked). So, but I have a bit problem with setting height of #full-content-wrap or left/right wrap.
When I set a full-cont-wrap's height to auto, and l-r wrap's height to auto too, it's still 0px. When I set 100% - auto it's still 100% and added elements are overflowing off the parent element. So I've done it this way. I have created a function that adjusts height of full-cont-wrap to biggest height of it's content (left or right wrap) and when it's empty, to window.innerHeight. But, it's kinda uncomfortable and it has two minuses. The first one is that when I change size of my browser, then I reload page and maximize window, the height is smaller than innerHeight of maximized window (this happens when I open inspect element function). The second one is as you can realise, it's unnecessary JS counting and setting of height.
Question is: How to do this simply in CSS without JS?
Things like: Divs are floating etc. I know and I have tried set display to every value.
Additional questions comment please :/
<div id="full-content-wrap">
<div id="section-name">
<span>Dashboard</span>
<span class="section-subname">statistics and more</span>
</div>
<div id="doubled-wrap-content">
<div id="doubled-wrap-content-left">
<div class="doubled-table">
<div class="table-header">
<div class="caption">
<span class="fa fa-cogs"></span>
<span class="caption-content">Server Control</span>
</div>
<div class="tools">
<div class="picon-collapse"></div>
<div class="picon-remove"></div>
</div>
</div>
<div class="table-body"></div>
</div>
</div>
<div id="doubled-wrap-content-right">
</div>
</div>
function setContentWrap () {
/* Set width for full-wrap-content */
var width = screen.width;
width -= 220;
var percent = ((width * 100) / screen.width);
$("#full-content-wrap").css({ width: percent + '%' });
/* Set height for full-wrap-content */
var left = $('#doubled-wrap-content-left')[0].offsetHeight;
var right = $('#doubled-wrap-content-right')[0].offsetHeight;
var sidePanel = $('.side-panel-menu')[0].offsetHeight;
var side = false;
var bigger = 0, b = "";
if (left > right) { bigger = left; b = "left"; }
else if (right > left) { bigger = right; b = "right"; }
else if (right == left) { bigger = right || left; }
if (bigger < sidePanel) {
bigger = sidePanel;
side = true;
}
var height = 0, j = 0;
$('#full-content-wrap').each(function () {
var n = this.children;
var length = this.children.length;
for ( var i = 0; i < length; i++ ) {
if (n[i].id == 'doubled-wrap-content') break;
height += n[i].style.height || n[i].offsetHeight;
j++;
}
});
var more = 0;
$('#doubled-wrap-content').each(function () {
if ( more < this.children.length ) {
more = this.children.length;
}
});
if (side == false) {
height += bigger + (more * 60);
} else {
height = window.innerHeight;
}
$('#full-content-wrap').css({ minHeight: height + 'px' });
var setTo = window.innerHeight;
if (parseInt($('#full-content-wrap').css('minHeight'), 10) < window.innerHeight) {
$('#full-content-wrap').css({ height: setTo + 'px' });
//$('#full-content-wrap').css({ height: '100%' });
}
}
Hope it's all. Because those spaces here are ....ooh
Working with this existing codepen (http://codepen.io/anon/pen/fDqdJ). I want to add another statement whereby at a certain distance from the top of the page, an already animated div then changes in scale whilst moving.
Really struggling with the syntax and to increment the scale of the animated div on the scroll. I'm guessing that I will need to use css transform, but need some help!
Please see below for js example:
var $window = $(window);
var $box = $("#box");
$window.scroll(function() {
var scrollTop = $window.scrollTop();
console.log(scrollTop);
if (scrollTop >= 250 && scrollTop < 400) {
$box.css({top: -250 + scrollTop});
} else if(scrollTop >= 400 && scrollTop < 460) {
$box.css({left: (10+(scrollTop-400)/2)+"%"})
} else if(scrollTop >= 460 && scrollTop < 580) {
$box.css({top: (50+(scrollTop-460)/2)+"%"})
} else if(scrollTop >= 580 && scrollTop < 620) {
$box.css('transform', 'scale(' + whateverTheScaleShouldBe + ')');
}
});
Here is the html structure -
<div class="wrapper">
<div class="row" id="row1">
</div>
<div class="row" id="row2">
<div id="box"></div>
</div>
<div class="row" id="row3">
</div>
<div class="row" id="row4">
</div>
</div>
Any help much appreciated! :)
J
The problem with this code:
$box.css({transform:scale(1.1)})
...is that the value is incorrect. The value to set for the CSS property should be a string. As it is currently, the code is trying to call a scale function in your JavaScript, which probably doesn't exist. If you want to use the CSS function scale, replace the code with this:
$box.css({transform: 'scale(1.1)'});
Or more simply:
$box.css('transform', 'scale(1.1)');
...then you'll change the CSS scale. You're probably also wanting to use a dynamic value for the scale CSS function. Doing that will be a matter of making the string dynamic:
$box.css('transform', 'scale(' + whateverTheScaleShouldBe + ')');
This whateverTheScaleShouldBe will be whatever your calculation is; it's not clear from your question how you want the scale to change as you scroll. If you wanted the scale to linearly grow by 0.1 per 100px, as an example, you could do this:
scaleAmt = 1.0 + (scrollTop / 100);
$box.css('transform', 'scale(' + scaleAmt + ')');