Text content disappears in div as scrolling - javascript

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/

Related

Mouse Scrolling image not zooming out (Javascript)

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>

How to increase width and height on click of a button

I need to increase height actually to increase bottom and top of div each for 25px also left and right side each for 25px.I don't now is that even possible.
So this is just example but it is similar to my code:
function increaseDiv() {
var myDiv = document.querySelector(".box")
var currWidth = myDiv.clientWidth;
myDiv.style.width = currWidth + 100 + "px";
}
.box {
width: 300px;
height: 200px;
position: absolute;
left: 100px;
background: black;
}
<div class="box"></div>
<button onclick="increaseDiv()">Click</button>
Here is demo https://jsfiddle.net/SutonJ/0pdwm39a/14/
The problem is that position of your div are related to left side and this is why it looks like you increase only the right side; try to add positioning with transform by center or make it by flex(align-items + justify-content)
.box {
width: 300px;
height: 200px;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
background: black;
}
If I am understanding you correctly, I think if you changed
var currWidth = myDiv.clientWidth;
myDiv.style.width = currWidth + 100 + "px";
to
var currWidth = myDiv.getBoundingClientRect().width;
myDiv.style.width = currWidth + 50 + "px";
and also added
var currHeight = myDiv.getBoundingClientRect().height;
myDiv.style.height = currHeight + 50 + "px";
I also noticed that your div is using absolute positioning, so you may also need to offset the left and top according to the size change. If you are getting an issue with the actual position when the size changes let me know.
What about CSS scale?
That will keep the actual position of the element and expand it in all directions, unless you specify a transform-origin value.
Edited with an ever growing effect...
let myDiv = document.querySelector(".box");
let orgiSize = myDiv.getBoundingClientRect().width;
let increments = 0;
function increaseDiv() {
increments += 50; // That is 25px on both sides...
// Make the math here
var percentage = Math.floor((orgiSize + increments) / orgiSize * 100) / 100
console.log(percentage);
myDiv.style.transform = `scale(${percentage})`; // That is a percentage value
}
.box {
width: 300px;
height: 200px;
position: absolute;
left: 100px;
background: black;
}
/* for the demo */
button {
position: absolute;
z-index: 9999;
}
<div class="box"></div>
<button onclick="increaseDiv()">Click</button>

Centering overflow:auto content inside DIV

