Im trying to move sections up and down on the wheel event by changing class on previous, inView and next sections. so every wheel event will change the activeIndex and hence classes to each sections. Also when the window is loaded the starting activeIndex = 0 so that it always starts from the top. i want to know is my approach correct? is it correct to add class to activeIndex and classes to sections before and after like:
Var previousSection = section[activeIndex - 1];
previousSection.classList.add("previous")
Var inViewSection = section[activeIndex];
inViewSection.classList.add("inView");
Var nextSection = section[activeIndex + 1];
nextSection.classList.add("next");
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
home, body {
margin: 0;
padding: 0;
overflow: hidden;
user-select: none;
}
section {
position: absolute;
left: 0;
width: 100vw;
height: 100vh;
transition: 1s ease-out;
}
.first {background-color:black;}
.second {background-color:red;}
.third {background-color:blue;}
.fourth {background-color:green;}
.fifth {background-color:yellow;}
.inView {top: 0;}
.previous {top: -100vh;}
.next {top: 100vh;}
</style>
<script>
window.load = function() {
var activeIndex = 0;
}
window.addEventListener("wheel", event => {
const delta = Math.sign(event.deltaY);
//console.info(delta);
if (delta > 0) {
nextSection();
}
else if (delta < 0) {
previousSection();
}
});
section: document.querySelectorAll(".section");
activeIndex: 0;
function nextService() {
if (activeIndex = sections.length) return;
let previousService = section[activeIndex - 1];
previousService.classList.add("previous");
let activeService = section[activeIndex];
activeService.classList.add("inView");
let nextService = section[activeIndex + 1];
nextService.classList.add("next");
activeIndex++;
//update the above variables
}
</script>
</head>
<body>
<section class="first section"></section>
<section class="second section"></section>
<sectionc class="third section"></sectionc>
<section class="fourth section"></section>
<section class="fifth section"></section>
</body>
</html>
You can't use Var as capital letter. It must be var with lowercase.
Wrong
Var previousSection = section[activeIndex - 1];
Var inViewSection = section[activeIndex];
Var nextSection = section[activeIndex + 1];
Correct
var previousSection = section[activeIndex - 1];
var inViewSection = section[activeIndex];
var nextSection = section[activeIndex + 1];
Related
How can this script start counting from zero? At the moment it starts with the number it's supposed to count to before starting from zero
The JavaScript function loads the counter when it is called into view. How can the numerical values in the counter start with zeros when it is called into view
function isVisible(el) {
const element = $(el);
var WindowTop = $(window).scrollTop();
var WindowBottom = WindowTop + $(window).height();
var ElementTop = element.offset().top;
//var ElementBottom = ElementTop + element.height();
var ElementBottom = ElementTop + 20;
return ElementBottom <= WindowBottom && ElementTop >= WindowTop;
}
function Counter(el) {
obj = $(el);
if (obj.hasClass("ms-animated")) {
return;
}
obj.addClass("ms-animated");
// get the number
var number = obj.text();
obj.attr("data-number", number);
// clear the HTML element
obj.empty();
// create an array from the text, prepare to identify which characters in the string are numbers
var numChars = number.split("");
var numArray = [];
var setOfNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// for each number, create the animation elements
for (var i = 0; i < numChars.length; i++) {
if ($.inArray(parseInt(numChars[i], 10), setOfNumbers) != -1) {
obj.append(
'<span class="digit-con"><span class="digit' +
numArray.length +
'">0<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br></span></span>'
);
numArray[numArray.length] = parseInt(numChars[i], 10);
} else {
obj.append("<span>" + numChars[i] + "</span>");
}
}
// determine the height of each number for the animation
var increment = obj.find(".digit-con").outerHeight();
var speed = 2000;
// animate each number
for (var i = 0; i < numArray.length; i++) {
obj
.find(".digit" + i)
.animate({
top: -(increment * numArray[i])
},
Math.round(speed / (1 + i * 0.333))
);
}
}
$(window).scroll(function() {
const counterNumbers = $(".number").toArray();
counterNumbers.filter(isVisible).map(Counter);
});
$(window).trigger("scroll");
.number {
display: block;
font-size: 6rem;
line-height: 6.5rem;
}
.number *+* {
margin-top: 0;
}
.digit-con {
display: inline-block;
height: 6.5rem;
overflow: hidden;
vertical-align: top;
}
.digit-con span {
display: block;
font-size: 6rem;
line-height: 6.5rem;
position: relative;
text-align: center;
top: 0;
width: 0.55em;
}
.month {
height: 100vh;
}
<h1>Scroll</h1>
<div class="number">$2,350,354.43</div>
<div class="month">March</div>
<div class="number">$6,350,354.43</div>
<div class="month">March</div>
<div class="number">$8,500,435.33</div>
<div class="month">April</div>
<div class="number">$3,500,435.53</div>
<div class="month">May</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
Your issue is a something similar to FOUC - Flash of Unstyled Content - where what's originally in the HTML is displayed before it can be updated.
This can be fixed by changing the html and showing the value you want to display on load, while storing the required number in a data- attribute, eg:
<div class="number" data-number="$2,350,354.43">$0,000,000.00</div>
with a small change to your existing code to read the data- instead of text, from
var number = obj.text();
obj.attr("data-number", number); // this is never used
to
var number = obj.data("number");
If you can't change the html (or don't want to) then you can have an initialisation script run before your first scroll initialisation:
$(".number").each((i,e) => {
var obj = $(e);
var number = obj.text();
obj.data("number", number);
obj.text(number.replace(/\d/g, "0"));
});
You will still get FOUC on the very first counter if it's already visible because that's how javascript works: to keep things simple/basic: the page is rendered, then js runs. So there's a short time before the js runs where it's parsing/processing the js ready to run - how long this will be depends on how much js you have (including libraries) / whether it's cached / how much initialisation code there is.
Generally better to output your HTML as you want it displayed rather than rely on JS to update it, but that's not always possible.
Updated snippet:
function isVisible(el) {
const element = $(el);
var WindowTop = $(window).scrollTop();
var WindowBottom = WindowTop + $(window).height();
var ElementTop = element.offset().top;
//var ElementBottom = ElementTop + element.height();
var ElementBottom = ElementTop + 20;
return ElementBottom <= WindowBottom && ElementTop >= WindowTop;
}
function Counter(el) {
obj = $(el);
if (obj.hasClass("ms-animated")) {
return;
}
obj.addClass("ms-animated");
// get the number
//var number = obj.text();
//obj.attr("data-number", number);
var number = obj.data("number");
// clear the HTML element
obj.empty();
// create an array from the text, prepare to identify which characters in the string are numbers
var numChars = number.split("");
var numArray = [];
var setOfNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// for each number, create the animation elements
for (var i = 0; i < numChars.length; i++) {
if ($.inArray(parseInt(numChars[i], 10), setOfNumbers) != -1) {
obj.append(
'<span class="digit-con"><span class="digit' +
numArray.length +
'">0<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br></span></span>'
);
numArray[numArray.length] = parseInt(numChars[i], 10);
} else {
obj.append("<span>" + numChars[i] + "</span>");
}
}
// determine the height of each number for the animation
var increment = obj.find(".digit-con").outerHeight();
var speed = 2000;
// animate each number
for (var i = 0; i < numArray.length; i++) {
obj
.find(".digit" + i)
.animate({
top: -(increment * numArray[i])
},
Math.round(speed / (1 + i * 0.333))
);
}
}
$(window).scroll(function() {
const counterNumbers = $(".number").toArray();
counterNumbers.filter(isVisible).map(Counter);
});
$(".number").each((i,e) => {
var obj = $(e);
var number = obj.text();
obj.data("number", number);
obj.text(number.replace(/\d/g, "0"));
});
$(window).trigger("scroll");
.number {
display: block;
font-size: 6rem;
line-height: 6.5rem;
}
.number *+* {
margin-top: 0;
}
.digit-con {
display: inline-block;
height: 6.5rem;
overflow: hidden;
vertical-align: top;
}
.digit-con span {
display: block;
font-size: 6rem;
line-height: 6.5rem;
position: relative;
text-align: center;
top: 0;
width: 0.55em;
}
.month {
height: 100vh;
}
<h1>Scroll</h1>
<div class="number">$2,350,354.43</div>
<div class="month">March</div>
<div class="number">$6,350,354.43</div>
<div class="month">March</div>
<div class="number">$8,500,435.33</div>
<div class="month">April</div>
<div class="number">$3,500,435.53</div>
<div class="month">May</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
I have a vertical navbar. When the client is on the website and viewing a section of the page that corresponds to the navbar button, that button should have a white border around it. When the client leaves that section for another section, that button should have a border around it and the last buttons border should disappear.
Unfortunately, only half of this works. I don't know why but when I scroll to another section the last sections corresponding button doesn't lose it's border, even though the debug messages state that the border color has been computed to be 'transparent'.
I've tried setting all faces of the border to transparent (top, bottom, left, right) and I've tried setting the style is jquery.
$(document).ready(() => {
$('.page').css('height', $(window).height());
$('.navbar').css('height', $(window).height());
})
let currentActiveButton = null;
document.addEventListener("scroll", () => {
let ids = calculateVisiblePages();
console.log(ids.join(", ") + "\n");
let heights = getVisibleHeights(ids);
let entry;
let highest = -1;
for (let i = 0; i < ids.length; i++) {
const id = ids[i];
if (highest == -1) {
highest = heights[id];
entry = id;
continue;
}
let height = heights[id];
if (highest < height) {
highest = height;
entry = id;
}
}
// console.log(`Highest: ${entry}`);
if (currentActiveButton === entry) return;
if (currentActiveButton != null) {
console.log(
`Attempting to set current active button, id is ${currentActiveButton}, to transparent.`
);
let activeButton = document.getElementById(currentActiveButton);
activeButton.style.borderColor = 'transparent';
let computedStyle = window.getComputedStyle(activeButton);
console.log(`Computes style border color: ${computedStyle.borderTopColor}`);
}
currentActiveButton = entry;
let buttons = document.getElementsByClassName("navbar_button");
switch (entry) {
case "projects": {
console.log("Case is projects.");
borderButton("portfolioButton");
return;
}
case "previousComms": {
borderButton("previousCommsButton");
return;
}
case "aboutMe": {
borderButton("aboutMeButton");
return;
}
}
});
// function getCurrentActiveButton() {
// let buttons = document.getElementsByClassName("navbar_button");
// for (let i = 0; i < buttons.length; i++) {
// const button = buttons[i];
// let computed = window.getComputedStyle(button);
// if (computed.borderTopColor.startsWith("rgba(255, 255, 255")) {
// return button;
// }
// }
// }
function borderButton(id) {
let button = document.getElementById(id);
let computedStyle = window.getComputedStyle(button);
button.style.borderColor = "white";
}
function calculateVisiblePages() {
let pages = document.getElementsByClassName("page");
let visible = [];
for (let i = 0; i < pages.length; i++) {
const page = pages[i];
if (isVisible(page)) visible.push(page.id);
}
return visible;
}
function isVisible(element) {
let elementTop = element.offsetTop;
let elementBottom =
elementTop + Number(element.style.height.replace("px", ""));
let viewportTop = window.scrollY;
let viewportBottom = viewportTop + window.innerHeight;
return elementBottom > viewportTop && elementTop < viewportBottom;
}
function getVisibleHeights(ids) {
let cache = {};
for (let i = 0; i < ids.length; i++) {
// console.log(`Iterating on element: ${ids[i]}`);
const element = document.getElementById(ids[i]);
let elementTop = element.offsetTop;
let elementBottom =
elementTop + Number(element.style.height.replace("px", ""));
let viewportBottom = window.scrollY + window.innerHeight;
let bottom = elementBottom - viewportBottom;
if (bottom < 0) bottom = elementBottom;
if (bottom < viewportBottom && viewportBottom < elementBottom)
bottom = viewportBottom;
let top = elementTop > window.scrollY ? elementTop : window.scrollY;
cache[element.id] = bottom - top;
// for (let i = elementTop; i < elementBottom; i++) {
// //Check if pixel is in element and in the viewport.
// // console.log(`Iteration: ${i}`);
// if (i < window.scrollY) continue;
// if (i > window.scrollY && i < elementBottom && i < viewportBottom) {
// cache[element.id] = i - window.scrollY;
// }
// }
}
return cache;
}
The CSS:
#import url(https://fonts.googleapis.com/css?family=Roboto:500&display=swap);
.root {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 95% 5%
}
.pages {
display: grid;
grid-template-rows: auto auto auto
}
.page {
height: 100%;
width: 100%
}
#projects {
background: #00f
}
#previousComms {
background: #ff0
}
#aboutMe {
background: red
}
.navbar_buttons_wrapper {
height: 100%;
width: 5%;
position: fixed;
top: 0;
right: 0
}
.navbar_buttons {
height: 100%;
display: flex;
align-items: center;
justify-content: center
}
.navbar_buttons ul {
height: auto;
list-style: none;
color: #fff;
padding: 0;
display: grid;
grid-template-columns: auto auto auto;
transform: rotate(-90deg)
}
.navbar_buttons ul li {
width: max-content;
margin-left: 30px;
margin-right: 30px;
font-size: 1.2rem;
text-transform: uppercase;
border-style: solid;
border-color: transparent;
transition: .7s;
padding: 7px
}
html body {
font-family: Roboto, sans-serif;
margin: 0;
border: 0;
padding: 0;
background: #2c2c2c
}
The HTML:
<html>
<head>
<link rel="stylesheet" type="text/css" href="./styles/main.css" />
<script type="text/javascript" src="./scripts/main-min.js"></script>
</head>
<body>
<div class="root">
<div class="pages">
<div class="page" id="projects"></div>
<div class="page" id="previousComms"></div>
<div class="page" id="aboutMe"></div>
</div>
<div class="navbar">
<div class="navbar_buttons_wrapper">
<div class="navbar_buttons">
<ul>
<li class="navbar_button" id="portfolioButton">Portfolio</li>
<li class="navbar_button" id="previousCommsButton">Previous Commissioners</li>
<li class="navbar_button" id="aboutMeButton">About Me</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
I had expected the border to change from white to transparent. However, all I got was no change to the color of the border of the button of the section I had previously been looking at on the website:
Before Movement: https://gyazo.com/77171adefe255973709f11e305bfb030
After Movement: https://gyazo.com/b121d1d33b4f5f205df1468cd936352b
Source Before Movement: https://gyazo.com/92359267cf06cbe3b7c4942f04dbf9ea
Source After Movement: https://gyazo.com/7cc03865e17fc42382774747fb30052a
Github Project File: https://github.com/TheMasteredPanda/Portfolio-Website/blob/master/src/scripts/src/navbarBorderManagement.js#L32
Your problem is inconsistent naming conventions between your ID's and it's causing your element objects to get obfuscated, so if for example you were to breakpoint where you're setting your borderColor to reset it back to transparent, you'd see you're hitting a page HTMLDivElement and not the li you're aiming for. See changes below and have a great weekend, cheers!
$(document).ready(() => {
$('.page').css('height', $(window).height());
$('.navbar').css('height', $(window).height());
})
let currentActiveButton = null;
document.addEventListener("scroll", () => {
let ids = calculateVisiblePages();
console.log(ids.join(", ") + "\n");
let heights = getVisibleHeights(ids);
let entry;
let highest = -1;
for (let i = 0; i < ids.length; i++) {
const id = ids[i];
if (highest == -1) {
highest = heights[id];
entry = id;
continue;
}
let height = heights[id];
if (highest < height) {
highest = height;
entry = id;
}
}
// console.log(`Highest: ${entry}`);
if (currentActiveButton === entry) return;
if (currentActiveButton != null) {
console.log(
`Attempting to set current active button, id is ${currentActiveButton}, to transparent.`
);
let activeButton = document.getElementById(currentActiveButton + 'Button');
activeButton.style.borderColor = 'transparent';
let computedStyle = window.getComputedStyle(activeButton);
console.log(`Computes style border color: ${computedStyle.borderTopColor}`);
}
currentActiveButton = entry;
let buttons = document.getElementsByClassName("navbar_button");
switch (entry) {
case "projects": {
console.log("Case is projects.");
borderButton("projectsButton");
return;
}
case "previousComms": {
borderButton("previousCommsButton");
return;
}
case "aboutMe": {
borderButton("aboutMeButton");
return;
}
}
});
// function getCurrentActiveButton() {
// let buttons = document.getElementsByClassName("navbar_button");
// for (let i = 0; i < buttons.length; i++) {
// const button = buttons[i];
// let computed = window.getComputedStyle(button);
// if (computed.borderTopColor.startsWith("rgba(255, 255, 255")) {
// return button;
// }
// }
// }
function borderButton(id) {
let button = document.getElementById(id);
let computedStyle = window.getComputedStyle(button);
button.style.borderColor = "white";
}
function calculateVisiblePages() {
let pages = document.getElementsByClassName("page");
let visible = [];
for (let i = 0; i < pages.length; i++) {
const page = pages[i];
if (isVisible(page)) visible.push(page.id);
}
return visible;
}
function isVisible(element) {
let elementTop = element.offsetTop;
let elementBottom =
elementTop + Number(element.style.height.replace("px", ""));
let viewportTop = window.scrollY;
let viewportBottom = viewportTop + window.innerHeight;
return elementBottom > viewportTop && elementTop < viewportBottom;
}
function getVisibleHeights(ids) {
let cache = {};
for (let i = 0; i < ids.length; i++) {
// console.log(`Iterating on element: ${ids[i]}`);
const element = document.getElementById(ids[i]);
let elementTop = element.offsetTop;
let elementBottom =
elementTop + Number(element.style.height.replace("px", ""));
let viewportBottom = window.scrollY + window.innerHeight;
let bottom = elementBottom - viewportBottom;
if (bottom < 0) bottom = elementBottom;
if (bottom < viewportBottom && viewportBottom < elementBottom)
bottom = viewportBottom;
let top = elementTop > window.scrollY ? elementTop : window.scrollY;
cache[element.id] = bottom - top;
// for (let i = elementTop; i < elementBottom; i++) {
// //Check if pixel is in element and in the viewport.
// // console.log(`Iteration: ${i}`);
// if (i < window.scrollY) continue;
// if (i > window.scrollY && i < elementBottom && i < viewportBottom) {
// cache[element.id] = i - window.scrollY;
// }
// }
}
return cache;
}
#import url(https://fonts.googleapis.com/css?family=Roboto:500&display=swap);
.root {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 95% 5%
}
.pages {
display: grid;
grid-template-rows: auto auto auto
}
.page {
height: 100%;
width: 100%
}
#projects {
background: #00f
}
#previousComms {
background: #ff0
}
#aboutMe {
background: red
}
.navbar_buttons_wrapper {
height: 100%;
width: 5%;
position: fixed;
top: 0;
right: 0
}
.navbar_buttons {
height: 100%;
display: flex;
align-items: center;
justify-content: center
}
.navbar_buttons ul {
height: auto;
list-style: none;
color: #fff;
padding: 0;
display: grid;
grid-template-columns: auto auto auto;
transform: rotate(-90deg)
}
.navbar_buttons ul li {
width: max-content;
margin-left: 30px;
margin-right: 30px;
font-size: 1.2rem;
text-transform: uppercase;
border-style: solid;
border-color: transparent;
transition: .7s;
padding: 7px
}
html body {
font-family: Roboto, sans-serif;
margin: 0;
border: 0;
padding: 0;
background: #2c2c2c
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
<link rel="stylesheet" type="text/css" href="./styles/main.css" />
<script type="text/javascript" src="./scripts/main-min.js"></script>
</head>
<body>
<div class="root">
<div class="pages">
<div class="page" id="projects"></div>
<div class="page" id="previousComms"></div>
<div class="page" id="aboutMe"></div>
</div>
<div class="navbar">
<div class="navbar_buttons_wrapper">
<div class="navbar_buttons">
<ul>
<li class="navbar_button" id="projectsButton">Portfolio</li>
<li class="navbar_button" id="previousCommsButton">Previous Commissioners</li>
<li class="navbar_button" id="aboutMeButton">About Me</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
I have a series of images I want to transition from 0 opacity to 1 opacity when they come into the view port. I have the viewport check part done and the adding classes, however I would like them to be on an interval, so once the first 3 images come into the view port they appear 1, 2, 3 every .5seconds or so. Instead of all 3 at the same time.
here's a JS fiddle of how it works currently
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
reveal[i].classList.add("fade");
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
https://jsfiddle.net/u04sy7jb/
I've modified your code to add a transition-delay of an additional .5 seconds for each element after the first one, in each "group" that is revealed as you scroll. I left comments in the JavaScript so you can understand the changes.
Let me know if you have any questions!
Live demo:
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
// start a new count each time user scrolls
count = 0;
for (var i = 0; i < reveal.length; i++) {
// also check here if the element has already been faded in
if (checkVisible(reveal[i]) && !reveal[i].classList.contains("fade")) {
// add .5 seconds to the transition for each
// additional element currently being revealed
reveal[i].style.transitionDelay = count * 500 + "ms";
reveal[i].classList.add("fade");
// increment count
count++;
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
.container {
width: 100%;
height: 1200px;
background-color: orange;
}
.reveal {
display: inline-block;
width: 32%;
margin: 0 auto;
height: 400px;
background-color: pink;
border: 1px solid black;
opacity: 0;
}
.fade {
opacity: 1;
transition: 1s;
}
<div class="container">
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
</div>
You could be able to stick your reveal[i].classList.add("fade"); inside of a setTimeout that executes as a function of your ith element so they show up how you're describing. Here is an example of adding short function to add the class and using it in a setTimeout to make this happen, although you could change it up to meet any additional needs.
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
addMyFadeClass(reveal[i], i)
}
}
}
};
function addMyFadeClass(element, i) {
setTimeout(function() {
element.classList.add("fade");
}, i * 500)
}
You can also use :nth-child CSS selectors without the need to change the JS:
.reveal:nth-child(3n+1).fade {
opacity: 1;
transition: 1s;
}
.reveal:nth-child(3n+2).fade {
opacity: 1;
transition: 1.5s;
}
.reveal:nth-child(3n).fade {
opacity: 1;
transition: 2s;
}
JSFiddle: https://jsfiddle.net/u04sy7jb/8/
Hi I'm still beginner at CSS, html and JS. I tried to do a transition ease-out for the property left, cuz I.m doing an animated galery for my future purposes. I tested it in the browser, the images where changing but the transition didn't happened.
Here is my "index.html":
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="galery">
<img class="galery_comp" src="img/leaf.jpg">
<img class="galery_comp" src="img/spital.jpg">
<img class="galery_comp" src="img/nature.jpg">
<img class="galery_comp" src="img/forest.jpg">
</div>
<br>
<button type="button" id="back"><-- Back</button>
<button type="button" id="next">Next --></button>
<script src="Galery.js"></script>
<script src="sketch.js"></script>
</body>
</html>
Here is my "style.css":
div.galery{
display: flex;
transition: left 0.4s ease-out; /* This is where i tried */
}
img{
width: 600;
height: 500;
display: none;
}
Here is my "Galery.js":
function Galery(){
this.imgs = document.getElementsByClassName('galery_comp');
this.currentImage = 0;
this.offSet = 0;
var hide = false;
this.sleep = function(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
this.init = function(){
this.imgs[0].style.display = "block"
}
this.next = function(){
this.currentImage++;
if (this.currentImage >= this.imgs.length)
{
this.currentImage = 0;
for (var i = 0; i < this.imgs.length; i++){
this.imgs[i].style.left = 0;
this.imgs[i].style.display = "none";
}
}
this.imgs[this.currentImage].style.display = "inline";
this.offSet=0;
}
this.slideNext = function(){
this.imgs[this.currentImage].style.left = -parseInt(window.getComputedStyle(this.imgs[0], null).width) - this.offSet;
this.imgs[this.currentImage].style.display = "none";
this.offSet = 10;
this.next();
}
this.slideBack = function(){
if (this.currentImage === 0){
this.currentImage = this.imgs.length;
for (var i = 0; i < this.imgs.length; i++){
this.imgs[i].style.left = -parseInt(window.getComputedStyle(this.imgs[0], null).width);
this.imgs[i].style.display = "none";
}
}
this.currentImage--;
this.imgs[this.currentImage].style.display = "inline";
this.imgs[this.currentImage].style.left = 0;
if (this.currentImage + 1 < this.imgs.length)
this.imgs[this.currentImage + 1].style.display = "none";
}
}
And finally here is my sketch.js:
var galery = new Galery();
galery.init();
document.getElementById('next').addEventListener("click", function(){
galery.slideNext();
});
document.getElementById('back').addEventListener("click", function(){
galery.slideBack();
});
Did i made something wrong? Or i should use another tehnique. If you want to test it you can use whatever images you want and how many you want(only keep the "galery_comp" class for the js)
Any answear apreciated!
You should add the transition to your img.
Your also setting (in your js) the display to none.
So you're basically removing the img before the transition can be seen. displayis also a non-transitionable attribute
Instead of display, try using opacity and setting it to either 0 or 1 (depending wether you want to show it or not)
then you could also add a transition for your opacity (maybe differently timed) and have a nice effect)
img{
width: 600;
height: 500;
opacity: 0;
transition: left 0.4s ease-out, opacity 0.3s ease-out;
}
Help! I've no idea what's going wrong here, I'm following along a tutorial video from Tuts+ The code is exact, yet the blue box is not animating to the left.
When I put an alert inside of the moveBox function, I see in the console the alert firing off the same message over and over again.
Here is my test link:
> Trying to animation a blue box left using Javascript <
Here is a screenshot from the video:
Here is my code:
(function() {
var speed = 10,
moveBox = function() {
var el = document.getElementById("box"),
i = 0,
left = el.offsetLeft,
moveBy = 3;
//console.log("moveBox executed " +(i+1)+ " times");
el.style.left = left + moveBy + "px";
if (left > 399) {
clearTimeout(timer);
}
};
var timer = setInterval(moveBox, speed);
}());
HTML:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>JavaScript 101 : Window Object</title>
<style>
#box {
position: abosolute;
height: 100px;
left: 50px;
top: 50px;
width: 100px;
background-color: Blue;
}
</style>
</head>
<body>
<div id="box"></div>
<script src="js/animation.js"></script>
You mispelled "absolute" in your positioning:
#box {
position: absolute; // Your mispelling here
height: 100px;
left: 50px;
top: 50px;
width: 100px;
background-color: Blue;
}
Once I fixed that, it worked fine.
A word of advice -- put a second condition in loops like this so that if the animation fails for some reason you don't end up in an infinite loop. For example, you might have done this:
(function() {
var maxTimes = 1000;
var loopTimes = 0;
var speed = 10,
moveBox = function() {
var el = document.getElementById("box"),
i = 0,
left = el.offsetLeft,
moveBy = 3;
//console.log("moveBox executed " +(i+1)+ " times");
el.style.left = left + moveBy + "px";
loopTimes += 1;
if (left > 399 || loopTimes > maxTimes) {
clearTimeout(timer);
}
};
var timer = setInterval(moveBox, speed);
}());