Scroll up or down, this gallery works both ways

in Programming & Dev2 years ago (edited)

I'm nowhere near ready to actually have a job as a FullStack Developer, but I'm slowly but steadily reaching that status; in the meantime, all I can do is grind.

Grinding, grinding, grinding. When we are talking code, it all comes down to grinding. The more you grind, practice your skills, find out about new tweaks, practice what you should already know by heart, and just putting your code to work... the more you will learn.

So that's what I am doing. I am already pretty efficient with my HTML and CSS code, I still need a lot of practice and a hell lot to learn regarding JavaScript - and don't worry, I've been taking my lessons religiously even though I haven't posted about JavaScript for something like two weeks; but the point is, these little projects are mainly about HTML and CSS and grinding my skills.

This is tenth post already about little projects based off online ideas and my plan is to join all of these ideas once I am ready and create my own CV website of my own where I'll showcase all that I've learned in a sort of interactive website. Heads up, I'm getting there, slowly but steady, more slowly than steady to be honest but what the hell, slow and steady wins the race.

In the meantime, I will leave you with one project Idea based off on Brad Traversy's paid course on Udemy. Credit at the bottom and links btw.

Note: The code is based off someone else's ideas, all the comments and doc are mine as this is supposed to be a teaching kind of post, and even though the main concept is not mine, all the code has been tweaked and modified to align with my own ideas.

Double Scrolling Gallery

I am going to build a double vertical slider, so one side goes up, the other goes down, but both sides always make sense. It won't be responsive to the size of the window - this makes it specifically for desktop windows and not for smartphone versions of the website - but still, it is pretty cool.

HTML Code

  <body>
    <div class="slider-container">

The first slide text matches the last image on the right side, so just make sure you add the text on the last spot of the left side, and on the first spot of the right side.

  <div class="left-slide">
    <div style="background-color: rgb(20, 106, 36)">
      <h1>Xcambo Ruins</h1>
      <p>The Celestial Crocodile archaeological site in Merida, Mexico</p>
    </div>
    <div style="background-color: rgb(121, 131, 15)">
      <h1>HiveFest Crew</h1>
      <p>
        A bunch of Hivers in Krakow, Poland enjoying what is probably the
        best HiveFest so far, the third edition
      </p>
    </div>
    <div style="background-color: rgb(52, 68, 175)">
      <h1>Street Art</h1>
      <p>
        One of the topics that appears the most in Anomadsoul's blog posts:
        Street art from around the world.
      </p>
    </div>
    <div style="background-color: rgb(116, 21, 145)">
      <h1>JavaScript Learning</h1>
      <p>
        The most common topic among those that Anomadsoul writes on Hive
      </p>
    </div>
  </div>
  <div class="right-slide">
    <div
      style="
        background-image: url('https://images.ecency.com/p/PB8ro82ZpZP35bVGjGoE93K3E4U5KX8KtMBJ2rhsbxYNExo6WDoguJobbdi6R4HbuVVSdnwwCTq5xFNdNvhQuxEhUEA61YyCfrYL47mCCAsqwh6v.webp?format=webp&mode=fit');
      "
    ></div>

    <div
      style="
        background-image: url('https://images.ecency.com/p/3jpR3paJ37V8XPrHkfZdMt57jY6pRt6zEt5iRJV9pRsB6uTUkGiX46yrvJyiaDZ2fKujXnnpHQRvb4X6rkV1HxpQeuKdTMwrvriyD7Liq1yPzfvsqoh6j3k9j3ujMbURY7nBp.webp?format=webp&mode=fit');
      "
    ></div>

    <div
      style="
        background-image: url('https://images.ecency.com/p/2gsjgna1uruvGBHDnRaj2z6FsL6XEQR3pnqa26GnVHqkZrMb8EnBRrsZod1uVJCy4SyKW6MQn32X83M12qTiXPtVCxhhmGr1wssVfny1R6JirafTwc.webp?format=webp&mode=fit');
      "
    ></div>

    <div
      style="
        background-image: url('https://images.ecency.com/p/3W72119s5BjW4PvRk9nXBzqrPWMsMTjNrXDPFFf11w2dDHirp2QwyCuM5Hoxp2bHDnAqBrTezagkqPoyywGG9ZHsLNLqt4JPr6SdnHPTxmnzMfjA271RSW.webp?format=webp&mode=fit');
      "
    ></div>
  </div>
  <div class="action-buttons">
    <button class="down-button">
      <i class="fas fa-arrow-down"></i>
    </button>
    <button class="up-button">
      <i class="fas fa-arrow-up"></i>
    </button>
  </div>
</div>

<script src="script.js"></script>
````

So far, it is getting some shape, not even close to ready but at least you can see where I want to get.

image.png

CSS Code

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Open Sans", sans-serif;
  height: 100vh;
}

I position the slider container as relative because everything inside this container will be positioned absolute.

