Blog

Simple JS carousel tutorial

Aug 22, 2022, 2:12 PM

Brazillian Furry tech wizard explains his javascript carousel source code in detail and makes a tutorial out of it.


tech


Before reading it further:

If you just want to see the source code check the github repo at the end of the article.

If you find something you've never seen before, search for it on websites like W3 Schools or Mozilla Docs


Here's what the final result will look like:

carouselfFinal


HTML

First let's begin by taking a look at our html:

<!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">
  <link rel="stylesheet" href="./css/styles.css">
  <title>epic</title>
  <script src="./js/carousel.js"></script>
</head>

<body>
  <h1>epic</h1>
  <article class="container">
    <section id="carousel">

      <a class="imagecontainer" href="">
        <img src="img/1.gif" alt="gif">
      </a>
      <a class="imagecontainer" href="">
        <img src="img/2.gif" alt="gif">
      </a>
      <a class="imagecontainer" href="">
        <img src="img/3.gif" alt="gif">
      </a>
      <a class="imagecontainer" href="">
        <img src="img/4.gif" alt="gif">
      </a>
      <a class="imagecontainer" href="">
        <img src="img/5.gif" alt="gif">
      </a>
      <a class="imagecontainer" href="">
        <img src="img/6.gif" alt="gif">
      </a>
    </section>

    <button id="btnright"></button>
    <button id="btnleft"></button>
	  
  </article>

</body>

</html>

Lest take a look at the components of the body one by one:

<article class="container"> Is just used to center the carousel and it's buttons in the page.

<section id="carousel"> Is the actual carousel and also where we will put all the images inside.

<a class="imagecontainer" href=""> Is a hyperlink tag that will contain the images, and it will allow you to use it's href attribute to redirect the user to another page after clicking the image for example.

<img src="img/6.gif" alt="gif"> Is just the image inside each container.

<button id="btnleft></button> Is the left button

<button id="btnright"></button> Is the right button

And that sums up the HTML (honestly it ins't like there is a lot to talk about anyway).


The CSS

Now let's take a look at the CSS:

@font-face {
    font-family: "Sauce Code Pro";
    src: url(../Sauce\ Code\ Pro\ Nerd\ Font\ Complete.ttf);
}


body {
    font-family: "Sauce Code Pro";
    text-align: center;
    margin: 0vw 10vw;
}

.container {
    overflow: hidden;
    border-radius: 20px;
    position: relative;
    height: fit-content;
}

button {
    font-family: "Sauce Code Pro" !important;
}

#carousel {
    background-color: #e9e9e960;
    max-height: 40vw;
	  max-height: 500px;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    position: relative;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;

    scrollbar-width: none;

}

#carousel::-webkit-scrollbar {
  display: none;
}

#btnleft {
    left: 0vw;
}

#btnright {
    right: 0vw;
}

#btnright,
#btnleft {
    font-family: "Sauce Code Pro";
    font-size: 1.6vw;
    color: #555555;
    z-index: 999;
    width: 3vw;
    border-style: none;
    position: absolute;
    top: 0;
    height: 100%;
    background-color: #d4d4d4a4;
}

#btnright:hover,
#btnleft:hover {
    color: #959595;
    background-color: #dededee4;
    cursor: pointer;
}

.imagecontainer {
    object-fit: cover;
    box-sizing: border-box;
    image-rendering: auto;
    height: 50vw;
    min-height: 50vw;
    min-width: 100%;
    margin: 0;
    padding: 0;
    scroll-snap-align: auto;
}

.imagecontainer>img {
    min-height: 50vw;
    object-fit: cover;
    object-position: 90% 90%;
    min-width: 80vw;
}

.imagecontainer:hover {
    filter: brightness(1.2);
    max-height: 105%;
}

Note:

For the sake of not keeping this too long i will not explain the css line by line, that said allow me to explain the css almost line by line.

The first thing we do is importing an icon font of our choice. The one i choose can be found in this carousel's github repository and also on the nerdfonts project webpage.

There are other better ways you might want to do this, like using something like the iconify api instead. So this is something you might want to change if you implement this on your personal project.

@font-face {
    font-family: "Sauce Code Pro";
    src: url(../Sauce\ Code\ Pro\ Nerd\ Font\ Complete.ttf);
}

On the .container i used position: relative; so later we can position the buttons on it's sides.

Now let's talk about the actual carrousel:

#carousel {
    background-color: #e9e9e960;
    min-height: 40vw;
    max-height: 500px;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    position: relative;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;

}

#carousel::-webkit-scrollbar {
  display: none;
}

So on the carousel we set: margins: 0; and paddings: 0; so it does not offset the images inside of it.

display:flex; so the images are displayed side by side.