I'm trying to create a grid inside of a DIV viewport with overflow set to auto and want to add a zoom feature to it. The user should be able to zoom in/out but I want to keep the content center-aligned throughout the zoom process.
When zooming, the overflowing content on the horizontal axis is centered and, when scrolled left and right, I can see all 8 grid boxes on that axis - this is perfect. However, for some strange reason, the overflowing content on the Y axis is not centering when zoomed and the uppermost part of the grid disappears out of the viewport and annoyingly can't be seen or scrolled to.
When you zoom in, pay attention to how the horizontal scrollbar remains centered and that you can scroll left and right and see all 8 boxes but the vertical axis doesn't work the same way.
I welcome your suggestions and/or a solution. Thanks.
$(function() {
var $container = $('.container');
var current_zoom = 1;
var current_cell_size = 20;
var cells_x = 8;
var cells_y = 8;
var grid_size_x = cells_x * current_cell_size;
var grid_size_y = cells_y * current_cell_size;
var $grid = $('<div />').addClass('grid').css({
'width': grid_size_x,
'height': grid_size_y
});
for (var x = 0; x < cells_y; x++) {
var $row = $('<div />').addClass('row');
for (var y = 0; y < cells_x; y++) {
var $cell = $('<div />').addClass('cell').css({
'width': current_cell_size,
'height': current_cell_size
});
$row.append($cell);
}
$grid.append($row);
}
$container.append($grid);
center_viewport();
// ----- EVENTS
$('.zoom-in-btn').click(zoom_in);
$('.zoom-out-btn').click(zoom_out);
// ----- FUNCTIONS
function center_viewport() {
$container.scrollLeft((grid_size_x - $container.width()) / 2);
$container.scrollTop((grid_size_y - $container.height()) / 2);
}
function zoom_in() {
current_cell_size = current_cell_size + 10;
grid_size_x = cells_x * current_cell_size;
grid_size_y = cells_y * current_cell_size;
$grid.css({
'width': grid_size_x,
'height': grid_size_y
}).find('.cell').css({
'width': current_cell_size,
'height': current_cell_size
});
center_viewport();
}
function zoom_out() {
current_cell_size = current_cell_size - 10;
grid_size_x = cells_x * current_cell_size;
grid_size_y = cells_y * current_cell_size;
$grid.css({
'width': grid_size_x,
'height': grid_size_y
}).find('.cell').css({
'width': current_cell_size,
'height': current_cell_size
});
center_viewport();
}
});
html,
body {
position: relative;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
html .container,
body .container {
position: fixed;
top: 30px;
right: 30px;
bottom: 30px;
left: 30px;
overflow: auto;
border: solid 1px #000;
}
html .container .grid,
body .container .grid {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
html .container .grid .row,
body .container .grid .row {
display: flex;
}
html .container .grid .row:nth-child(odd) .cell:nth-child(odd),
body .container .grid .row:nth-child(odd) .cell:nth-child(odd) {
background: #EEE;
}
html .container .grid .row:nth-child(even) .cell:nth-child(even),
body .container .grid .row:nth-child(even) .cell:nth-child(even) {
background: #EEE;
}
html .container .zoom-btns,
body .container .zoom-btns {
position: fixed;
z-index: 2;
right: 50px;
bottom: 50px;
}
html .container .zoom-btns button,
body .container .zoom-btns button {
margin-left: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="container">
<div class="zoom-btns">
<button class="zoom-in-btn">Zoom In</button>
<button class="zoom-out-btn">Zoom Out</button>
</div>
</div>
Demo Fiddle here.
I think that instead of using width/height CSS properties to zoom, you should consider using transform and transform-origin properties. You can use the scale value of transform to zoom, then assign the coordinates of the center of the item as the transform-origin value.
CSS Transform
CSS Transform Origin

Background zooms in incorrectly when following mouse movement

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>

Jquery/CSS: Full size background image

I am currently working with a jquery plugin for setting my background image. The issue i am having is with the CSS/JQuery making the page in-proportionate. My content lies inside the #container div so I have set its position to absolute(originally was relative). How can I have the content of the page be aligned in the center and keep the properties of a 100% height? EXAMPLE
This is before the jquery plugin- CSS 100% height- EXAMPLE
Jquery Background plugin
<script>
(function($) {
$.fn.fullBg = function(){
var bgImg = $(this);
function resizeImg() {
var imgwidth = bgImg.width();
var imgheight = bgImg.height();
var winwidth = $(window).width();
var winheight = $(window).height();
var widthratio = winwidth / imgwidth;
var heightratio = winheight / imgheight;
var widthdiff = heightratio * imgwidth;
var heightdiff = widthratio * imgheight;
if(heightdiff>winheight) {
bgImg.css({
width: winwidth+'px',
height: heightdiff+'px'
});
} else {
bgImg.css({
width: widthdiff+'px',
height: winheight+'px'
});
}
}
resizeImg();
$(window).resize(function() {
resizeImg();
});
};
})(jQuery)
</script>
CSS related to the issue
#container {
position: relative;
margin: 0 auto;
width: 945px;
background: #f0f0f0;
height: auto!important;
height: 100%;
min-height: 100%;
border-right: 15px solid #000;
border-left: 15px solid #000;
}
.fullBg {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
}
HTML/Inline JS to call function
<img src="images/raven_bg.jpg" alt="" id="background" />
<div id="container">
</div>
<script>
$(window).load(function() {
$("#background").fullBg();
});///this comes right before the closing body tag
</script>
This centers it -
#container {
margin-left: 50%;
left: -488px;
}
it's kind of hacky, but it works.
50% shift (to keep it centered based on width)
half of width, plus border = 478.5 (or 488) to keep it centered in frame. And of course, with "left" only works because it's got position: relative; attached to it

Categories

Resources