setProperty("left",...) on absolute div slow in parallax - javascript

I want to build a sidescrolling parallax effect with 3 different overlaying pictures that move at different speeds, my code for this is the following:
<div class="parallax-wrapper">
<div class="parallax1 parallax"></div>
<div class="parallax2 parallax"></div>
<div class="parallax3 parallax"></div>
</div>
.parallax-wrapper {
width: 100%;
height: 100%;
background-color: black;
}
.parallax {
position: fixed;
display: inline-block;
width: 500%;
height: 100%;
left: 0;
background-size: auto 100%;
}
.parallax1 {
background-image: url("../assets/Parallax/Parallax1.svg");
}
.parallax2 {
background-image: url("../assets/Parallax/Parallax2.svg");
}
.parallax3 {
background-image: url("../assets/Parallax/Parallax3.svg");
}
and this function that is called on scroll:
function updateScroll(scrollDest){
parallax1.style.setProperty("left", "-" + (scrollDest * 0.3) + "px")
parallax2.style.setProperty("left", "-" + (scrollDest * 0.2) + "px")
parallax3.style.setProperty("left", "-" + (scrollDest * 0.1) + "px")
}
I have done this differently before which worked but had little browser support so I changed it to this method which I thought was very lightweight but sadly it is very laggy on mobile and also not very smooth on my desktop PC, why is this method so slow and how to improve it?

I guess you probably just added event listener to window on scroll, that causes calling updateScroll on every scroll event. I'd suggest using throttling and debouncing, to reduce amount of events (Great example you can find on other stack question "Simple throttle in JavaScript".
After reducing the amount of events it'll be a little weird, so I'd suggest adding also transition on left like this:
.parallax {
transition: left .2s;
}

Related

Analogue of zoom in css? Transform: scale() property as zoom property

There is a zoom property in css, it does what it needs, but there is no support in browsers (Firefox in particular). There is also a transform: scale () property, but the fact is that the main_div block becomes visible when using transform: scale (), which is not when using the zoom property. I need exactly this behavior.
Can the transform: scale() property be applied in such a way that it works like a zoom? Or what analogs does the zoom property have? How to be in this situation?
Here is my code. You need to check in Google Chrome, since Firefox's zoom property does not work
https://jsfiddle.net/tj2349f5/1/
html
<div id='main_div'>
<div id="second_div">Hello</div>
</div>
<input class="test_button" type="button" name="button_name" value="test">
JavaScript
let test_button = document.querySelector('input.test_button');
test_button.addEventListener('click', () => {
//second_div.style.transform = 'scale(0.5)';
second_div.style.zoom = 0.5;
});
The difference between a 'real' CSS zoom and a scale is that a scaled element does not change the space it takes up whereas a zoomed one does.
I am not absolutely sure whether this code does what you want as on my device I don't see the red appearing as described in the question [I think this is because my device is narrower]. What it does is change the width and height of the zoomed element alongside the scaling.
The effect on Chrome that I see is that the scrollbars change the same amount whether using this code or the real CSS zoom whereas using scale only the scrollbars don't change at all.
let test_button = document.querySelector('.test_button');
test_button.addEventListener('click', () => {
second_div.style.height = second_div.offsetHeight * 0.5 + 'px';
second_div.style.width = second_div.offsetWidth * 0.5 + 'px';
second_div.style.transform = 'scale(0.5)';
test_button.style.display = 'none';
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
div {
display: flex;
}
div#main_div {
display: block;
margin: 10px auto;
height: 80vh;
width: 80vw;
background: red;
overflow: scroll;
}
div#second_div {
height: 3000px;
width: 3000px;
background: green;
transform-origin: 0% 0%;
}
<div id='main_div'>
<div id="second_div">Hello</div>
</div>
<button class="test_button">CLICK TO MAKE IT LOOK LIKE A REAL CSS ZOOM BUT USING SCALE AND DIMENSION SETTING</button>
Note: if you scale back up remember to restore the dimensions as well.

Progress- percentage bar for webpage

