Home > Back-end >  Scale current item to 1
Scale current item to 1

Time:05-15

I wonder how to scale the current index from 1 to 0.8 when swiping to the next item. I've been building a carousel on how to make the centered item from 1 to 0.8 when the user swipes to the previous item or next item

When the user swipes into the next item the current item should slowly become from a 1 to 0.8 scaleY when it's not on the center

Only one item should have a 1 scaleY and centered item should scaleY from 1 to 0.8 every touchmove not only on touchend event

const MAIN_CONTAINER = document.querySelector('.main-container');
const CONTAINER_FLEX = document.getElementById('container-flex');

if (window.screen.width < 800) {
  MAIN_CONTAINER.style.width = `${window.screen.width}px`;
}

// Get the position when clicking the element
let touchstartX = 0;
let touchstartY = 0;

// Get the position when moving the element
let touchMoveX = 0;
let touchMoveY = 0;

let previous_move = 0;

// Get the position when leaving the element
let touchendX = 0;
let touchendY = 0;

// Swipe Detection

// Default is 1
let speed_of_swipe = 0.5;

let previous_translate_item = -305;
let current_translate = -305;
let current_index = 1;

CONTAINER_FLEX.style.transform = `translate3d(-305px, 0, 0)`;

CONTAINER_FLEX.addEventListener('touchstart', (event) => {
  touchstartX = event.touches[0].pageX;
  touchstartY = event.touches[0].pageY;

  previous_move = touchstartX;
});

CONTAINER_FLEX.addEventListener('touchmove', (event) => {
  touchMoveX = event.touches[0].pageX;
  touchMoveY = event.touches[0].pageY;

  current_translate =
    previous_translate_item   (touchMoveX - touchstartX) * speed_of_swipe;

  // if (current_index === 0 && current_translate > 20) current_translate = 20;
  // if (current_index === 2 && current_translate < -620) current_translate = -620;

  CONTAINER_FLEX.style.transition =
    'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
  CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
});

CONTAINER_FLEX.addEventListener('touchend', (event) => {
  touchendX = event.changedTouches[0].pageX;
  touchendY = event.changedTouches[0].pageY;

  let val_converter = (val) =>
    -Math.sign(val) * Math.floor((Math.abs(val) - 40) / 300   1);

  let move = current_translate - previous_translate_item;

  current_index  = val_converter(move);

  // if (move < -345) current_index  = 1;
  // if (move < -40) current_index  = 1;
  // if (move > 40) current_index -= 1;
  // if (move > 345) current_index -= 1;

  // including the margin
  current_translate = current_index * -305;
  previous_translate_item = current_translate;

  CONTAINER_FLEX.style.transition =
    'transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1)';
  CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;

  if (current_index > 3) {
    CONTAINER_FLEX.style.pointerEvents = 'none';
    current_index = 1;

    setTimeout(() => {
      current_translate = current_index * -305;
      previous_translate_item = current_translate;

      CONTAINER_FLEX.style.transition =
        'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
      CONTAINER_FLEX.style.pointerEvents = 'auto';
      CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
    }, 400);
  }

  if (current_index <= 0) {
    CONTAINER_FLEX.style.pointerEvents = 'none';
    current_index = 3;

    setTimeout(() => {
      current_translate = current_index * -305;
      previous_translate_item = current_translate;

      CONTAINER_FLEX.style.transition =
        'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
      CONTAINER_FLEX.style.pointerEvents = 'auto';
      CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
    }, 400);
  }

  console.log(current_index);
});

//

window.addEventListener('resize', (event) => {
  if (window.screen.width < 800) {
    MAIN_CONTAINER.style.width = `${window.screen.width}px`;
  }
});
*,
 ::before,
 ::after {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
  font-family: Arial, Helvetica, sans-serif;
  line-height: 1.5;
  background-color: #131b24;
}

