bluring background when mousewheel scrolling - javascript

I was referring to the following link to blur background on mouse scroll.
http://codepen.io/sotayamashita/pen/pqLcv
The code is shown as below:
HTML:
<div id="blurred-image-container">
<div class="img-src" style="background-image:url('https://d262ilb51hltx0.cloudfront.net/fit/c/1600/1280/gradv/29/81/60/darken/25/0*I7mXgSon9oco-rim.jpeg')"></div>
<div class="img-src blurred-img" style="background-image:url('https://d262ilb51hltx0.cloudfront.net/fit/c/1600/1280/gradv/29/81/40/darken/50/blur/50/0*I7mXgSon9oco-rim.jpeg')"></div>
</div>
<div class="article">
<h1>Medium</h1>
</div>
CSS:
.img-src {
position: fixed;
background-position: center;
-webkit-background-size: cover;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
}
.blurred-img { opacity: 0; }
.article {
width:500px;
height: 2000px;
}
h1 {
color: #fff;
position: fixed;
z-index: 9999;
font-size: 50px;
top: 50%;
margin-top: -25px;
left: 50%;
margin-left: -103px;
}
jQuery
$(window).scroll(function() {
// Get scroll position
var s = $(window).scrollTop(),
// scroll value and opacity
opacityVal = (s / 150.0);
// opacity value 0% to 100%
$('.blurred-img').css('opacity', opacityVal);
});
Then, the background picture that needs to be blurred is not at the very top of the page. My webpage is quite long and the background needs to be blurred is at the very bottom of the page.
I think the following code is trying to set the point where bluring starts to occur at the top of the page. I think there are more than 2000px to scroll down before reaching to the section I want to blur the background.
var s = $(window).scrollTop(), opacityVal = (s / 150.0);
Lets say my html document looks like this:
<div id="firstdiv">
<p>long text goes here....</p>
</div>
<div id="seconddiv">
<p>long text goes here....</p>
</div>
<div id="thirddiv">
<p>long text goes here....</p>
</div>
<div id="blurred-image-container">
<div class="img-src" style="background-image:url('https://d262ilb51hltx0.cloudfront.net/fit/c/1600/1280/gradv/29/81/60/darken/25/0*I7mXgSon9oco-rim.jpeg')"></div>
<div class="img-src blurred-img" style="background-image:url('https://d262ilb51hltx0.cloudfront.net/fit/c/1600/1280/gradv/29/81/40/darken/50/blur/50/0*I7mXgSon9oco-rim.jpeg')"></div>
</div>
<div class="article">
<h1>Medium</h1>
</div>
I want the background page to blur when the page is scroll down to #blurred-image-container section.
How can I modify the jQuery to work that?

<div class="out">
</div>
<div class="in">
</div>
out {
width: 100%;
height: 800px;
background: url('background') no-repeat;
}
.in {
width: 100%;
height: 200px;
background-color:olive;
}
$(window).on('scroll', function () {
var pixs = $(document).scrollTop()
pixs = pixs / 100;
var scroll;
$(window).scroll(function (event) {
scroll = $(window).scrollTop();
console.log(scroll);
*if(scroll>606)
{
$(".out").css({"-webkit-filter": "blur("+pixs+"px)","filter": "blur("+pixs+"px)" })
}*
});
});

This solution will require a separate element for the background but uses SVG filter to allow emulating motion blur in vertical direction.
It calculates the difference between last and current scroll position and uses that for a blur value. It debounces as well via using requestAnimationFrame(). It's easy to adopt to support a separate value for horizontal blurring as well.
You may want to tweak scale and max values for the blur, below some initial values only.
var blur = document.getElementById("fltBlur");
var prevY = 0;
var reqId;
window.onscroll = function() {
cancelAnimationFrame(reqId);
reqId = requestAnimationFrame(motionBlur)
};
function motionBlur() {
var y = window.scrollY;
var n = Math.min(32, Math.abs(y - prevY));
blur.setAttribute("stdDeviation" ,"0 " + n);
prevY = y;
}
html, body {width:100%; height:300%}
#cont {
width:100%;
height:300%;
background:url(//i.imgur.com/47zcWet.jpg);
-webkit-filter: url(#svgBlur);
filter: url("#svgBlur");
}
<svg style="position: absolute; top: -99999px" xmlns="http://www.w3.org/2000/svg">
<filter id="svgBlur" x="-5%" y="-5%" width="110%" height="110%">
<feGaussianBlur id="fltBlur" in="SourceGraphic" stdDeviation="0 0" />
</filter>
</svg>
<div id=cont></div>

Related

Is there any way to change a div size on scroll using intersectionObserver?

I'm trying to change the size (or scale) of a div while scrolling.
This div has a .8 scale attached to it css. I'd like to reach a scale of 1 progressively while scrolling.
IntersectionObserver seems to be a good choice to work with instead of scroll event but i don't know if i can change the state of an element using it.
You can change the scale of a div using.
document.getElementById("scaledDiv").style.transform = "scale(1)";
The scroll event should do what you want it to do. You can continue to add more if statements and check how many pixels they are scrolling to change it gradually to 1 or even back to 0.8 when they scroll back up. The 50 below represents 50 pixels from the top of the page.
window.onscroll = function() {
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
// They are scrolling past a certain position
document.getElementById("scaledDiv").style.transform = "scale(1)";
} else {
// They are scrolling back
}
};
I hope this will help you:
const container = document.querySelector('.container');
const containerHeight = container.scrollHeight;
const iWillExpand = document.querySelector('.iWillExpand');
container.onscroll = function(e) {
iWillExpand.style.transform = `scale(${0.8 + 0.2 * container.scrollTop / (containerHeight - 300)})`;
};
.container {
height: 300px;
width: 100%;
overflow-y: scroll;
}
.scrollMe {
height: 1500px;
width: 100%;
}
.iWillExpand {
position: fixed;
width: 200px;
height: 200px;
top: 10px;
left: 10px;
background-color: aqua;
transform: scale(0.8);
}
<div class='container'>
<div class='scrollMe' />
<div class='iWillExpand' />
</div>