.slider-container {
  position: relative;
  overflow: hidden;
  width: 100vw;
  height: 100vh;
}

.left-slide {
  height: 100%;
  width: 30%;
  position: absolute;
  top: 0;
  left: 0;
}

I want to target the immediate div on the left-slide so:

.left-slide > div {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #fff;
}

Above I specified a height and a width, this means that the immediate div will take up 100% of the total height, but also the 100% of the 30% of the total width.

.left-slide h1 {
  font-size: 40px;
  margin-bottom: 10px;
  /* Adding this negative margin pulls the text up */
  margin-top: -50px;
}

.left-slide p {
  font-size: 16px;
  margin-left: 20px;
  margin-top: 100px;
  margin-bottom: -100px;
  transition: transform 0.5s ease-in-out;
}

.right-slide {
  height: 100%;
  position: absolute;
  top: 0;
  left: 30%;
  width: 70%;
  transition: transform 0.5s ease-in-out;
}

.right-slide > div {
  background-repeat: no-repeat;
  /* I want to show the whole image: */
  background-size: cover;
  /* First center is the X and second is the Y axis */
  background-position: center center;
  height: 100%;
  width: 100%;
}

This is not how I intend the images to show, if you check the HTML code you'll see that I arranged them in a counter order, but I will fix that on the JS code.

image.png

button {
  background-color: #fff;
  border: none;
  color: #aaa;
  cursor: pointer;
  font-size: 16px;
  padding: 15px;
}

button:hover {
  color: #222;
}

button:focus {
  outline: none;
}

.slider-container .action-buttons button {
  position: absolute;
  left: 30%;
  top: 50%;
  /* I make sure they are always on top */
  z-index: 100;
}

I want to move the down button to the left. Using 100% moves an element over the X axis to the right a distance equal to its size. Using a negative percentage moves it to the left.

.slider-container .action-buttons .down-button {
  transform: translateX(-100%);
  /* This will turn circular the left corners of the button: */
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
}

.slider-container .action-buttons .up-button {
  /* I want to move up the *up* button. I use the Y axis but the principle is the same as the one I used above. */
  transform: translateY(-100%);
  /* This will turn circular the left corners of the button: */
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
}

Now you can actually see what I want to accomplish, and all I need is a little bit of JS to do so.

gif1.gif

JavaScript Code

const sliderContainer = document.querySelector(".slider-container");
const slideRight = document.querySelector(".right-slide");
const slideLeft = document.querySelector(".left-slide");
const upButton = document.querySelector(".up-button");
const downButton = document.querySelector(".down-button");
const slidesLength = slideRight.querySelectorAll("div").length;

I want an active slide index, so we need to know which index is in view.

let activeSlideIndex = 0;

I set it to 0 now, but we'll modifiy it later on this code

slideLeft.style.top = `-${(slidesLength - 1) * 100}vh `;

I do it negative because the slides are going to go up

Remember that node lists behave like arrays, that's why we use the length - 1 to get the last slide.

upButton.addEventListener("click", () => changeSlide("up"));
downButton.addEventListener("click", () => changeSlide("down"));

const changeSlide = (direction) => {
  const sliderHeight = sliderContainer.clientHeight;
  if (direction === "up") {
    activeSlideIndex++;
    if (activeSlideIndex > slidesLength - 1) {
      activeSlideIndex = 0;
    }
  } else if (direction === "down") {
    activeSlideIndex--;
    if (activeSlideIndex < 0) {
      activeSlideIndex = slidesLength - 1;
    }
  }

  slideRight.style.transform = `translateY(-${
    activeSlideIndex * sliderHeight
  }px`;

  slideLeft.style.transform = `translateY(${activeSlideIndex * sliderHeight}px`;
};

gif2.gif

And voila, if you check the 10 second GIF, you'll see the mission has been accomplished!!




These projects are based on a CSS, HTML and JS paid course I got on Udemy by Brad Traversy. I made my own changes and tweaks but the template so to speak, is his idea and I do not claim them to be my own. If you are looking to practice CSS and JavaScript, his courses are the way to go, check them out on Udemy.

Sort:  

You have simply raised my interest in going back to coding seriously. Thanks for this motivation sir.

That's great man! What language do you write in? Perhaps you can post about programming, we definitely need a more active coder scene on Hive.

Looking very slick! Nice work 💪

Thanks amigo! Doing my best

Yay! 🤗
Your content has been boosted with Ecency Points, by @anomadsoul.
Use Ecency daily to boost your growth on platform!

Support Ecency
Vote for new Proposal
Delegate HP and earn more

All of a sudden I now find codding attractive again after reading this post months without opening a code editor on my PC. I have to rediscover the love I once have for it.
Thanks for this post.

Oh damn, hopefully you get back to it man! What were you writing before you stopped months ago?

La práctica hace al maestro! Mientras seas disciplinado y persistas, pronto lo lograrás como todo un experto!

Muchas gracias Gaby! Esperemos que la practica de frutos pronto!