.main-container {
  padding: 30px 0;
  height: 300px;
  width: 910px;
  border-top: 1px solid #444;
  border-bottom: 1px solid #444;
  overflow: hidden;
  background-color: white;
}

.container-flex {
  height: 100%;
  display: flex;
  column-gap: 5px;
  transition: transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1);
}

.item {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  min-width: 300px;
  max-width: 300px;
  transform: scaleY(0.8);
}

.item h1 {
  font-size: 40px;
  color: white;
}


/* ITEMS */

.item-1 {
  background-color: #2c3e50;
}

.item-2 {
  background-color: #3498db;
}

.item-3 {
  background-color: #1abc9c;
}
<div >
  <div  id="container-flex">
    <div >
      <h1>2</h1>
    </div>
    <div >
      <h1>3</h1>
    </div>
    <div >
      <h1>1</h1>
    </div>
    <div >
      <h1>2</h1>
    </div>
    <div >
      <h1>3</h1>
    </div>
    <div >
      <h1>1</h1>
    </div>
    <div >
      <h1>2</h1>
    </div>
  </div>
</div>

Carousel for mobile screens

CodePudding user response:

i add a scaleUp function to your js that called on CIRCLE_ITEMS.onclick and CONTAINER_FLEX.ontouchend . and by calling it , a scale-up class is added to the items.

function scaleUp (current_index){
  document.querySelectorAll('.item').forEach(item => {
     item.classList.remove('scale-up') 
  })
  document.querySelectorAll(`.item-${current_index}`).forEach(item => {
    item.classList.add('scale-up') 
 })
}

.scale-up{
  transform: scale(1)
}

and you can improve the code ... :)

const MAIN_CONTAINER = document.querySelector('.main-container');
const CONTAINER_FLEX = document.getElementById('container-flex');
const CIRCLE_ITEMS = document.querySelectorAll('.circle-holder span');

if (window.screen.width < 800) {
  MAIN_CONTAINER.style.width = `${window.screen.width}px`;
}

// Get the position when clicking the element
let touchstartX = 0;
let touchstartY = 0;

// Get the position when moving the element
let touchMoveX = 0;
let touchMoveY = 0;

let previous_move = 0;

// Get the position when leaving the element
let touchendX = 0;
let touchendY = 0;

// Swipe Detection

// Default is 1
let speed_of_swipe = 0.5;

let previous_translate_item = -305;
let current_translate = -305;
let current_index = 1;

CONTAINER_FLEX.style.transform = `translate3d(-305px, 0, 0)`;

CONTAINER_FLEX.addEventListener('touchstart', (event) => {
  touchstartX = event.touches[0].pageX;
  touchstartY = event.touches[0].pageY;

  previous_move = touchstartX;
});

CONTAINER_FLEX.addEventListener('touchmove', (event) => {
  touchMoveX = event.touches[0].pageX;
  touchMoveY = event.touches[0].pageY;

  current_translate =
    previous_translate_item   (touchMoveX - touchstartX) * speed_of_swipe;

  // if (current_index === 0 && current_translate > 20) current_translate = 20;
  // if (current_index === 2 && current_translate < -620) current_translate = -620;

  CONTAINER_FLEX.style.transition =
    'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
  CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
});