overflow-x: auto; and overflow-y:hidden; so we can scroll them horizontally but not vertically.

scroll-behavior: smooth; and scroll-snap-type: x mandatory; so we have a smooth scrolling animation between the images and the images will snap horizontally if we scroll them on a touch screen.

scrollbar-width: none; and

#carousel::-webkit-scrollbar {
  display: none;
} 

so we hide the scrollbar.

On #btnright and #btnleft i used position: absolute , right: 0; and left: 0; to set their position.

On .imagecontainer i set object-fit: cover; so the images are cropped to fit the carousel, and scroll-snap-align: auto; to specify that this is the element that should snap when we scroll the carousel.

On the .imagecontainer>img i also set object-fit: cover;.

And that's about it.


The JS:

The js code is pretty simple and well commented so you'll probably understand it just by taking a look. Anyway i still wrote some paragraphs explaining it in case you miss something.

document.addEventListener("DOMContentLoaded", () => {

  //Define your variables here:
  const cid = '#carousel';                //carrousel id
  const imgclass = 'imagecontainer';      //images class
  const btnL = '#btnleft';                //Left button id
  const btnR = '#btnright';               //right button id

  const timer = 2000;                     //timer in ms for the carousel to autoswitch, leave zero for no autoswitch;
  const autoSwitchDir = 1;                //direction for the carrousel to move automatically

  setupCarousel(cid, imgclass, btnL, btnR, timer, autoSwitchDir);
})

/**
* This function will call the other functions, add event listener to the buttons and make te carrousel move if a timer is defined!
* @param {string} cid               // Carrousel id
* @param {string} imgclass          // class for the image containers
* @param {string} btnL              // id for Left Button
* @param {string} btnR              // id for Right Button
* @param {number} timer             // time in ms between each image transition 
* @param {number} autoSwitchDir     // 1 or 0 or -1, direction for the image to scroll automatically if a timer is setup.  
*/
function setupCarousel(cid, imgclass, btnL, btnR, timer, autoSwitchDir) {
  var carousel = document.querySelector(cid);
  var images = document.getElementsByClassName(imgclass);
  var bLeft = document.querySelector(btnL);
  var bRight = document.querySelector(btnR);

  forceStartPosition(carousel, 0);

  let interval = null;

  if (timer > 0) {
    interval = window.setInterval(move, timer, carousel, images, autoSwitchDir);
  }

  bRight.onclick = () => {
    if (interval) {
      clearInterval(interval);
    }
    move(carousel, images, 1);
    if (timer > 0) {
      interval = window.setInterval(move, timer, carousel, images, autoSwitchDir);
    }
  }
  bLeft.onclick = () => {
    if (interval) {
      clearInterval(interval);
    }
    move(carousel, images, -1);

    if (timer > 0) {
      interval = window.setInterval(move, timer, carousel, images, autoSwitchDir);
    }
  }
}


/**
 * This function is updates the position of the data-pos attribute and scrolls to the next image.
 * @param {object} carousel //the carousel 
 * @param {object} images //images that are children of the carrosel
 * @param {number} dir //the direction to move the image
 */
function move(carousel, images, dir) {

  var width = images[0].offsetWidth;
  var maxpos = width * images.length; //mutiply the imagewidth by the amount of images to get the total size of the carrosel


  var pos = parseInt(carousel.dataset.pos);
  var nextpos = pos + width * dir; //calculate next position

  if (nextpos < maxpos && nextpos >= 0) {
    //just move to the nextpos 
    pos = nextpos;
    carousel.dataset.pos = pos;
    carousel.scrollTo(pos, 0);

  } else if (nextpos < 0) {
    //wrap around to the maxpos 
    pos = (maxpos - width);
    carousel.dataset.pos = pos;
    carousel.scrollTo(pos, 0);

  } else if (nextpos >= maxpos) {
    // go back to start position
    pos = 0;
    carousel.dataset.pos = pos;
    carousel.scrollTo(pos, 0);
  }
}

/*
* This function forces the carousel start position to be 0 and sets the data-pos attribute for the first time to 0 aswell.
* @param {object} carousel // the carousel object
*/
function forceStartPosition(carousel) {
  carousel.scrollTo(0, 0);
  carousel.dataset.pos = 0;
}

First we wait for the page to be fully loaded by using the document.addEventListener("DOMContentLoaded", () => { }) function, then once it's loaded, we setup some variables for the carousel and call setupCarousel() with them.

