i am trying to zoom out the image when scroll . if i change the width and height of image to 150px. the image is zooming in first then zooming out when go back scroll. however i want the other way around. on the first view the image is full width and height then when i scroll i want to zoom out the image first then proceed to red background. then if i scroll back again the image will be zoom in again. Please help.
This is the code:
https://codesandbox.io/s/relaxed-elgamal-43iltb?file=/index.html
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<style>
body {
margin: 0;
}
img {
width: 100%;
height: 100%;
background-color: black;
}
.fade {
height: 100vh;
width: 100%;
position: fixed;
top: 0;
left: 0;
background: blue;
}
.zoom {
height: 100vh;
width: 100%;
display: grid;
place-items: center;
position: fixed;
top: 0;
left: 0;
}
.afterzoom {
position: relative;
height: 200vh;
width: 100%;
background: red;
overflow-x: auto;
}
.third {
position: absolute;
height: 300vh;
width: 100%;
background: red;
overflow-x: auto;
}
</style>
<body>
<div class="fade"></div>
<div class="zoom">
<img src="https://via.placeholder.com/150" alt="" />
</div>
<div class="afterzoom">
<p>This should appear after the above element is fully zoomed.</p>
</div>
<div class="third">
<p>Thirdpage</p>
</div>
</body>
</html>
<script>
const zoomElement = document.querySelector(".zoom");
const fadeElement = document.querySelector(".fade");
const afterZoomElement = document.querySelector(".afterzoom");
const imgElement = document.querySelector("img");
const WIDTH = document.body.clientWidth;
const HEIGHT = zoomElement.clientHeight;
const IMAGE_WIDTH = imgElement.clientWidth;
const IMAGE_HEIGHT = imgElement.clientHeight;
const ZOOM_SPEED = 100; // Lower is faster
const ZOOM_BREAKPOINT = WIDTH / IMAGE_WIDTH; // When it should stop zooming in
const IMAGE_HEIGHT_MAX = IMAGE_HEIGHT * ZOOM_BREAKPOINT;
const ABSOLUTE = ZOOM_BREAKPOINT * ZOOM_SPEED; // Absolute position, when the Element reached maximum size
// Fade --------------------------------------------------------------------------------------
const FADE_SPEED = 500; // Lower is faster
let fade = 1;
let prev = 0;
// -------------------------------------------------------------------------------------- Fade
function anim() {
let scroll = window.scrollY;
let temp = scroll / ZOOM_SPEED;
let zoom = temp > 1 ? temp : 1;
console.log("ZOOM_BREAKPOINT", ZOOM_BREAKPOINT);
// Only update the Elements scale, when we are below the breakpoint
if (zoom < ZOOM_BREAKPOINT) {
console.log("less breakpont");
console.log("zoom", zoom);
// Only scale the Image, so the Zoom element does not mess with the document width
imgElement.style.transform = `scale(${zoom - 0.6})`;
// Sets the Elements position to fixed, so it can resize without scrolling away
zoomElement.style.top = "0px";
zoomElement.style.position = "fixed";
} else {
// Makes sure the Element always reaches Max Size
imgElement.style.transform = `scale(${ZOOM_BREAKPOINT})`;
// Sets the elements position to absolute, so it will scroll with the rest of the document
zoomElement.style.position = "absolute";
zoomElement.style.top = ABSOLUTE + "px";
}
// Fade --------------------------------------------------------------------------------------
let dif = prev - scroll;
if (zoom < ZOOM_BREAKPOINT - FADE_SPEED / ZOOM_SPEED) {
fade = 1;
} else if (zoom > ZOOM_BREAKPOINT) {
fade = 0;
} else {
fade += dif / FADE_SPEED;
}
fadeElement.style.opacity = fade;
prev = scroll;
// -------------------------------------------------------------------------------------- Fade
}
// Resets scroll position on every reload
if ("scrollRestoration" in history) {
history.scrollRestoration = "manual";
}
document.addEventListener("scroll", () => window.requestAnimationFrame(anim));
// Fade --------------------------------------------------------------------------------------
zoomElement.style.opacity = 1;
// -------------------------------------------------------------------------------------- Fade
// Positions the afterZoom element right below the zoomed image
afterZoomElement.style.top =
ABSOLUTE + IMAGE_HEIGHT_MAX / 2 + HEIGHT / 2 + "px";
</script>
Related
I am creating div dynamically inside a div with negative margins, but my div outer scroller is not activating to scroll and see those dynamically created div.
HTML code
<html>
<body align="center">
<div id "TC" class = "Tile_container">
</div>
</body>
</html>
Here i am creating tile container with x scroll and y scroll.
CSS code
.Tile_container
{
height: 500px;
width: 500px;
background-color: lightgray;
position: relative;
overflow-x: scroll;
overflow-y: scroll;
}
JS code
$(document).ready(function () {
var tileContainer = document.getElementsByClassName("Tile_container")[0];
var newTile = document.createElement("div");
newTile.setAttribute("class", "PlayerTile");
var strTop = "" + (-100) + "px";
var strLeft = ""+ (-100) + "px";
newTile.style.left = strLeft;
newTile.style.top = strTop;
tileContainer.appendChild(newTile);
});
My scrollers are activating when i create inner div at position more than the Tile_container div dimension.
can anyone please tell how to scroll and see those created div. in that div i have other functionalities to add.
You have moved the PlayerTile off the top and left of the parent div.
overflow-x and overflow-y will not scroll for contents that are off the top or left.
Scrolling to the right and down works fine.
var tileContainer = document.getElementById("TC");
window.onload = (function() {
var newTile = document.createElement("div");
newTile.id = 'newtile';
newTile.setAttribute("class", "PlayerTile");
tileContainer.appendChild(newTile);
});
function moveTile(direction, value) {
const tile = document.getElementById('newtile');
if (direction === 'horizontal') {
tile.style.left =
Number(tile.style.left.replace('px', '')) +
value + 'px';
} else {
tile.style.top =
Number(tile.style.top.replace('px', '')) +
value + 'px';
}
}
const moveRight = () => moveTile('horizontal', 60);
const moveLeft = () => moveTile('horizontal', -60);
const moveUp = () => moveTile('vertical', -12);
const moveDown = () => moveTile('vertical', 12);
function reset() {
const tile = document.getElementById('newtile');
tile.style.left = tile.style.top = '12px';
}
.Tile_container {
height: 140px;
width: 90%;
background-color: lightgray;
position: relative;
overflow-x: scroll;
overflow-y: scroll;
}
.PlayerTile {
height: 100px;
width: 200px;
background-color: dodgerBlue;
position: absolute;
top: 12px;
left: 12px;
}
Move Tile: <button onclick="moveRight()">Right</button>
<button onclick="moveLeft()">Left</button>
<button onclick="moveUp()">Up</button>
<button onclick="moveDown()">Down</button>
<button onclick="reset()">Reset</button><br/>
<div id="TC" class="Tile_container"></div>
I am trying to expand a child element to the very top of its parent with the following code. However, the text disappears after a while of scrolling downward in the child element. How do I fix this?
function setHeight() {
var panel = document.getElementById("panel");
var container = document.getElementById("container");
var panelHeight = container.offsetHeight;
var y = panel.scrollTop;
// YOU MUST SET THE PERCENTAGE, OR A MAX HEIGHT
maxHeight = panelHeight * 0.9;
var targetHeight = Math.min(maxHeight, 0.7 * panelHeight + y);
panel.style.height = targetHeight + "px";
document.getElementById("panelContent").style.marginTop = Math.min(y, panelHeight - maxHeight) + "px";
}
document.getElementById('panel').addEventListener("scroll", setHeight);
#container {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: red;
}
#panel {
position: fixed;
width: 100%;
height: 70%;
bottom: 0;
background-color: green;
overflow-y: scroll;
}
<div id="container">
Scroll up to here
<div id="panel">
<div id="panelContent">
As user scroll downs here in this div, expand this div to the top but only as much as the user has scrolled down: asdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasda<br>sdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasda<br>sdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasda<br>sdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasd<br>sdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasda<br>sdasdasdasdasdasdasdasdasdasdasdasdassdasdasdasdasdasd
</div>
</div>
</div>
https://jsfiddle.net/1ekpx3sd/
I am trying to set the maximum scroll of an element, in this case .contain, to match the height needed for .square to fill the entire viewport (both width and height) on scroll. I need to figure out how I can retrieve the remaining height needed to cover the offset value of the scroll.
Here is a codepen showing what currently happens. The scroll reaches the bottom and the square fails to fill the screen. Without the offset I can get this to work perfectly (see line 17), but I'd really like to learn how I can incorporate the parallax offset/speed effect.
https://codepen.io/anon/pen/zbeyQd
The non-offset version to show how the above pen should work. Square fills the screen as the scrollbar hits the bottom: https://codepen.io/anon/pen/Rdvvom
This should do the trick
const sq = document.querySelector('.square')
const contain = document.querySelector('.contain')
//set desired scroll boundaries. can be any size
//the higher the value the longer you'll have to scroll
const scrollOffset = 250
const sqW = sq.offsetWidth
const sqH = sq.offsetHeight
const wHeight = window.innerHeight
const wWidth = window.innerWidth
contain.style.height = `${wHeight + scrollOffset}px`
window.addEventListener('scroll', (e) => {
const percentScroll = window.scrollY * 100 / scrollOffset
const width = (wWidth - sqW) * percentScroll / 100
const height = (wHeight - sqH) * percentScroll / 100
sq.style.width = `${sqW + width}px`
sq.style.height = `${sqH + height}px`
})
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.contain {
height: 100%;
width: 100%;
background-color: papayawhip;
}
.square {
width: 100px;
height: 100px;
background-color: tomato;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0.25;
}
<div class="contain">
<div class="square"></div>
</div>
I've created a button, when you hover over it a div with a background image enlarges. The background should follow the cursor's movements. Meaning that the background image follows your cursor as you hover over the button.
When I hover over the bottom right part of the button, the image will zoom in to the top left before moving to the cursor's location. Check out the example below to see what I mean. I'd like to make it zoom directly to the cursor's location, any ideas?
var imgZoomIn = 1.2; //% of how much the image will enlarge
function buttonImgResize(x, e){
//Location of the cursor (as percentage of the container's size)
var imgContPosition = x.getBoundingClientRect();
var mousePosX = (e.clientX - imgContPosition.left) / x.offsetWidth;
var mousePosY = (e.clientY - imgContPosition.top) / x.offsetHeight;
//Finding how far to move the image from top and left
var leftImgOverlap = x.offsetWidth * (imgZoomIn - 1) * mousePosX;
var topImgOverlap = x.offsetHeight * (imgZoomIn - 1) * mousePosY;
//implementing changes
x.firstElementChild.style.left = 0 - leftImgOverlap + "px";
x.firstElementChild.style.top = 0 - topImgOverlap + "px";
}
//Reseting values
function buttonImgDownsize(x){
x.firstElementChild.style.left = "0";
x.firstElementChild.style.top = "0";
}
/*Container*/
.showCaseBtn{
overflow: hidden;
position: relative;
width: 500px; height: 300px;
}
/*div with background image*/
.showcaseBtn_Back{
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
background: black no-repeat center center / cover;
transition: 0.4s;
}
.showCaseBtn:hover .showcaseBtn_Back{
height: 120%; width: 120%;
}
<div class="showCaseBtn" onmousemove="buttonImgResize(this, event)" onmouseout="buttonImgDownsize(this)">
<div class="showcaseBtn_Back" style="background-image: url(https://media.contentapi.ea.com/content/dam/need-for-speed/common/2017/10/nfs-payback-jaguar-f-type-2x.jpg.adapt.1920w.jpg);"></div>
</div>
The problem is caused by the css transition. If you remove it, the zooming works but no fancy scaling will happen.
var imgZoomIn = 1.2;
function buttonImgResize(x, e){
var imgContPosition = x.getBoundingClientRect();
var mousePosX = (e.clientX - imgContPosition.left) / imgContPosition.width;
var mousePosY = (e.clientY - imgContPosition.top) / imgContPosition.height;
var leftImgOverlap = imgContPosition.width * (imgZoomIn - 1) * mousePosX;
var topImgOverlap = imgContPosition.height * (imgZoomIn - 1) * mousePosY;
x.firstElementChild.style.left = - leftImgOverlap + "px";
x.firstElementChild.style.top = - topImgOverlap + "px";
}
function buttonImgDownsize(x){
x.firstElementChild.style.left = "0";
x.firstElementChild.style.top = "0";
}
.showCaseBtn{
overflow: hidden;
position: relative;
width: 500px; height: 300px;
}
.showcaseBtn_Back{
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
background: black no-repeat center center / cover;
}
.showCaseBtn:hover .showcaseBtn_Back{
height: 120%; width: 120%;
}
<div class="showCaseBtn" onmousemove="buttonImgResize(this, event)" onmouseout="buttonImgDownsize(this)">
<div class="showcaseBtn_Back" style="background-image: url(https://media.contentapi.ea.com/content/dam/need-for-speed/common/2017/10/nfs-payback-jaguar-f-type-2x.jpg.adapt.1920w.jpg);"></div>
</div>
I am trying to make so that if you scroll down, a blurred picture appears (with opacity) and if you're at the bottom of the page, the blurred picture is fully visible and the old one disappeared. I'm using the same pagecontainer for every page and I want to make this script do this on every page, with different page lengths.
I have this so far:
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;
}
JS:
var divs = $('.social, .title'),
limit = 0;
$(window).on('scroll', function() {
var st = $(this).scrollTop();
if (st <= limit) {
$('.blurred-img').css({ 'opacity' : (1 - st/limit) });
}
});
filter: blur usually works fine and looks better. How about something like this?
var img = document.getElementById("background-img");
var container = document.body;
var maxBlur = 20;
window.addEventListener("scroll", function(){
var position = container.scrollTop / (container.scrollHeight - window.innerHeight);
// Adjust the position for safari that may scroll higher or lower than the
// actual size during their "bounce effect".
position = Math.max(0, Math.min(1, position));
var blurAmount = position * maxBlur;
img.style["filter"] = "blur(" + blurAmount + "px)";
});
#background-img {
position: fixed;
}
#spacer {
width: 50px;
height: 2000px;
}
<img id="background-img" src="http://placehold.it/400x200?text=Background" />
<div id="spacer"></div>
If you really want to do your two images strategy, here is how I would do it.
var img = document.getElementById("blured-background-img");
var container = document.body;
window.addEventListener("scroll", function(){
var opacity = container.scrollTop / (container.scrollHeight - window.innerHeight);
// Adjust the opacity for safari that may scroll higher or lower than the
// actual size during their "bounce effect".
opacity = Math.max(0, Math.min(1, opacity));
img.style["opacity"] = opacity;
});
#background-img {
position: fixed;
}
#blured-background-img {
position: fixed;
opacity: 0;
}
#spacer {
width: 50px;
height: 2000px;
}
<img id="background-img" src="http://placehold.it/400x200/7A6DFF/D3CFFF?text=Bottom" />
<img id="blured-background-img" src="http://placehold.it/400x200?text=Top" />
<div id="spacer"></div>