"On click" interaction in Wix Studio

Question:
[How to have an arrow icon continuously scroll a container on click?]

Product:
[Wix Studio Editor]

What are you trying to achieve:
[I have my first website build where i added and arrow icon (left and right) and 3 containers in a horizontal stack below the arrow icons.

I am trying to create an interaction where as the user continues to click the forward arrow, the stack will scroll, revealing each container till the end and vice versa for the left arrow.

Right now I have the click interaction on the arrows connected to the stack, but I only get one click out of them. If I keep clicking the arrow icons nothing happens further after the first “move” animation is completed. How do I make the behavior that on each arrow click, it moves the elements a certain pixel forward each time till it reaches the end.]

What have you already tried:
[Share resources, forum topics, articles, or tutorials you’ve already used to try and answer your question.]

Additional information:
[Include any other pertinent details or information that might be helpful for people to know when trying to answer your question.]

I would think Velo is needed for this.

Oh wow…i thought it would be something simple. Thanks a lot for the response.

Where would i begin to learn velo? i have no idea on how to code and am just trying to learn the basics on wix studio. Do you think there is any other possible alternative to doing this? or could you point me in the right direction to learn velo?

Instead of trying to generate it with velo-code —> what will not be that simple i think (possible=yes), but not simple.

Instead i would recommend to use a CUSTOM-ELEMENT or a HTML-Component and generate your wished functioality by your own with pure JS, or pure CSS, or CSS+JS+HTML.

But if you do not know how to code in JS → then you have a little problem.

What are you trying to achieve?
a) slide-show?
b) caroussel?
c) something else?

What are you trying to show?
a) IMAGES ?
b) VIDEOS ?
c) something else?

My understanding of your —> SETUP:

  1. You have 3-boxes/containers on your page (question: simple boxes, or msb’s, or boxes inside repeater, somekind of another container)??? By the way → MSB = MULTISTATE-BOX.

So as you can see, the whole things gets more detailed but also more complicated.
Anyway, let’s continue with our little selfmade analysis.

  1. You have placed 2x icons in shape of an ARROW, like << >> (could also be 2 buttons).

How do I make the behavior that on each arrow click, it moves the elements a certain pixel forward each time till it reaches the end

Why do you need this pixel-movement-behaviour?

And here again the question → What kind of function, feature, functionality, should be your end-result? Because, regarding last mentioned point, it even seems like you want to move an element directly on screen.

You must know → that in wix/velo you can’t move elements → directly. The only way would be to use → wix animations (maybe).

So since you can not exactly provide what you are looking for, i will make examples by myself…

EXAMPLE: —> SIMPLE-SLIDER (arrows)

EXAMPLE: —> SIMPLE-SLIDER (buttons)

EXAMPLE: —> SIMPLE-SLIDER-CAROUSEL


EXAMPLE: —> CAROUSEL (medium-difficulty/quality)

EXAMPLE: —> CAROUSEL (HIGH-QUALITY)

EXAMPLE: —> SOMETHING-ELSE

And if you will search the web, you will find much more.

Or you simply use one of Wix provided GALLARIES
Or maybe a → REPEATER ?
But you couls maybe even use a MSB for your purposes?

