CSS3 Div Animation Relative Spacing - javascript

Recently I have asked a similar question about transition animation in divs. (See this post)
The Code Snippet below shows my solution.
However, the animation only works if the width is given in pixels, not as a percentage.
Does anybody know a way around this?
EDIT (More info to clarify my problem):
In this section of a website, I have a heading that should always stay the same and 3 pages of content which can be "swiped" on user input.
Thus, the span of the left margin of the page would range from -100% to +100%.
I want a swiping animation so that the user can switch from page 2 (i.e. displaying an image) to page 3 (i.e. the text correlating to the image).
Because of different browser window sizes, I need the width to be in percentages. Sadly...
$(document).ready(function() {
$(".next").click(function() {
var current = $(".container").css("left");
if (current == "-200px") {
current = "-400px";
} else if (current == "0px") {
current = "-200px";
}
$(".container").css("left", current);
});
$(".prev").click(function() {
var current = $(".container").css("left");
if (current == "-200px") {
current = "0px";
} else if (current == "-400px") {
current = "-200px";
}
$(".container").css("left", current);
});
});
.row {
border: 1px solid black;
height: 200px;
margin: 0;
width: 200px;
padding: 0;
display: block;
position: relative;
overflow: hidden;
}
.container {
height: 200px;
margin: 0;
width: 600px;
padding: 0;
display: block;
position: absolute;
left: -200px;
top: 0;
-webkit-transition: left 0.5s ease-in-out;
-moz-transition: left 0.5s ease-in-out;
transition: left 0.5s ease-in-out;
}
.ins {
width: 200px;
float: left;
height: 200px;
margin: 0;
padding: 0;
background-color: red;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
.div3 {
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<!-- Thanks to kittyCat at stackoverflow.com for helping me with this website.-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>TITLE</title>
<meta name="Title" content="Main">
</head>
<body>
<div class="row">
<div class="container">
<div class="ins div1">div-1</div>
<div class="ins div2">div-2</div>
<div class="ins div3">div-3</div>
</div>
</div>
<button class="prev">prev</button>
<button class="next">next</button>
</body>
</html>

I have changed the left positioning for a transform on the individual elements:
Now, also, the class row is set to occupy full browser width. The container class is se to 300% (because it will make room for 3 elements). And the children are set to 33% of this, that at the end is 100% of the row.
var pos = 2; /* values 1 - 2 or 3 */
$(document).ready(function() {
$(".next").click(function() {
if (pos == 1) {
$(".container").removeClass("pos1");
$(".container").addClass("pos2");
pos++;
} else if (pos == 2) {
$(".container").removeClass("pos2");
$(".container").addClass("pos3");
pos++;
}
});
$(".prev").click(function() {
if (pos == 3) {
$(".container").removeClass("pos3");
$(".container").addClass("pos2");
pos--;
} else if (pos == 2) {
$(".container").removeClass("pos2");
$(".container").addClass("pos1");
pos--;
}
});
});
.row {
border: 1px solid black;
height: 200px;
margin: 0;
width: 100%;
padding: 0;
display: block;
position: relative;
overflow: hidden;
}
.container {
height: 200px;
width: 300%;
margin: 0;
padding: 0;
display: block;
position: absolute;
top: 0;
}
.ins {
width: 33.33%;
height: 200px;
margin: 0;
padding: 0;
float: left;
transition: transform 0.5s ease-in-out;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
.div3 {
background-color: blue;
}
.pos2 .ins {
transform: translateX(-100%);
}
.pos3 .ins {
transform: translateX(-200%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<!-- Thanks to kittyCat at stackoverflow.com for helping me with this website.-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>TITLE</title>
<meta name="Title" content="Main">
</head>
<body>
<div class="row">
<div class="container pos2">
<div class="ins div1">div-1</div>
<div class="ins div2">div-2</div>
<div class="ins div3">div-3</div>
</div>
</div>
<button class="prev">prev</button>
<button class="next">next</button>
</body>
</html>

Narusan,
If I'm understanding your goal correctly, part of the problem is that no matter what, jQuery wants to return px units to you. You can set a percentage value, but it seems it will not then return those percentages to you.
I changed your code some to demonstrate this:
$(document).ready(function() {
$(".next").click(function() {
var current = $(".container").css("left");
console.log(current);
if (current == "-200px" || current == "-100%") {
current = "-200%";
} else if (current == "0%") {
current = "-100%";
}
$(".container").css("left", current);
});
$(".prev").click(function() {
var current = $(".container").css("left");
console.log(current);
if (current == "-200px" || current == "-100%") {
current = "0%";
} else if (current == "-200%") {
current = "-100%";
}
$(".container").css("left", current);
});
});
You'll see that the values printed to the console are always in px, but if you inspect the DOM you'll see that the % value is being set on the element.
Approaching the problem very differently, like vals did, seems like a good approach.

Related

How can I make the bar run through in 1 second ? in html css and javascript

I'm working on a progress bar (in Javascript) that cycles through every second and then starts again.
I tried to change value with setInteval() but nothing helped me.
I hope for help, thanks
here's my code:
<!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>
<style>
.progress {
position: relative;
width: 510px;
height: 60px;
background: #9cbab4;
overflow: hidden;
}
.progress__fill {
width: 0%;
height: 100%;
background: #009579;
transition: all 0.1s;
}
.progress__text{
position: absolute;
top: 50%;
right: 5px;
transform: translateY(-50%);
font: bold 20px 'Quicksand', sans-serif;
color: #ffffff;
}
</style>
</head>
<body>
<div class="progress">
<div class="progress__fill"></div>
<span class="progress__text">0%</span>
</div>
<script>
setInterval(function(){
value++;
}, 1000);
function updateProgressBar(ProgressBar, value){
ProgressBar.querySelector(".progress__fill").style.width = '${value}%'
ProgressBar.querySelector(".progress__text").textContent = '${value}%'
}
</script>
</body>
</html> ```
I tried reproducing your code by changing the progress, progress__fill, and progress__text into id's and changed the <div class="__" /> into <div id="__" />:
<style>
#progress {
position: relative;
width: 510px;
height: 60px;
background: #9cbab4;
overflow: hidden;
}
#progress_fill {
width: 0%;
height: 100%;
background: #009579;
transition: all 0.1s;
}
#progress_text{
position: absolute;
top: 50%;
right: 5px;
transform: translateY(-50%);
font: bold 20px 'Quicksand', sans-serif;
color: #ffffff;
}
</style>
here's the <div /> in my repro code:
<div id="progress">
<div id="progress_fill"></div>
<span id="progress_text">0%</span>
</div>
then on the <script>, You did not have a variable for value so I made one and set the value to zero: let value = 0; then concatenated it with '%'.
I used window.setInterval then changed the querySelector to document.getElementById because of the changes above.
here's what it looks like on the script tag:
<script>
let value = 0;
window.setInterval(function() {
if (value != 100) {
value++;
document.getElementById("progress_fill").style.width = value + '%';
document.getElementById("progress_text").textContent = value + '%';
}
}, 1000);
</script>
I included an if (value != 100) to stop the cycle when it reaches 100.
Hope this helps! here's my code snippet if you want some reference:
https://jsbin.com/xiwiyew/5/edit?html
I have taken you example and played around a bit.
I have changed it up for I think suits better.
Problem one was you did not call the updateProgressBar() in your interval. So it did not work.. I think the code speaks for itself. If you have a question let me know
My code. Note: you could chose to put the two lines in the update function and move them directly in the interval function. Also the function does not have a cap now. and will go above 100% if left running long enough.
Hope this helps
value = 0;
setInterval(function() {
value++;
updateProgressBar(value);
}, 1000);
function updateProgressBar(value) {
document.querySelector(".progress__fill").style.width = value + "%"
document.querySelector(".progress__text").innerHTML = value + "%"
}
Looking at your code I am geussing you are new. Try writing out/ describing what you want in your head and try have your code replicate that. Example: I want a progressbar with a value, that increments every second. (interval function tells that now). Than the logic that looks clunky/reads less easy can be put behind a function
First of all you have to understand that variables have a scope limitations, so what you can do is get value from your innerHTML and update it in each function call. this way you can get realtime value, without storing it somewhere globally.
Here is the working code for the same.
setInterval(function () {
const progress__text = document.querySelector(".progress__text");
const progress__fill = document.querySelector(".progress__fill");
if (progress__text && progress__fill) {
let value = parseInt(progress__text.innerHTML.split("%")[0]);
if (value === 100) {
progress__fill.style.width = "0%";
progress__text.innerHTML = "0%";
} else {
progress__fill.style.width = ++value + "%";
progress__text.innerHTML = ++value + "%";
}
}
}, 100);
.progress {
position: relative;
width: 510px;
height: 60px;
background: #9cbab4;
overflow: hidden;
}
.progress__fill {
width: 0%;
height: 100%;
background: #009579;
transition: all 0.1s;
}
.progress__text {
position: absolute;
top: 50%;
right: 5px;
transform: translateY(-50%);
font: bold 20px "Quicksand", sans-serif;
color: #ffffff;
}
<body>
<div class="progress">
<div class="progress__fill"></div>
<span value="0" class="progress__text">0%</span>
</div>
</body>
This isn't an accurate way of timing a animation, but pretty simple to implement
const animation = {
duration: 2, // animation length in seconds
steps: 60,
counter: 0,
incrementCounter() {
this.counter += ((1 / this.duration) * (this.steps / 1000) * 100);
this.counter = Math.min(this.counter, 100)
}
}
const draw = setInterval(updateAnimation, animation.steps);
function updateAnimation() {
animation.incrementCounter();
document.querySelector(".progress__fill").style.width = animation.counter + '%'
document.querySelector(".progress__text").textContent = animation.counter + '%'
if (animation.counter === 100) {
animation.counter = 0;
clearInterval(draw)
};
}
.progress {
position: relative;
width: 510px;
height: 60px;
background: #9cbab4;
overflow: hidden;
}
.progress__fill {
width: 0%;
height: 100%;
background: #009579;
transition: all 0.1s;
}
.progress__text {
position: absolute;
top: 50%;
right: 5px;
transform: translateY(-50%);
font: bold 20px 'Quicksand', sans-serif;
color: #ffffff;
}
<div class="progress">
<div class="progress__fill"></div>
<span class="progress__text">0%</span>
</div>

How can I make text change when a page is scrolled to a certain point using jQuery?

I am trying to make the content of a div change when the page is scrolled to a certain point using jQuery. Currently, I am trying to accomplish this by adding a class when the page is scrolled past 800 and removing it and adding a different class when the page is above 800. Here is my current code on jsfiddle: https://jsfiddle.net/shgfrdm8/
Here is the jQuery code:
$(window).scroll(function() {
let windowTop = $(window).scrollTop();
if (windowTop < 800) {
$('image-content').addClass('scrolledDown');
$('image-content').removeClass('scrolledUp');
} else {
$('image-content').addClass('scrolledUp');
$('image-content').removeClass('scrolledDown')
}
})
The CSS ids/classes:
.main {
width: 100%;
height: 700px;
overflow: hidden;
position: relative;
}
.main-image {
width: 100%;
position: fixed;
left: 50%;
transform: translate(-50%) scale(500%);
}
.filler {
height: 400vh;
}
.main-text {
left: -14px;
width: 99.3vw;
height: 4000px;
text-align: center;
background-color: red;
position: relative;
}
#image-content::before {
white-space: pre;
position: absolute;
bottom: 20px;
left: 20px;
font-family: Impact;
font-size: 55px;
font-weight: 550;
color: white;
z-index: 4;
opacity: 1;
position: fixed;
}
#image-content.scrolledDown::before {
opacity: 1;
content: 'ABC';
}
#image-content.scrolledUp::before {
opacity: 1;
content: "DEF";
}
The HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="zoom.css">
</head>
<body>
<div class="image-container">
<div class="zoom main">
<img src="images/sourcecode.jpg" class="main-image">
</div>
<div id="content-anchor"></div>
<div id="image-content"></div>
</div>
<div class="filler">
</div>
<div class="main-text">
</div>
I am wondering how I can make this work because I far as I can tell the classes either not being added or the classes are not working.
Suggesting the following changes:
$(window).scroll(function() {
var windowTop = $(window).scrollTop();
if (windowTop < 800) {
$('.image-content').addClass('scrolledDown');
$('.image-content').removeClass('scrolledUp');
} else {
$('.image-content').addClass('scrolledUp');
$('.image-content').removeClass('scrolledDown')
}
});
This ensures you have the correct Class selector.

CSS javascript animation

I cannot actually do the animation thing. I tried to call the function but it is not working. As a self-learner, i couldn't ask anyone. So, yes. Pretty noob but couldn't find the answer anywhere on web.
<!DOCTYPE html>
<html>
<style>
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
</style>
<body>
<p><button onclick="main()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>
<script>
function main() {
var elem = document.getElementById("animate");
var posTop = elem.style.top;
var posLeft = elem.style.left;
function realAnimate(posTop,posLeft){
if (posTop<350){
for (let index = 0; index < posTop; index++) {
return posTop;
posTop == posLeft;
return posLeft;
realAnimate(posTop,posLeft);
}
}
else{
for (let index = 0; index > posTop; index--) {
return posTop;
posTop == posLeft;
return posLeft;
realAnimate(posTop,posLeft);
}
}
}
}
window.setInterval(main,0)
</script>
</body>
</html>
I am expecting to animate to and from the edges, that the cube has to travel.
just give a inline top and left style to the element so that the DOM will recognize any values. Because if you dont . The value for your element will be undefined
Try this:
function main(){
$('.animate').toggleClass('move');
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
.animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
top:0;
left:0;
transition:all 5s linear;
}
.move{
top:350px;
left:350px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p><button onclick="main()">Click Me</button></p>
<div id ="container">
<div class ="animate"></div>
</div>

Inline Javascript stoped adding class to element

Hey I have an inline javascript code that adds a class to an element and makes it slide up in the screen. But it suddenly stopped working and I don't know why. Here's the HTMl and JS:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 400) {
$(".converter").addClass("atcbottomactive");
} else {
$(".converter").removeClass("atcbottomactive");
}
});
.converter {
position: fixed;
height: 60px;
width: 100%;
bottom: -200;
background: #eeeeee;
transition: 1s;
z-index: 10000;
}
.ccontent {
display: inline-flex;
width: 100%;
padding: 10px 5%;
}
.atcbottomactive{
bottom:0;
transition: 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="background: green; height: 1500px; width: 100%;"></div>
<div class="converter"><div class="ccontent">...</div></div>
Here's the link
Thanks in advance :)
In fact, trying to use it without including JQuery gives you the error. You can solve this easily with "JavaScript" without using jQuery.
var element = document.querySelector(".converter");
window.addEventListener('scroll', function() {
var scroll = window.pageYOffset || document.documentElement.scrollTop;
if (scroll >= 400) {
element.classList.add("atcbottomactive");
} else {
element.classList.remove("atcbottomactive");
}
});
.converter {
padding: 20px 20px 200%;
background: blue;
color: white;
}
.converter.atcbottomactive {
background: green;
}
<div class="converter">
<div class="ccontent">Scroll me: 400px</div>
</div>

Parallax Curtain Reveal Effect with jQuery and CSS3

It is really difficult to explain what kind of effect I mean. But let me try. :)
When you scroll down one DIV with text Block moves over a fixed background DIV with a background image. Now when the DIV on top leave the bottom area and moves to the top of the viewport you can seen the half (and later the full) new background image. But the Background Images are not moving, they are fixed. Only the Page Content with Text Blocks moves when you scroll down.
If you still see a question mark then take a look at this website, there you can see the concept in use.
So my question is how can I recreate this effect only with CSS3 and jQuery (Without YUI etc.)?
I don't really understand the logic that is needed for this to work. How do I need to animate the DIVs and where should I place them in the HTML Document.
Below you find some tests I did (But they don't work)
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0, minimal-ui">
<title>Agency</title>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<script>
$(document).ready(function() {
$("div.blankItem").css("min-height", $(window).innerHeight()-44);
$("div.red").css("min-height", $(window).innerHeight()-44);
var windowHeight = $(window).innerHeight()+ 44;
var total = - windowHeight - 400;
$('div.red').css('-webkit-transform', 'translate3d(0,' + total + 'px,0)');
//$("div.pageContentBackground").css("bottom", -$(window).innerHeight()+44 + "px");
//$("div.pageContentBackground").css("bottom", -$(window).innerHeight()-44);
$(window).resize(function() {
$("div.blankItem").css("min-height", $(window).innerHeight()-44);
$("div.red").css("min-height", $(window).innerHeight()-44);
//$("div.pageContentBackground").css("bottom", -$(window).innerHeight()+44 + "px");
//$("div.pageContentBackground").css("bottom", -$(window).innerHeight()-44);
});
$(function(){
$(window).bind({scroll: Scroll, touchmove: Scroll});
});
function Scroll(){
// var op = (window.pageYOffset-$(window).innerHeight()-44-356);
// $("div.pageContentBackground").css("bottom", + op);
var scrollTop = $(window).scrollTop();
var pageYDoc = 1300;
var factor = 0.8;
var pageYViewport = pageYDoc - scrollTop;
var imageY = -1 * parseInt(pageYViewport * factor);
//var tr = -200; // You'd need to calculate this value
/**$('div.red').css("-webkit-transform", "translate3d(0, " + tr + "px, 0)");
*/
//var offset = total + $(window).scrollTop()+400;
$('div.red').css({'-webkit-transform': 'translate3d(0, '+ imageY + '%, 0)'});
// $('div.blue').stop().css('bottom', $(window).scrollTop() - $(window).innerHeight()-44-400 + "px");
console.log(offset);
}
});
</script>
<style>
* {
padding: 0;
margin: 0;
}
ul, li {
margin: 0;
padding: 0;
}
a {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-moz-tap-highlight-color: rgba(0,0,0,0);
tap-highlight-color: rgba(0,0,0,0);
text-decoration: none;
}
html {
-ms-text-size-adjust: none;
-webkit-text-size-adjust: none;
}
body {
transition:all .2s linear;
-o-transition:all .2s linear;
-moz-transition:all .2s linear;
-webkit-transition:all .2s linear;
font-family: 'Open Sans', Helvetica;
color: #F0F2ED;
-webkit-font-smoothing: subpixel-antialiased !important;
}
div.pageMenu {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 44px;
background-color: #333;
z-index: 10;
opacity: 0.99;
}
a.pageMenuButton {
position: fixed;
top: 8px;
right: 44px;
text-decoration: none;
color: #fff;
font-weight: bold;
}
div.pageHeader {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: #daddda;
z-index: 1;
padding-bottom: 10px;
}
div.pageContent {
position: absolute;
top: 100%;
width: 100%;
z-index: 5;
max-width: 100%;
overflow: hidden;
}
div.pageContentBackground {
position: fixed;
left: 0px;
width: 100%;
}
div.red {
background-color: red;
z-index: 2;
}
div.blue {
background-color: blue;
z-index: 3;
}
div.pageContentBody {
width: 100%;
z-index: 2;
}
div.pageContentBodyItem {
width: 100%;
height: 400px;
background-color: #fff;
display: block;
}
div.blankItem {
background: transparent;
width: 100%;
display: block;
}
</style>
</head>
<body>
<div class="pageMenu">
<div class="pageMenuLogo">
</div>
☰
</div>
<div class="pageHeader">
</div>
<div class="pageContentBackground red">
</div>
<!--<div class="pageContentBackground blue">
</div>-->
<div class="pageContent">
<div class="pageContentBody">
<div class="pageContentBodyItem">
</div>
<div class="blankItem">
</div>
<div class="pageContentBodyItem">
</div>
<div class="blankItem">
</div>
<div class="pageContentBodyItem">
</div>
<div class="blankItem">
</div>
<div class="pageContentBodyItem">
</div>
<div class="blankItem">
</div>
<div class="pageContentBodyItem">
</div>
</div>
</div>
<div class="pageContentFooter">
</div>
</div>
</body>
This is my try: http://codepen.io/rafaelcastrocouto/pen/bCxAd
Although there are lots of differences in the sites, they are still kinda alike.
Notice that my parallax only woks on big screens.
The JS is pretty small:
var lastScrollTop = 0;
var backgroundImages = $('.backgroundImage');
$(window).scroll(function(e){
var st = $(this).scrollTop();
var ah = $(this).height();
backgroundImages.each(function(i){
var img = $(this);
var pos = img.position().top;
var hei = img.height();
if ((st + ah) > pos && st < (pos + hei)){
var p = ((pos - st)/ah) + 0.25;
if(i == 1) console.log(p);
img.css('background-position', '50%'+(p*100)+'%');
}
});
lastScrollTop = st;
});
$(window).scroll();

Categories

Resources