Then setupCarousel() will do the following:

  • Force the scrollbar position to be 0 and create a data-pos attribute on the carousel html element for storing the position.
  • Create an interval for automatically switching images if we passed an timer bigger than 0.
  • Add click event listeners to both buttons so once we click them we clear the interval, move the carousel and start another interval. (we reset the interval so the images don't scroll on a row if the user clicks next to the interval )

Note on html data-attributes:


Basically you can use an html element to store a variable and read it later by defining and data-attribute, we're using it because we need the position to be an universal value used by all function calls. More on data-attributes here: Mozilla docs - How to use data attributes, W3 Schools - html data-* attribute.

But how do we actually move() the images ?


Well here's how:

  • Get the image width. (all images have the same width)
  • Galculate the max position of the scrollbar ( image width * number of images)
  • Get our scroll position from the carousel's data-pos attribute.
  • Calculate the next position ( current position + ( image width * direction)) , note that direction is or 1 or -1 here.
    • If our next position is between 0 and max position we move one image to the side and update the carousel data-pos attribute.
    • If our next position is less than 0 then we move to the last image of the carousel (maxpos - width) and update the carousel data-pos attribute.
    • If our next position is bigger or equal to our max pos then we scroll back to the start of the carousel ( 0 ) and update the carousel data-pos attribute.

Conclusion

Now that you understand how it works, feel free to copy the source code from my github repo and use it in your projects as you see fit.

github Link!

Well that's about it. I made this to help people who are starting get a better understanding of js, html and css.

Hope it helps ~ Niii.

ScreenShare your Android device to PC with scrcpy!

Sep 30, 2022, 10:10 PM

ScreenShare and Control your Android devices on your PC over usb and TCP/IP with scrcpy and guiscrcpy!


tech

okay but what is scrcpy?

Scrcpy (pronounced "screen copy") is a command line utility that connects to your android device via USB or TCP/IP and allows you to share it's screen to your computer and control it remotely.

Here are some of it's main features (directly taken from their github):

  • recording
  • mirroring with Android device screen off
  • copy-paste in both directions
  • configurable quality
  • Android device as a webcam (V4L2) (Linux-only)
  • physical keyboard simulation (HID)
  • physical mouse simulation (HID)
  • OTG mode

How 2 use itt!

First you will need to enable the developer options on your android device.
After that you will have to plug it up on your computer with a usb cable and enable USB Tethering in your device's config's.

Then you run scrcpy on your terminal with: scrcpy

And after that a pop up asking for permission will appear on your android device. Once you accept it, a new window with the device's screen mirrored will appear on your desktop.

Other commands i like: scrcpy -n The -n option will disable remote input to your device. scrcpy -e The -e option will use the Wireless connection instead of the USB one. (Beware that you'll have to accept another permission pop up on your device.)

image

This is streaming my tablet's screen with the thumbnail art for this blogg lol.

Remember you can always use the --help option or check their github for a more in depth explanation of how it works!

guiscrcpy

There's also a gui front end for scrcpy called guiscrcpy! It is pretty straightfoward to use and configure!
Here's what it looks like:

image

Conclusion

Welp this is a very useful tool, i use it to stream the screen of my tablet to obs so i can stream/record art stuffs.

Hope it helps ya!

Their Github

Don't forget to check out their githubs:

scrcpy

guiscrcpy

Samsung Galaxy Tab S7 Art Review

Sep 19, 2022, 4:04 AM

This is a brief art focused review of the Samsumg Galaxy Tab S7


review

Tablet specs and overall performance

I just ain't going over them, this review is art focused, if you want ot check that just google a review that focueses on that instead.

image

Is the tablet good for art?

Yes, here are some arts i did using it

Is there any Delay on the pen?

No, but if you use run some application that is really heavy it will start to have a bit of delay, but this is normal to any computer, if you use all of it's memory and resources it's gonna slow down. I noticed it only in the older android krita version that was very buggy to me, and on drawings with ridiculous amount of layers with different blend modes, which is , again, expected, even a computer would lag with that stuff.

How does the pen feel?

It feels pretty much like a wacom tablet, probably because samsung liscenced wacom's technology and is using it in their products.

Cons:

The pen nib will break from time to time , so i recommend buying a few replacement nibs , they're pretty cheap. Also when the tip breaks half of the nib might still be inside the pen, so you'll have to pick a needle, heat it up with fire and then use it to melt a bit of the nib inside the pen and then pull it out. It honestly isn't that hard, for me it takes about 5 minutes to grab all the stuff and do it.

Here's a video of a guy trying to do it, missing a few times and then finally removing the half of the nib that was stuck inside the pen, i would make a video of me doing it but my pen is fine rn so i don't have a reason to do it.

Would i recommend the tablet?

Absolutely.

Overall experience:

8.75 / 10 , pen could be better, android art apps can still evolve a bit further, besides that, an absolute breeze to use. really good.

Also i'm pretty sure that there are alternative pens that are pretty good and you can buy online if you don't like this problem with the pen nib.

yeah that's it this was the revveww hope it helps.