I'm trying to recreate this simple jquery image zoom scroll effect in vanilla javascript with no success:
I'm looking online and all tutorials seems to use jquery or skrollr library which is not being supported since 2014.
This is a tutorial of this effect on youtube:
https://www.youtube.com/watch?v=hjeS8HxH3k0
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Image Zoom Scroll Effect</title>
<style>
body {
margin: 0;
padding: 0;
}
div {
width: 100%;
height: 100vh;
overflow: hidden;
position: relative;
}
div img {
width: 100%;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%);
}
/* BLANK SPACE, JUST TO TRY OUT THE SCROLL EFFECT */
.whitespace {
width: 100%;
height: 100vh;
}
</style>
<!-- JQUERY CDN -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="img-area">
<img
src="https://images.pexels.com/photos/775201/pexels-photo-775201.jpeg"
/>
</div>
<!-- BLANK SPACE, JUST TO TRY OUT THE SCROLL EFFECT -->
<div class="whitespace"></div>
<script>
// JQUERY
$(window).scroll(() => {
let scroll = $(window).scrollTop();
$('.img-area img').css({
width: 100 + scroll / 5 + '%',
});
});
// VANILLA JS
// window.addEventListener('scroll', () => {
// let scroll = window.scrollTop;
// document.querySelector('.img-area img').style.width =
// 100 + scroll / 5 + '%';
// });
</script>
</body>
</html>
I've commented out my vanilla javascript code.
There is no property scrollTop for the window object. Use document.documentElement:
window.addEventListener('scroll', () => {
let scrollTop = document.documentElement.scrollTop;
document.getElementById('test').style.width = 100 + scrollTop / 5 + '%';
});
See working fiddle: https://jsfiddle.net/z3hux1ra/5/
Related
I want to make the grid element to fall down to the page . I used setInterval to repeat the proces (the bottom will decrease so the grid will descend ) . I think I didn't create move() function correctly.I just want to know how can I set the function correctly .
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel= "stylesheet" href ="style.css"></link>
</head>
<body>
<div class="grid"></div>
<script src="javascript.js" ></script>
</body>
</html>
.grid {
background-color:blue;
height: 20px;
width :100px;
left:600px;
top:150px;
position : absolute;
}
var grid =document.querySelector('.grid');
function move () {
grid.style.bottom-=4;
grid.style.bottom=grid.bottom +'px';
}
move();
setInterval(move,30);
If you would still like to implement your approach to realize this movement, here is some feedback.
Bottom value is String, not numerical (e.g. 300px vs 300)
If you want to manipulate the bottom value of an element, you have to parse the numerical value first, then change it, and then append a 'px' (or whatever unit you're using).
// grid.style.bottom-=4; // subtraction on strings is not allowed
// instead, use:
const currentBottom = parseInt(grid.style.bottom, 10)
grid.style.bottom = (currentBottom - 4) + 'px'
document.getElementById(...).style misses styles from <style> blocks and stylesheets
If you want to get all current styles of a DOM element, you should use window.getComputedStyle. As described in the docs:
getComputedStyle is read-only, and should be used to inspect the element's style — including those set by a element or an external stylesheet
In the snippet below, you can see and compare the values grid.style.bottom and window.getComputedStyle(grid). At first, the first version is empty, but the second has the expected value from the stylesheet.
Alternatively, you could directly apply the style in-line with the HTML element. Then you could use .style as well for accessing the correct value from the beginning.
<div class="grid" style="bottom: 100px"></div>
Check out the fixed version of the snippet below with a delay of 3 seconds for better understanding.
var grid = document.querySelector('.grid');
function move() {
const style = grid.style.bottom
const computedStyle = window.getComputedStyle(grid)
console.log('bottom', style)
console.log('bottom from computed style', computedStyle.bottom)
// grid.style.bottom -= 4;
// grid.style.bottom = grid.bottom + 'px';
const newBottom = parseInt(computedStyle.bottom, 10) - 4; // parseInt only reads the numeric value from the bottom string
grid.style.bottom = newBottom + 'px';
}
move();
setInterval(move, 3000);
.grid {
background-color: blue;
height: 20px;
width: 100px;
left: 100px;
bottom: 200px;
position: absolute;
}
<div class="grid"></div>
I would recommend you to use a CSS animation for that, you don't need JavaScript for that.
.grid {
background-color: blue;
height: 20px;
width: 100px;
left: 100px;
position: absolute;
animation: move 1.5s forwards;
}
#keyframes move {
from {
bottom: 200px;
}
to {
bottom: 0;
}
}
<body>
<div class="grid"></div>
</body>
I'm incredibly new to JavaScript, and honestly thought I had a solid plan-of-attack to make my logo smaller after scrolling from the top by 10px. The goal is to make the logo (normally 400px in width) get smaller (to 100px) upon scrolling down from the top.
Can anyone help me understand why this code isn't returning any visual response?
Here is the HTML markup:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="author" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="normalize.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<!--<div id="header">Header</div>-->
<div id="header">
<img id="header-image" src="logo-mockup.png">
</div>
<p>THIS IS ALL JUST FILLER TEXT RIGHT NOW.</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
The CSS:
#header {
background-color: #f1f1f1; /* Grey background */
padding: 30px 0px; /* Some padding */
color: black;
text-align: center; /* Centered text */
font-size: 90px; /* Big font size */
font-weight: bold;
position: fixed; /* Fixed position - sit on top of the page */
top: 0;
width: 100%; /* Full width */
height:90px;
transition: 0.2s; /* Add a transition effect (when scrolling - and font size is decreased) */
}
#header-image {
padding: 0px 10px; /* Some padding */
text-align: center;
top: 0;
transition: 0.2s; /* Add a transition effect (when scrolling - and font size is decreased) */
}
p {
margin:300px;
}
And the JS:
function scrollFunction() {
if (document.body.scrollTop > 10 || document.documentElement.scrollTop > 10) {
document.getElementById("header-image").style.width = "100";
} else {
document.getElementById("header-image").style.width = "400";
}
}
You need to set up an eventListener that calls scrollFunction whenever the user scrolls the wheel.
A shortcut would be to just change <body> to <body onscroll="scrollFunction()">.
You could also set up an event listener in the javascript:
window.addEventListener("scroll", function(e) {
scrollFunction();
}
Your scrollFunction() in never called. You should add event listener for window scroll and remember to add the unit at the end for setting the width- in your case 'px'.
window.onscroll = function() {
if (document.body.scrollTop > 10 || document.documentElement.scrollTop > 10) {
document.getElementById("header").style.width = "100px";
} else {
document.getElementById("header").style.width = "400px";
}
}
i try to set a margin bottom to the body element, but it wont work as expected...
document.addEventListener('DOMContentLoaded', (event) => {
if(window.outerWidth > 768) {
let footerHeight = document.querySelector('footer').offsetHeight;
document.querySelector('body').style.marginBottom = footerHeight + "px";
}
/* .... */
});
its just doing nothing.
the weird part i dont understand: it works as expected when i try to set it as a paddingBottom, but when i change it to margin...
my current solution for now is to wrap it in a setTimeout() like:
document.addEventListener('DOMContentLoaded', (event) => {
if(window.outerWidth > 768) {
setTimeout(function(){
let footerHeight = document.querySelector('footer').offsetHeight;
document.querySelector('body').style.marginBottom = footerHeight + "px";
}, 1);
}
/* .... */
});
let footerHeight gets the correct value in any cases.
no other scripts are loaded which i can think of could affect this...
The simplified CSS & HTML:
body {
margin: 0;
padding-top: 48px;
}
.content-wrapper {
background: #fff;
padding-bottom: 40px;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.08), 0 4px 4px rgba(0, 0, 0, 0.16);
}
footer {
position: fixed;
bottom: 0;
z-index: -1;
background-size: cover;
background-position: center;
display: flex;
width: 100%;
}
<!DOCTYPE html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
</head>
<body class="start">
...
<div class="content-wrapper">
...
</div>
<footer style="background-image: url('/images/polygon.jpg');">
<div class="container">
<div class="row">
...
</div>
</div>
</footer>
<script src="/js/script.js"></script>
</body>
</html>
creates this type of footer reveal effect: https://codepen.io/hkdc/pen/BLJAVL
but to make sure that the whole footer is always visible i add a margin-bottom of the footers height to the body element.
Anyone has an idea what is happening here or am i getting wrong and can explain it?
I'm not sure you understand body tag correctly. You footer is in that body too adding margin to body cant have any effect in this case cause there is no element (at least visible) after body. Padding works cause padding is for the elements inside the body. If you want to add margin before your footer you can use previousSibling property and set its margin.
I'm experimenting with some touch integration with my web app and i'm noticing that with the code posted below the block that moves on touch has a costant offset and I can temporarly remove it by going in f11 mode. How do i remove it such that the block is always under the finger?
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no">
<head>
<title>A title</title>
</head>
<style>
body {
width: 100vw;
height: 100vh;
position: absolute;
top: -8px;
left: -8px;
overflow: hidden;
}
</style>
<body>
<div id="bup" style="position:absolute; background-color:blue;width:100px;height:100px;"></div>
<script>
var touch = [];
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
touch = event.touches;
document.getElementById('bup').style.top= (touch[0].screenY-50) + 'px';
document.getElementById('bup').style.left= (touch[0].screenX-50) + 'px';
}, false);
</script>
</body>
</html>
(the -50 is there just to center the block on my finger considering that the block it self is 100x100px)
ty
Alright i solved it my self.
the issue was the touch[0].screenX. I shoud have used touch[0].clientX, same for the Y.
Hope this helps someone, see ya
I have this code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<style>
#draggable {
width: 150px;
height: 150px;
padding: 0.5em;
border: 1px solid red;
}
.container {
height: 500px;
width: 500px;
border: 1px solid green;
transform: scale(1.6);
position: relative;
left: 300px;
top: 150px;
}
</style>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(function() {
$("#draggable").draggable();
});
</script>
</head>
<body>
<div class="container">
<div id="draggable" class="ui-widget-content">
<p>Drag me around</p>
</div>
</div>
</body>
</html>
It works perfect without transform: scale(1.6);. However, the #draggable moves faster than the mouse with the transform property. How can I make it draggable and scale the container to a value like 1.65? Is there any draggable option I'm supposed to use?
This can be solved by adjusting for the transform: scale(1.6). When the item is dragged, it uses it's position to adjust the top and left of the dragged item. With the scale(), these values are off and you will see the items movement move that same factor faster then the mouse.
x1 = x * 1.6;
y1 = y * 1.6;
To move with the mouse, we need to adjust this back to the same 1:1 (instead of 1:1.6) ratio. This can be done like so:
jQuery > Draggable > Drag Option
drag: function(e, ui) {
// Adjust for Scale
var myScale = parseFloat($('.container').css('transform').split(',')[3]);
var myTop = Math.round(ui.position.top / myScale);
var myLeft = Math.round(ui.position.left / myScale);
ui.position = {
top: myTop,
left: myLeft
};
}
FYI, $('.container').css('transform') will return: matrix(1.6, 0, 0, 1.6, 0, 0). See more: Get CSS transform property with jQuery
You could hard code 1.6 into your script, but I like to keep things portable. So if you change the CSS, you don't have to change this script. See more about setting position: http://api.jqueryui.com/draggable/#event-drag
Working Example: https://jsfiddle.net/Twisty/1gnehyum/