CONTAINER_FLEX.addEventListener('touchend', (event) => {
  touchendX = event.changedTouches[0].pageX;
  touchendY = event.changedTouches[0].pageY;

  let val_converter = (val) =>
    -Math.sign(val) * Math.floor((Math.abs(val) - 40) / 300   1);

  let move = current_translate - previous_translate_item;

  current_index  = val_converter(move);

  // if (move < -345) current_index  = 1;
  // if (move < -40) current_index  = 1;
  // if (move > 40) current_index -= 1;
  // if (move > 345) current_index -= 1;

  // including the margin
  current_translate = current_index * -305;
  previous_translate_item = current_translate;

  CONTAINER_FLEX.style.transition =
    'transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1)';
  CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;

  if (current_index > CIRCLE_ITEMS.length) {
    CONTAINER_FLEX.style.pointerEvents = 'none';
    current_index = 1;

    setTimeout(() => {
      current_translate = current_index * -305;
      previous_translate_item = current_translate;

      CONTAINER_FLEX.style.transition =
        'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
      CONTAINER_FLEX.style.pointerEvents = 'auto';
      CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
    }, 400);
  }

  if (current_index <= 0) {
    CONTAINER_FLEX.style.pointerEvents = 'none';
    current_index = CIRCLE_ITEMS.length;

    setTimeout(() => {
      current_translate = current_index * -305;
      previous_translate_item = current_translate;

      CONTAINER_FLEX.style.transition =
        'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
      CONTAINER_FLEX.style.pointerEvents = 'auto';
      CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
    }, 400);
  }

  //console.log(current_index);

  onRemoveCarouselActiveItem();
  CIRCLE_ITEMS[current_index - 1].classList.add('active');
  
   scaleUp (current_index)
  
});

//

CIRCLE_ITEMS.forEach((item) => {
  item.addEventListener('click', (e) => {
    let data_item = e.target.dataset.carouselCount * 1;

    current_index = data_item;

    current_translate = current_index * -305; 
    previous_translate_item = current_translate;

    
    onRemoveCarouselActiveItem();

    e.target.classList.add('active');
    
    scaleUp (current_index)
    
    CONTAINER_FLEX.style.transition =
      'transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1)';
    CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
  });
});

function onRemoveCarouselActiveItem() {
  let active_item = document.querySelector('.circle-holder .active');
  if (active_item)active_item.classList.remove('active')
  
}

window.addEventListener('resize', (event) => {
  if (window.screen.width < 800) {
    MAIN_CONTAINER.style.width = `${window.screen.width}px`;
  }
});

function scaleUp (current_index){
  document.querySelectorAll('.item').forEach(item => {
    item.classList.remove('scale-up') 
  })
  document.querySelectorAll(`.item-${current_index}`).forEach(item => {
    item.classList.add('scale-up') 
  })
}
*,
::before,
::after {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
  font-family: Arial, Helvetica, sans-serif;
  line-height: 1.5;
  background-color: #131b24;
}

.main-container {
  padding: 30px 0;
  height: 300px;
  width: 910px;
  border-top: 1px solid #444;
  border-bottom: 1px solid #444;
  overflow: hidden;
  background-color: white;
}

.container-flex {
  height: 100%;
  display: flex;
  column-gap: 5px;
  transition: transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1);
}

.item {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  min-width: 300px;
  max-width: 300px;
  transform: scaleY(0.8);
  transition: ease .3s transform;
}

.item h1 {
  font-size: 40px;
  color: white;
}

/* ITEMS */

.item-1 {
  background-color: #2c3e50;
}

.item-2 {
  background-color: #3498db;
}

.item-3 {
  background-color: #1abc9c;
}

/* ============================================================== */

.circle-holder {
  display: flex;
  align-items: center;
  margin-top: 30px;
}

.circle-holder span {
  height: 30px;
  width: 30px;
  border: 1px solid #444;
  border-radius: 100%;
  margin: 0 20px;
}

.circle-holder span.active {
  background-color: #2c3e50;
}

.scale-up{
  transform: scale(1)
}
<!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>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div >
      <div  id="container-flex">
        <div >
          <h1>2</h1>
        </div>
        <div >
          <h1>3</h1>
        </div>
        <div >
          <h1>1</h1>
        </div>
        <div >
          <h1>2</h1>
        </div>
        <div >
          <h1>3</h1>
        </div>
        <div >
          <h1>1</h1>
        </div>
        <div >
          <h1>2</h1>
        </div>
      </div>
    </div>

    <div >
      <span  data-carousel-count="1"></span>
      <span  data-carousel-count="2"></span>
      <span  data-carousel-count="3"></span>
    </div>

    <script src="index.js"></script>
  </body>