Div to take entire height of viewport, until scroll to next div

I have 5 div containers. I want to render the first div to be the entire height of the viewport. And on scroll, next div takes over entire height of viewport. How would I do this?
HTML Code:
<div class="wrapper">
<div id="first-container" >
<p> hello </p>
</div>
<div id="second-container">
<p> hello </p>
</div>
<div id="third-container">
<p> hello </p>
</div>
<div id="four-container">
<p> hello </p>
</div>
<div id="five-container">
<p> hello </p>
</div>
</div>
I found this simple CSS code. It works on the first div but then doesn't allow me to scroll to the next div.
#first-container{
position: fixed !important;
position: absolute;
top:0;
right:0;
bottom:0;
left:0;
}
#second-container{
background-image: url("blue-gradient.png");
}
#third-container{
background-color: #A8CEFF;
}
#four-container{
background-image: url("green-gradient.png");
}
#five-container{
background-color: #394457;
}
UPDATE:
I've created a working fiddle of this: https://jsfiddle.net/zrgLahbx/1/ for demonstration
How to set to 100% height of the viewport
You can set the CSS height property of the and div containers (#first-container, #second-container etc.) to 100vh.
This 100vh essentially means "set the height to 100% of the viewport height (vh).
Like so:
#first-container {
height: 100vh;
}
#second-container {
height: 100vh;
}
... and so on ...
Personally, I would create a class for this:
.full-viewport-height {
height: 100vh;
}
Then apply this to each container:
<div class="full-viewport-height" >
<p> hello </p>
</div>
<div class="full-viewport-height">
<p> hello </p>
</div>
... and so on ...
Furthermore
I would also advise to set a fallback value (just above the 100vh). Just in case the browser does not support vh - trust me I've seen this happen.
Like this:
.full-viewport-height {
height: 800px;
height: 100vh;
}
CSS goes top-down. So, in case the browser does not support vh, it will use the first value.
If the browser does support vh, the vh value will override the first px value, anyway.
I would advise using ems if you can, instead of pixels.
Why what you've tried didn't work
Setting the position: fixed property like you have done, along with the top, bottom... etc. will make that div appear fixed to 100% of the screen, and not move whatsoever.
Confusingly, you then set the position to absolute.
Hope this helps! :)
Set your html, and body to height: 100% and apply height: 100% to your sections. Like this:
HTML
<div class="wrapper">
<section>
Content 1
</section>
<section>
Content 2
</section>
<section>
Content 3
</section>
<section>
Content 4
</section>
<section>
Content 5
</section>
</div>
CSS
body, html {
height: 100%;
width: 100%;
}
section {
height: 100%;
width: 100%
}
Your position code will make any DIV take up the whole screen and ignore scrolling. You need to pull that code out into a class:
.active {
position: fixed !important;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
Then you can use the vh unit to specify that all child DIVs take up 100% of the viewport. Only the active one will ever be visible, but you need this to block off the space in the document and to calculate where they change.
.wrapper>div {
height: 100vh;
}
Next you need to tap into the scroll event and set the active class based on current positioning.
(function() {
'use strict';
var containers = [...document.querySelectorAll('.wrapper > div')],
heights = containers.map(c => $(c).height()),
scrollTops = [],
currentIdx = 0,
nextUp = null,
nextDown = null;
heights.forEach( (h,i) => scrollTops.push(h + scrollTops[i-1] || 0) );
setCurrentIdx(0);
function setCurrentIdx(idx){
if (containers[currentIdx])
containers[currentIdx].classList.remove('active');
currentIdx = idx;
containers[currentIdx].classList.add('active');
nextUp = ( idx === 0 ? null : scrollTops[currentIdx] );
nextDown = ( idx === scrollTops.length - 1 ? null : scrollTops[currentIdx + 1] );
}
function move(direction){
var newIdx = currentIdx + (direction === 'up' ? -1 : 1);
if (newIdx < 0 || newIdx >= containers.length)
return;
setCurrentIdx(newIdx);
}
$(window).scroll(function() {
var currentScroll = $(this).scrollTop();
console.log(nextUp, '<--', currentScroll, '-->', nextDown);
if (nextDown && currentScroll > nextDown)
move('down');
if (nextUp && currentScroll <= nextUp)
move('up');
});
}());
.wrapper>div {
height: 100vh;
}
.wrapper{
margin-bottom:100vh;
}
#first-container {
background-color: gray;
}
#second-container {
background-color: blue;
;
}
#third-container {
background-color: #A8CEFF;
}
#four-container {
background-color: green;
}
#five-container {
background-color: #394457;
}
.active {
position: fixed !important;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div id="first-container" class="active">
<p>hello 1</p>
</div>
<div id="second-container">
<p>hello 2</p>
</div>
<div id="third-container">
<p>hello 3</p>
</div>
<div id="four-container">
<p>hello 4</p>
</div>
<div id="five-container">
<p>hello 5</p>
</div>
</div>

How to find the location of HTML element using javascript reliably

I have a html block that is consist of many <div>s.
I use these <div>s to create modal windows by altering their opacity upon target (done in CSS).
These <div>s are distinguished by id and all have the same class name.
The <div>s have a border of 10px. Upon mouse hover, the border is changed to 38px for right and left border only (done in css).
Upon mouse hover I want to show back and next arrow to appear exactly middle of the left and right hand border. Different 'div's have different heights.
My approach:
I have use the event.target.id to get the id of the <div> that calls the function.
Then I used the getBoundingClientRect() to get a rectangle representation of that element on the screen.
I used the .top .bottom .left .right to get the x and y coordinates of each four points. From these points I find the height and then set the <div>s .left and .right to be equal to it.
I have used alert() to return the result and it sometime returns the correct value and sometimes no values at all. The return result is either of these two. And the arrows don't get placed where they are suppose to. I am quite new to Javascript and I am still learning so I'd appreciate if you also explain your answers.
The HTML codes is below:
<html>
<head>
<script src="jquery-1.11.1.js"></script>
<script type="text/javascript" src="midpointHeight.js"></script>
<script type="text/javascript" src="modalDialogHover.js"></script>
</head>
<!--first modal-->
<a href="#X">
<image src="X.gif" id="X" class="Gif" />
</a>
<div id="h" class="modalDialog">
<div id="miniModal_h" class="miniModal" onmouseover="getMidPointHeight(event)">
<div class="close_btn"></div>
<div class="next_btn"></div>
<p>
<!--some text here-->
</p>
</div>
</div>
<!--second modal-->
<a href="#p">
<image src="p.gif" id="p" class="Gif" />
</a>
<div id="p" class="modalDialog">
<div id="miniModal_p" class="miniModal" onmouseover="getMidPointHeight(event)">
<div class="close_btn"></div>
<div class="back_btn"></div>
<div class="next_btn"></div>
<p>
<!--some text here-->
</p>
</div>
</div>
</html>
in CSS:
.modalDialog {
position: fixed;
font-family: Arial, Helvetica, sans-serif;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 99999;
opacity: 0;
}
.modalDialog > div {
width: 704px;
position: relative;
margin: 10% auto;
background: white;
border-image: url("grey_flat_tile.png");
border-image-repeat: repeat;
border-image-slice: 30%;
border-width: 10px;
}
.modalDialog:target{
opacity:1;
}
.next_btn {
display: none;
background-image: url("arrow_right.png");
position: absolute;
right: -30px;
width: 20px;
height: 22px;
}
.back_btn{
display: none;
background-image: url("arrow_left.png");
position: absolute;
left: -30px;
width: 20px;
height: 22px;
}
.visible {
display: block;
}
In jQuery to hid/show the left and right buttons on the panels:
jQuery(document).ready(function(){
jQuery(".miniModal").hover(
function(){
jQuery(".close_btn").addClass("visible"),
jQuery(".next_btn").addClass("visible"),
jQuery(".back_btn").addClass("visible")
},
function(){
jQuery(".close_btn").removeClass("visible"),
jQuery(".next_btn").removeClass("visible"),
jQuery(".back_btn").removeClass("visible")
}
)
});
In javascript to find the midpoint height and show the arrow at the right position:
function getMidPointHeight(event){
var miniModal= event.target.id;
//alert(miniModal);
var smallRect = document.getElementById(event.target.id).getBoundingClientRect();
var sX = smallRect.left;
var sY = smallRect.top;
var sW = smallRect.right;
var sH = smallRect.bottom;
//alert(sX + "," + sY + "," + sW + "," + sH);
var sHeight = (sH - sY);
var smidHeight = (sHeight / 2);
var arrow_loc = (smidHeight)+"px";
alert(arrow_loc);
var next_btn = document.getElementById("next_btn");
next_btn.style.top = arrow_loc;
var back_btn = document.getElementById("back_btn");
back_btn.style.top = arrow_loc;
}

How to make vertical "slide" scroll?

I have a landing page, consisting of three frames, this frames always take 100% of viewport height and width.
I need to make transitions between frames, like "powerpoint presentation" etc. User scroll's, frame-1 slides up above viewport and frame-2 becomes in his place from bottom of viewport. I have almost zero experience in javascript/jquery. Have some ideas, that you can see in the code, but this ideas not works.
HTML:
<div class="wrapper" id="wrapper">
<div class="frame frame-1">
<!-- Content here -->
</div>
<div class="frame frame-2">
<!-- Content here -->
</div>
<div class="frame frame-3">
<!-- Content here -->
</div>
</div>
CSS:
.wrapper {
height: 300vh;
}
.frame {
position: fixed;
height: 100vh;
transition: all 1s ease;
}
.frame-1 {
top: 0vh;
}
.frame-2 {
top: 100vh;
}
.frame-3 {
top: 200vh;
}
JS:
var $document = $(document),
$element1 = $('.frame-1'),
$element2 = $('.frame-2'),
$element3 = $('.frame-3');
$(window).scroll(function () {
if ($(this).scrollTop() >= 50) {
$element1.css("top", "-100vh");
$element2.css("top", "0vh");
$element3.css("top", "100vh");
} else if ($(this).scrollTop() >= 100) {
$element1.css("top", "-200vh");
$element2.css("top", "-100vh");
$element3.css("top", "0vh");
} else {
$element1.css("top", "0vh");
$element2.css("top", "100vh");
$element3.css("top", "200vh");
}
});
If you have a set number of frames, I would suggest placing them all in a single div, and changing the top value of that. that way, only one value need be modified.
Like this: http://jsfiddle.net/xkh4D/10/
(Note that, though px are used, vh or whichever other unit should work just as well... haven't tried %, though...)
HTML
<div id='yo' class='view'>
<div>
<div class='frame red'></div>
<div class='frame green'></div>
<div class='frame blue'></div>
</div>
</div>
<input type='button' value='Scroll' onclick='scrollFrame()'/>
CSS
.view {
position:relative;
width:300px;
height:250px;
border:1px solid black;
overflow:hidden;
}
.view > div {
position:absolute;
width:inherit;
height:inherit;
top:0px;
}
.frame {
width:inherit;
height:inherit;
}
.red { background-color:#faa }
.green { background-color:#afa }
.blue { background-color:#aaf }
JavaScript
scrollFrame = function()
{
var h = $('#yo').height();
var y = parseFloat($('.view > div').css('top'));
var hsum = $('.view .frame').length * h;
console.log('h,y,hsum',h,y,hsum);
if (hsum-h == -1*y)
$('.view > div').animate({'top':0});
else
$('.view > div').animate({top:y-h},500);
}
This js could be your solution
http://alvarotrigo.com/fullPage/

CSS3 image rotation and reposition to fit in div

I'll start with JS Fiddle:
http://jsfiddle.net/zy2xy/4/
<div id="page" style="position: relative; background: #ccc; width: 500px; height: 600px;">
<div id="container" style="top: 50px; left: 100px; width: 200px; height: 200px; position: absolute; background: #fff;">
<img src="http://lorempixel.com/200/100/">
</div>
</div>​​​​​​​​​
I've got a whole page div #page, and inside that another div #container positioned absolute against #page.
What I want to achieve, is to rotate image inside it 90deg, 180deg or 270deg but always move that image to top left corner of #container.
I tried a little bit with transform-origin but I couldn't find any solution.
Set the position:absolute to the image
Then calculate the angle.. If it's 90 or 270 then set the left and top attributes for the image.
Code
$('a').click(function(e) {
e.preventDefault();
var angle = $(this).attr("id");
console.log("angle");
var $container = $('#container');
var left = 0;
var top = 0;
if(+angle === 90 || +angle === 270){
top = 50;
left = -50;
}
$("#my_image").css({
transform: 'rotate('+angle+'deg)',
'-moz-transform': 'rotate('+angle+'deg)',
'-webkit-transform': 'rotate('+angle+'deg)',
'top' : top + 'px',
'left' : left + 'px'
});
}).click();​ // Fire click on DOM ready
Check Fiddle

Categories