Or you create your own stuff, for example like this one, i am working on…(beta-version)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Centered Div</title>
  <link rel="stylesheet" href="styles.css">
  
   <style>
      :root {--cell-font-color: black;} 
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
      }
      .nav-button {
        padding: 0.3em;
        margin: auto;
        border: 1px solid var(--cell-font-color);
        border-radius: 5px;
        color: white;
        background: red;
        display: flex;
        align-items: center;
        justify-content: center; /* Horizontally center the content */
        text-align: center; /* Horizontally center the text within the button */
      }
      .carousel__cell {
        position: absolute;
        left: 10px;
        top: 10px;
        border: 2px solid var(--cell-font-color);
        line-height: 116px;
        font-size: 80px;
        font-weight: bold;
        color: var(--cell-font-color);
        text-align: center;
        transition: transform 1s, opacity 1s;
      }
      .carousel-options {
        text-align: center;
        position: relative;
        z-index: 2;      
      }
    </style>

    <style>
    /* Add the following styles */
      .radio-container {
        position: absolute;
        top: 50%; /* Center vertically */
        left: 50%; /* Center horizontally */
        transform: translate(-50%, -50%); /* Center both horizontally and vertically */
        background: white; /* Change the background color for visibility */
        padding: 10px; /* Add padding for better visibility */
      }
    </style>
    
    
    
   
    
    
    
    <script>  
      function create_carousel(carouselOptions, radioOptions) {
        let cellCount,selectedIndex=0,isHorizontal=true;
        //-------------------------------------
        const containerMS = create_mainStage();
        const containerCB = create_controlBox(containerMS);
        const containerSD1 = create_subDiv(containerCB);   
        const divScene = create_divScene(containerMS);
        const carousel = create_divCarousel(divScene);
        //-------------------------------------
        const divSlider = create_Slider(containerCB);
        const nextButton = create_NavButton(containerSD1,'Next', +1, onNavigationMouseOver, onNavigationMouseOut, onNavigationClick);
        const prevButton = create_NavButton(containerSD1,'Prev', -1, onNavigationMouseOver, onNavigationMouseOut, onNavigationClick);
        const optRadio = create_RadioButtons(containerCB,radioOptions);      
        //-------------------------------------
        const cellsRange = document.querySelector('.cells-range');
        const navButtons = document.querySelectorAll('.nav-button');
        const orientationRadios = document.querySelectorAll('input[name="orientation"]');
        //-------------------------------------
        cellsRange.addEventListener('input', handleInputChange);
        orientationRadios.forEach(radio => radio.addEventListener('change', onOrientationChange));
        cellsRange.dispatchEvent(new Event('input'));
        //#####################################[ Carousel-FUNCTIONS ]###############################################
        //------------[ Carousel-Update ]----------------------------
        function updateCarousel() {
          const cellSize = isHorizontal ? carousel.offsetWidth : carousel.offsetHeight;
          const theta = 360 / cellCount;
          const radius = Math.round((cellSize / 2) / Math.tan(Math.PI / cellCount));
          carousel.style.transform = `translateZ(${-radius}px) rotate${isHorizontal ? 'Y' : 'X'}(${-theta * selectedIndex}deg)`;
          for (let i = 0; i < cells.length; i++) {
            const cell = cells[i];
            const cellAngle = theta * i;

            if (i < cellCount) {
              cell.style.opacity = carouselOptions.opacity;
              cell.style.transform = `rotate${isHorizontal ? 'Y' : 'X'}(${cellAngle}deg) translateZ(${radius}px)`;
            } else {
              // cell.style.opacity = 0;
              // cell.style.transform = 'none';
            }
          }
        }      
        //------------[ RANDOM-COLOR-GENERATOR ]----------------------------
        function getRandomRGBA() {
          //const random255 = () => Math.floor(Math.random() * 256);
          //return `rgba(${random255()}, ${random255()}, ${random255()}, 0.8)`;
          return 'rgba(100,200,255, 0.8)';
        }      
        //------------[ Generate CAROUSEL-ITEMS ]----------------------------
        function create_Cell(index) {
          const cell = document.createElement('div');
          cell.classList.add('carousel__cell');
          cell.textContent = index + 1;
          cell.style.width = carouselOptions.itemWidth;
          cell.style.height = carouselOptions.itemHeight;
          const randomColor = getRandomRGBA();
          cell.style.backgroundColor = randomColor;
          return cell;
        }         
        //#####################################[ Main-FUNCTIONS ]###############################################
        //------------[ CREATE-MAINSTAGE ]----------------------------
        function create_mainStage(){
          const containerMS = document.createElement('div');
                containerMS.id = 'mainStage';
                containerMS.style.width = '500px';
                containerMS.style.height = '500px';
                containerMS.style.backgroundColor = 'black';
                //containerMS.style.position = 'relative';
                containerMS.style.display = 'flex';
                containerMS.style.justifyContent = 'flex-start';
                containerMS.style.flexDirection = 'column';
                containerMS.style.alignItems = 'center';
                containerMS.style.textAlign = 'center';        
          document.body.appendChild(containerMS);
          return containerMS
        }       
        //------------[ CREATE-CONTROLBOX ]----------------------------
        function create_controlBox(containerMS){
          const containerCB = document.createElement('div');
                containerCB.style.width = '180px';
                containerCB.style.height = '90px';
                containerCB.style.top = '10px';
                containerCB.style.backgroundColor = 'yellow';
                containerCB.style.margin = '5px'
                containerCB.style.padding = '5px';
                containerCB.style.display = 'flex';
                containerCB.style.flexDirection = 'column';
                containerCB.style.alignItems = 'center';
                containerCB.style.justifyContent = 'center';
                containerCB.style.textAlign = 'center'; 
          containerMS.appendChild(containerCB);
          return containerCB
        }
      	//------------[ CREATE-CONTROLBOX-SUBDIV ]----------------------------
        function create_subDiv(container) {
          const subDiv1 = document.createElement('div');
                subDiv1.style.width = '150px';
                subDiv1.style.margin = 'auto';
                subDiv1.style.padding = '10px';
                subDiv1.style.backgroundColor = 'blue';
                subDiv1.style.display = 'flex';          
                subDiv1.style.alignItems = 'center';
                subDiv1.style.justifyContent = 'center';
                subDiv1.style.textAlign = 'center'; 
          container.appendChild(subDiv1);   
          return subDiv1
        }
        //------------[ CREATE-SCENE ]----------------------------       
        function create_divScene(parentContainer){
          const divScene = document.createElement('div');
                divScene.id = 'scene';
                divScene.style.width = '220px';
                divScene.style.height = '125px';
                divScene.style.backgroundColor = 'red';
                divScene.style.display = 'flex';
                divScene.style.margin = 'auto';
                divScene.style.position = 'relative';              
                divScene.style. perspective = '1000px';
                //divScene.style.border = '2px solid black';              
          parentContainer.appendChild(divScene);
          return divScene
        }        
        //------------[ CREATE-DIV-CAROUSEL ]----------------------------
        function create_divCarousel(parentContainer){
          const carousel = document.createElement('div');        
                carousel.style.width = '100%';
                carousel.style.height = ' 100%';
                carousel.style.position = 'absolute';
                carousel.style.transformStyle = 'preserve-3d';
                carousel.style.transition = 'transform 1s';        
          parentContainer.appendChild(carousel);
          return carousel
        }         
     	 //------------[ CREATE-NAVBUTTON ]----------------------------
       function create_NavButton(container,text,direction, fMouseOver, fMouseOut, fClick) {
         const button = document.createElement('button');
               button.classList.add('nav-button');
               button.textContent = text;
               button.dataset.direction = direction;
               button.addEventListener('mouseover', fMouseOver);
               button.addEventListener('mouseout', fMouseOut);
               button.addEventListener('click', fClick);
         container.appendChild(button);
         return button;
       }          
       //------------[ CREATE-SLIDER ]----------------------------
        function create_Slider(container) {
          const inputSlider = document.createElement('input');
                inputSlider.classList.add('cells-range');
                inputSlider.type = 'range';
                inputSlider.min = '3';
                inputSlider.max = '15';
                inputSlider.value = '9';
          container.appendChild(inputSlider);
          return inputSlider
        }
        //------------[ CREATE-RADIOBUTTONS ]----------------------------
        function create_RadioButtons(container, options) {
          const radioContainer = document.createElement('div');
          options.forEach(option => {
            const label = document.createElement('label');
            const radioInput = document.createElement('input');
                  radioInput.type = 'radio';
                  radioInput.name = 'orientation';
                  radioInput.value = option.value;
            if (option.checked) {radioInput.checked=true;}
            label.appendChild(radioInput);
            label.appendChild(document.createTextNode(option.label));
            radioContainer.appendChild(label);
          });container.appendChild(radioContainer);
        }        
        //#####################################[ SLIDER-FUNCTIONS ]###############################################
        function onNavigationMouseOver(event) {
          event.target.style.backgroundColor = 'lightcoral';
          event.target.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.7)';
        }
        function onNavigationMouseOut(event) 	{event.target.style.backgroundColor = 'red'; event.target.style.boxShadow = 'none';}
        function onNavigationClick(event) {selectedIndex += parseInt(event.target.dataset.direction); updateCarousel();}
        function handleInputChange() {
          cellCount = cellsRange.value;
          cells = Array.from({ length: cellCount }, (_, i) => create_Cell(i));
          carousel.innerHTML = '';
          cells.forEach(cell => carousel.appendChild(cell));
          updateCarousel();
        }
      //#####################################[ RADIOBUTTON-FUNCTIONS ]###############################################
      	//------------[ ORIENTATION-CHANGE ]----------------------------
        function onOrientationChange() {
          isHorizontal = document.querySelector('input[name="orientation"]:checked').value === 'horizontal';
          updateCarousel();
        }        
      }  	
      //#####################################[ SLIDER-FUNCTIONS ]###############################################
        function onNavigationMouseOver(event) {
          event.target.style.backgroundColor = 'lightcoral';
          event.target.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.7)';
        }
        function onNavigationMouseOut(event) 	{event.target.style.backgroundColor = 'red'; event.target.style.boxShadow = 'none';}
        function onNavigationClick(event) {selectedIndex += parseInt(event.target.dataset.direction); updateCarousel();}
        function handleInputChange() {
          cellCount = cellsRange.value;
          cells = Array.from({ length: cellCount }, (_, i) => create_Cell(i));          
          cells.forEach(cell => carousel.appendChild(cell));
          updateCarousel();
        }
      //#####################################[ RADIOBUTTON-FUNCTIONS ]###############################################
      	//------------[ ORIENTATION-CHANGE ]----------------------------
        function onOrientationChange() {
          isHorizontal = document.querySelector('input[name="orientation"]:checked').value === 'horizontal';
          updateCarousel();
        }
    	</script>      
  </head>
  
  <body>
  <script>
  		//-------------------------------------
  		const carouselOptions = {
        opacity: 1,
        itemWidth: '200px',
        itemHeight: '100px',
      };      
      const radioOptions = [
        { value: 'horizontal', label: 'horizontal', checked: true },
        { value: 'vertical', label: 'vertical', checked: false },
      ];      
      //-------------------------------------      
      create_carousel(carouselOptions, radioOptions);
    </script>
    
    
     <script>     
      const resizableDiv = document.getElementById('mainStage');
      let startX, startY, startWidth, startHeight;

      resizableDiv.addEventListener('mousedown', initResize);

      function initResize(e) {
        startX = e.clientX;
        startY = e.clientY;
        startWidth = parseInt(document.defaultView.getComputedStyle(resizableDiv).width, 10);
        startHeight = parseInt(document.defaultView.getComputedStyle(resizableDiv).height, 10);
        document.addEventListener('mousemove', resize);
        document.addEventListener('mouseup', stopResize);
      }

      function resize(e) {
        const width = startWidth + e.clientX - startX;
        const height = startHeight + e.clientY - startY;
        resizableDiv.style.width = width + 'px';
        resizableDiv.style.height = height + 'px';
      }

      function stopResize() {
        document.removeEventListener('mousemove', resize);
      }
		</script>
    
    
    
    
  </body>