</html>

CodePudding user response:

Is that what you need ? Test it on screen because of px calculations, SO snippet is not behave correct.


const MAIN_CONTAINER = document.querySelector('.main-container');
const CONTAINER_FLEX = document.getElementById('container-flex');
const CIRCLE_ITEMS = document.querySelectorAll('.circle-holder span');

if (window.screen.width < 800) {
  MAIN_CONTAINER.style.width = `${window.screen.width}px`;
}

// Get the position when clicking the element
let touchstartX = 0;
let touchstartY = 0;

// Get the position when moving the element
let touchMoveX = 0;
let touchMoveY = 0;

let previous_move = 0;

// Get the position when leaving the element
let touchendX = 0;
let touchendY = 0;

// Swipe Detection

// Default is 1
let speed_of_swipe = 0.5;

let previous_translate_item = -305;
let current_translate = -305;
let current_index = 1;
let old_index = 1;


CONTAINER_FLEX.style.transform = `translate3d(-305px, 0, 0)`;


CONTAINER_FLEX.addEventListener('transitionstart', () =>{
  FindAndChangeMiddleItem(1,2);
},{once: true})



CONTAINER_FLEX.addEventListener('touchstart', (event) => {
  touchstartX = event.touches[0].pageX;
  touchstartY = event.touches[0].pageY;

  previous_move = touchstartX;
});

CONTAINER_FLEX.addEventListener('touchmove', (event) => {
  touchMoveX = event.touches[0].pageX;
  touchMoveY = event.touches[0].pageY;

  current_translate =
    previous_translate_item   (touchMoveX - touchstartX) * speed_of_swipe;

  CONTAINER_FLEX.style.transition =
    'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
  CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
});

CONTAINER_FLEX.addEventListener('touchend', (event) => {
  touchendX = event.changedTouches[0].pageX;
  touchendY = event.changedTouches[0].pageY;

  let val_converter = (val) =>
    -Math.sign(val) * Math.floor((Math.abs(val) - 40) / 300   1);

  let move = current_translate - previous_translate_item;

  current_index  = val_converter(move);

  // if (move < -345) current_index  = 1;
  // if (move < -40) current_index  = 1;
  // if (move > 40) current_index -= 1;
  // if (move > 345) current_index -= 1;

  // including the margin
  current_translate = current_index * -305;
  previous_translate_item = current_translate;

  CONTAINER_FLEX.style.transition =
    'transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1)';
  CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;

  if (current_index > CIRCLE_ITEMS.length) {
    CONTAINER_FLEX.style.pointerEvents = 'none';
    current_index = 1;

    setTimeout(() => {
      current_translate = current_index * -305;
      previous_translate_item = current_translate;

      CONTAINER_FLEX.style.transition =
        'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
      CONTAINER_FLEX.style.pointerEvents = 'auto';
      CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
    }, 400);
  }

  if (current_index <= 0) {
    CONTAINER_FLEX.style.pointerEvents = 'none';
    current_index = CIRCLE_ITEMS.length;

    setTimeout(() => {
      current_translate = current_index * -305;
      previous_translate_item = current_translate;

      CONTAINER_FLEX.style.transition =
        'transform 0ms cubic-bezier(0.165, 0.84, 0.44, 1)';
      CONTAINER_FLEX.style.pointerEvents = 'auto';
      CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;
    }, 400);
  }

  
  onRemoveCarouselActiveItem();
  CIRCLE_ITEMS[current_index - 1].classList.add('active');
});