I am trying to make a loading bar but with percentage. I mean imagine when it’s 50% it will show that number also it will fill until half. If it’s 75% it will go up until 3/4.
I am trying to do this with HTML,CSS and JS. So far I made up everything but at the same time number will increase (by clicking button) and pattern will fill up according to percentage? This part is challenging me.
Can you lead me way if it’s possible? Or even if there is example so I can learn?
UPDATE CODE BELOW
<script>
var i = 0;
function buttonClick5() {
i += 5;
document.getElementById('demo').innerHTML = i + "€";
}
function percentage(per) {
return (100 / 100) * per;
}
</script>
<div class="textContainer">
<p class="perc" id="here"></p>
<script>
document.getElementById('here').textContent = percentage(10) + "%";
</script>
<h2 id="demo">0€</h2>
</div>
and css part
.textContainer {
margin-top:-10%;
margin-left: 30%;
height: auto;
text-align: center;
}
.textContainer h2 {
margin-left: -40%;
font-size: 500px;
color: rgba(225, 225, 225, .1);
background-image: url(color3.jpg);
background-repeat:repeat;
-webkit-background-clip: text;
animation: animateMid 15s linear infinite;
}
#keyframes animateMid {
0% {
background-position: left 0px top 0px;
}
1% {
background-position: left 1200px top 0px;
}
}
basically with those I can just make pattern moving as background of the percentage but always at 100 per cent.
Use your percentage variable as a width of the div that shows progress. Add click even listener to your button that will update that percentage variable and width of the div. If you make a callback function that updates both at the same it would be easy for you. Share your code here so we can help further.

Invert scroll on rotate(180d)

Having a small problem. (Refer to fiddle)
I've got a container in my project that has been rotated 180 deg, with a container inside that has been rotated another 180 back to the original state.
I need to invert the scroll.
How would i go about this?
Dont mind wasting your time with a method, that reverts the basic setup.
The basic setup has to stay.
http://jsfiddle.net/vavxy36s/
Description of fiddle:
"Start" marks the initial string and "end" ofcourse the last one.
If you try scrolling you will realize, that it's inverted as to how one would normally scroll.
.class1 {
height: 200px;
background-color: blue;
color: white;
width: 100px;
overflow-y: scroll;
overflow-x: hidden;
direction: rtl;
-webkit-transform: rotate(180deg);
}
.class2 {
direction: ltr;
-webkit-transform: rotate(180deg);
}
EDIT: Just mousewheel scroll, has to be inverted.
Edit: Your original setup has different behaviors in Chrome and in [IE & Firefox]. In Chrome, the scroll is already inverted, but in FF and IE, the scroll remains normal. My solution reverts it in both cases, but the behaviors remain different across browsers.
You could add these styles:
/* ...
Your original styles
...
*/
.class1 {
overflow: hidden;
position: relative;
}
.class2 {
position: absolute;
bottom: 0;
}
And then, using jQuery, modify the bottom CSS property of .class2:
var scrollPos = 0,
diff = $('.class2').height() - $('.class1').height();
$('.class1').on('mousewheel', function(e) {
scrollPos = Math.min(
0,
Math.max(
-diff,
scrollPos + e.originalEvent.wheelDelta
)
);
$('.class2').css('bottom', scrollPos);
});
JS Fiddle Demo
You could use the mousewheel library to catch and invert the scroll movement.
$(".class1").mousewheel(function(event) {
event.preventDefault();
this.scrollTop -= (event.deltaY * event.deltaFactor * -1);
});
You can view a demo here: http://jsfiddle.net/fduu20df/1/

keep the background image fixed position and centered