</html>
  1. Add an HTML-Component onto your page.
  2. Add the shown code into the HTML-Component.
  3. Save the settings of the HTML-Component.
  4. Test it.

(Sorry can’t show you the real-carousel).

Thanks a lot man. i may need to come back and re-read your comment as a lot of it is very high level for me…i have attached some screen shots below as to help with what i think i am trying to achieve.

All i want o do is be able to click left and right and have the stack slide left and right. i can do that with interactions in the wix studio but it only allows me to click the arrow once to make a slide movement it seems.

does this make more sense as to what i am trying to do?

  1. Are you able to provide a video-screen-shot of how it is working right now?
  2. Choose one of the numerous examples i offered you, which would fit your expectations the most.

Or are you looking for a functionality like…

→ as long as you hold the button clicked → SLIDE-SHOW do a continious SLIDE?
→ releasing the button —> SLIDE-SHOW stops?
→ of course depending on the pressed direction (2-buttons od icons, or images, or what ever)

i could certainly send you a video.

here is the link to what i have right now
current functionality

i could also invite you into the workspace if you want to take a look as well

This is what you want? —> TEST <—
https://russian-dima.wixstudio.io/my-site-8

yes pretty much like that…how did you build that?

SLIDE-SHOW-REPEATER

Well seems to be a little bit buggy on my screen. However, as you can see, this functionality is even provided already by wix.

1 Like

i wasn’t looking to make it full width like that, but i think i can compromise if that’s the only way i can get it to work without having to code. i don’t know how to code at all and wouldn’t be able to to start learning right away for this build as i am in a time crunch

okay thank you so so much for showing me this…i will try to implement it!

If you need further help on your project → velo-ninja@outlook.com