CIRCLE_ITEMS.forEach((item) => {
  item.addEventListener('click', (e) => {

    
    let data_item = e.target.dataset.carouselCount * 1;

    current_index = data_item;
    current_translate = current_index * -305;
    previous_translate_item = current_translate;

    onRemoveCarouselActiveItem();

    e.target.classList.add('active');

    CONTAINER_FLEX.style.transition =
      'transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1)';
    CONTAINER_FLEX.style.transform = `translate3d(${current_translate}px, 0, 0)`;

        FindAndChangeMiddleItem(old_index, current_index);
        old_index = current_index;
        
  });
});




const items = document.querySelectorAll('.item');
let middleItemBeforeChange;
let middleItemAfterChange;
let change_index;

function FindAndChangeMiddleItem(old_index, current_index){
        let itemArray = document.elementsFromPoint(window.innerWidth / 2, window.innerHeight / 2); 

        change_index = current_index - old_index;

        for (let i = 0; i < itemArray.length; i  ){
            if (itemArray[i].classList.contains('item')){
              middleItemBeforeChange = itemArray[i];
            }
        }

        for (let i = 0; i < items.length; i  ){
          if (items[i] === middleItemBeforeChange){
            if (change_index < 0 && i   change_index < 0){
              return;
            }
            else if (change_index > 0 && i   change_index > items.length){
              return;
            }
            else{
              middleItemAfterChange = items[i   change_index];
            }
          }
        }
    
        items.forEach((item) => {
            if (item != middleItemAfterChange){
                if(item.classList.contains('item-big')){
                    item.classList.remove('item-big');
                }
                item.classList.add('item-small');
            }
            else{
                if(item.classList.contains('item-small')){
                    item.classList.remove('item-small');
                }
                item.classList.add('item-big');
            }   
        })
}

function onRemoveCarouselActiveItem() {
  let active_item = document.querySelector('.circle-holder .active');
  if (active_item) active_item.classList.remove('active');
}

window.addEventListener('resize', (event) => {
  if (window.screen.width < 800) {
    MAIN_CONTAINER.style.width = `${window.screen.width}px`;
  }
});
/* Remove default margin */
body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
  margin: 0;
}



input,
button,
textarea,
select {
  font: inherit;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}


/* body {
  min-height: 100vh;
  margin: 0;
  background-color: bisque;
  display: grid;
  place-content: center;
} */



body {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
  font-family: Arial, Helvetica, sans-serif;
  line-height: 1.5;
  background-color: #131b24;
}

.main-container {
  padding: 30px 0;
  height: 300px;
  width: 910px;
  border-top: 1px solid #444;
  border-bottom: 1px solid #444;
  overflow: hidden;
  background-color: white;
}

.container-flex {
  height: 100%;
  display: flex;
  column-gap: 5px;
  transition: transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1);
}

.item {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  min-width: 300px;
  max-width: 300px;
  transition: 400ms all ease;
}

.item h1 {
  font-size: 40px;
  color: white;
}

/* ITEMS */

.item-1 {
  background-color: #2c3e50;
}

.item-2 {
  background-color: #3498db;
}

.item-3 {
  background-color: #1abc9c;
}

.circle-holder {
  display: flex;
  align-items: center;
  margin-top: 30px;
}

.circle-holder span {
  height: 30px;
  width: 30px;
  border: 1px solid #444;
  border-radius: 100%;
  margin: 0 20px;
}

.circle-holder span.active {
  background-color: #2c3e50;
}


.item-small{
  transform: scaleY(0.8);
}
.item-big{
  transform: scaleY(1);
}
 <div >
      <div  id="container-flex">
        <div >
          <h1>2</h1>
        </div>
        <div >
          <h1>3</h1>
        </div>
        <div >
          <h1>1</h1>
        </div>
        <div >
          <h1>2</h1>
        </div>
        <div >
          <h1>3</h1>
        </div>
        <div >
          <h1>1</h1>
        </div>
        <div >
          <h1>2</h1>
        </div>
      </div>
    </div>

    <div >
      <span  data-carousel-count="1"></span>
      <span  data-carousel-count="2"></span>
      <span  data-carousel-count="3"></span>
    </div>

  • Related