In my project, I need to show a small image in center of the visible part of the container, with respect to the window i.e .loader. Even when the user scrolls the page, the image should be visible in center of .loader.
I successfully implemented this but now I am facing a edgecase which is when user scrolls the page "up to the header" or "down to the footer", the small image is hiding. demo.
This is actually normal behaviour but in these edgecases, I want the image to stick to top/bottom end of the .loader container.
What I want:
Keep the small image always at center of .loader container. (I already implemented this)
when scrolled to any end of .loader container, the image should stick to that end instead of hiding behind the container.
Fiddle
A solution using just css is preferred. I am looking for browser support in IE9+, chrome and firefox.
.header {
height: 600px;
width: 650px;
background-color: grey;
}
.left-side {
height: 300px;
width: 150px;
float: left;
background-color: red;
}
.loader {
background-image: url('http://i.imgur.com/U2njI.jpg');
margin-left: 150px;
height: 1500px;
width: 500px;
background-position: 345px center;
background-repeat: no-repeat;
background-attachment: fixed;
background-color: cornflowerblue;
}
.footer {
height: 600px;
width: 650px;
background-color: silver;
}
<div class="header"></div>
<div class="left-side"></div>
<div class="loader"></div>
<div class="footer"></div>
Here is a working solution with javascript, I hope its behaviour is how you expect it to be. I'm unfortunately not able to test it on IE9 right now but it should work (DEMO):
document.addEventListener('DOMContentLoaded',function() {
var loader = document.querySelector('.loader'),
loaderRect = loader.getBoundingClientRect(),
loaderTop = loaderRect.top + document.body.scrollTop,
loaderBottom = loaderTop + loader.offsetHeight,
initialBgPos = loader.style.backgroundPosition,
imageHeight = 141;
function onScroll() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if(loaderTop >= (scrollTop + (window.innerHeight - imageHeight)/2)) {
loader.style.backgroundPosition='345px ' + (loaderTop - scrollTop) + 'px';
} else if(loaderBottom <= (scrollTop + (window.innerHeight + imageHeight)/2)) {
loader.style.backgroundPosition='345px ' + (loaderBottom - scrollTop - imageHeight) + 'px';
} else {
loader.style.backgroundPosition = initialBgPos;
}
}
window.addEventListener('scroll', onScroll);
onScroll();
});
To achieve what I think you want. We have to set the position of the .loader div to fixed, then it'll always stay where it's placed, regardless of whether the user scrolls the page, the div will scroll too. In here's how to set the position of loader to fixed in CSS (you may also have to get the position of your fixed div):
.loader{
position: fixed;
left: 100px;
top: 300px;
}
Here's your upadted JSFiddle: http://jsfiddle.net/Ezhb4/4/

Use full height in mobile browse with retracting address bar

I have a web page where I want to use the full height (no more, no less) of the screen with two stacked divs, so that the second div fills out the height that remains after the first one.
At the moment I am doing it like this:
css
body { height: 100%; }
JavaScript
window.onload=function(){
document.getElementById('div2').style.height =
(document.getElementById('body').offsetHeight -
document.getElementById('div1').offsetHeight) + 'px';
}
This works fine, but in mobile browsers (tested on Android default browser and Chrome) the address bar remains visible, although it can be hidden and the space used for the second div. I assume similar behaviour can be expected from iPhones.
So my question is: Does anyone know how to get the available height in a mobile browser, including retractable address bar?
edit
Ifound this:http://mobile.tutsplus.com/tutorials/mobile-web-apps/remove-address-bar/, but I can't get it to work in Chrome.
update
I am now using this code, but it still doesn't work in Android Chrome (and I haven't tried it in iPhones).
JavaScript function:
if(typeof window.orientation !== 'undefined') {
document.body.style.height = (window.outerHeight) + 'px';
setTimeout( function(){ window.scrollTo(0, 50); }, 50);
}
document.getElementById('div2').style.height =
(document.body.offsetHeight -
document.getElementById('div2').offsetHeight) + 'px';
I am calling this function in window.onload and window.onresize.
Try this:
HTML
<div class="box">
<div class="div1">1st</div>
<div class="div2">2nd</div>
<div class="clear"></div>
</div>
CSS
html, body { height: 100%; }
div.box { background: #EEE; height: 100%; width: 600px; }
div.div1{background: #999; height: 20%;}
div.div2{ background: #666; height: 100%; }
div.clear { clear: both; height: 1px; overflow: hidden; font-size:0pt; margin-top: -1px; }
See the demo.
Hope it helped.

Categories