首页 > 解决方案 > 轮换列表

  • 任何孩子点击给定位置时放置在圆圈上的图像的数量
  • 问题描述

    我已经使用 css 变换在一个圆圈上排列了一个图像列表。我想要的是,当单击列表的任何子图像时,圆圈会旋转并且所选或活动的子图像到达给定位置。说 3 点钟。我怎样才能用js实现这一点。我目前不知道 sass

    这就是我现在得到的。

    https://ibb.co/zfPQvNn

    单击任何子图像时,我希望圆圈旋转,以使活动图像始终位于同一位置。说 3 点钟

    <div class="team-list">
        <ul>
           <li class="wow active zoomIn" data-wow-duration="1s" data-wow-delay=".1s">
                <a href="#team-1" data-team="team-1">
                   <figure>
                          <img src="https://dummyimage.com/640x4:3/" alt="Team Member image One">
                   </figure>
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".3s">
                <a href="#team-2" data-team="team-2">
                   <figure>
                           <img src="https://dummyimage.com/640x4:3/" alt="Team Member image two">
                   </figure>
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".5s">
                <a href="#team-3" data-team="team-3">
                   <figure>
                          <img src="https://dummyimage.com/640x4:3/" alt="Team Member image three">
                  </figure>
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".7s">
                <a href="#team-4" data-team="team-4">
                   <figure>
                          <img src="https://dummyimage.com/640x4:3/" alt="Team Member image four">
                   </figure>
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".9s">
                <a href="#team-5" data-team="team-5">
                   <figure>
                          <img src="https://dummyimage.com/640x4:3/" alt="Team Member image five">
                  </figure>
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.1s">
                <a href="#team-6" data-team="team-6">
                   <figure>
                          <img src="https://dummyimage.com/640x4:3/" alt="Team Member image six">
                   </figure>
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.3s">
                <a href="#team-7" data-team="team-7">
                   <figure>
                           <img src="https://dummyimage.com/640x4:3/" alt="Team Member image seven">
                   </figure>
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.5s">
                <a href="#team-8" data-team="team-8">
                   <figure>
                           <img src="https://dummyimage.com/640x4:3/" alt="Team Member image eight">
                   </figure>
                </a>
            </li>
         </ul>      
    </div>
    
    
    
    .team-list > ul > * {
      /* 4 */
      display: block;
      position: absolute;
      margin-top:55%;
    
    }
    .team-list > ul > :nth-of-type(1) {
      transform: rotate(0deg) translate(10em) rotate(0deg);
    }
    .team-list >ul > :nth-of-type(2) {
      transform: rotate(45deg) translate(10em) rotate(-45deg);
    }
    .team-list > ul > :nth-of-type(3) {
      transform: rotate(90deg) translate(10em) rotate(-90deg);
    }
    .team-list > ul > :nth-of-type(4) {
      transform: rotate(135deg) translate(10em) rotate(-135deg);
    }
    .team-list > ul > :nth-of-type(5) {
      transform: rotate(180deg) translate(10em) rotate(-180deg);
    }
    .team-list > ul > :nth-of-type(6) {
      transform: rotate(225deg) translate(10em) rotate(-225deg);
    }
    .team-list > ul > :nth-of-type(7) {
      transform: rotate(270deg) translate(10em) rotate(-270deg);
    }
    .team-list > ul > :nth-of-type(8) {
      transform: rotate(315deg) translate(10em) rotate(-315deg);
    }
    
    .team-list img {
      display: block;
      width: 100%;
    }
    

    标签: javascripthtmlcsssasscss-animations

    解决方案


    选项1

    可以完成的方法之一是每次用户单击项目时“转移”项目的变换属性,从而实现有点吸引人但不是很干净的旋转效果。您可以使用getComputedStyle函数来执行此操作,如下所示:

    let allItems = document.getElementById('list').getElementsByTagName('li');
    let allItemsAsArray = Array.from(allItems);
    
    let fixedPositions = {}, transforms = {};
    let auxPosition = 0;
    
    allItemsAsArray.forEach((elem, index) => {
      transforms[auxPosition] = window.getComputedStyle(elem).transform;
      fixedPositions[index] = auxPosition++;
    
      elem.addEventListener('click', (event) => {
        let steps = 8 - fixedPositions[index];
        allItemsAsArray.forEach((elem2, index2) => {
              copyTransformProp(
                  transforms[fixedPositions[(index2 + steps) % 8]]
                ,
              elem2);
        });
      });
    });
    
    function copyTransformProp(sourceProperty, targetNode) {  
      targetNode.style.setProperty('transform', sourceProperty);
    }
    .team-list > ul > li {
      /* 4 */
      display: block;
      position: absolute;
      top:55%;
      left: 40%;
      transition: ease all 1s;
    }
    
    #list img {
      width: 50px
    }
    
    .team-list > ul > :nth-of-type(1) {
      transform: rotate(0deg) translate(10em) rotate(0deg);
    }
    
    .team-list >ul > :nth-of-type(2) {
      transform: rotate(45deg) translate(10em) rotate(-45deg);
    }
    
    .team-list > ul > :nth-of-type(3) {
      transform: rotate(90deg) translate(10em) rotate(-90deg);
    }
    
    .team-list > ul > :nth-of-type(4) {
      transform: rotate(135deg) translate(10em) rotate(-135deg);
    }
    .team-list > ul > :nth-of-type(5) {
      transform: rotate(180deg) translate(10em) rotate(-180deg);
    }
    .team-list > ul > :nth-of-type(6) {
      transform: rotate(225deg) translate(10em) rotate(-225deg);
    }
    .team-list > ul > :nth-of-type(7) {
      transform: rotate(270deg) translate(10em) rotate(-270deg);
    }
    .team-list > ul > :nth-of-type(8) {
      transform: rotate(315deg) translate(10em) rotate(-315deg);
    }
    
    .team-list img {
      display: block;
      width: 20%;
    }
    <div class="team-list">
        <ul id='list'>
           <li class="wow active zoomIn" data-wow-duration="1s" data-wow-delay=".1s" >
                <a href="#team-1" data-team="team-1">
                   
                          <img src="https://dummyimage.com/640x4:3/&text=1" alt="Team Member image One">
                   
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".3s">
                <a href="#team-2" data-team="team-2">
                   
                           <img src="https://dummyimage.com/640x4:3/&text=2" alt="Team Member image two">
                   
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".5s">
                <a href="#team-3" data-team="team-3">
                   
                          <img src="https://dummyimage.com/640x4:3/&text=3" alt="Team Member image three">
                  
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".7s">
                <a href="#team-4" data-team="team-4">
                   
                          <img src="https://dummyimage.com/640x4:3/&text=4" alt="Team Member image four">
                   
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay=".9s">
                <a href="#team-5" data-team="team-5">
                   
                          <img src="https://dummyimage.com/640x4:3/&text=5" alt="Team Member image five">
                  
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.1s">
                <a href="#team-6" data-team="team-6">
                   
                          <img src="https://dummyimage.com/640x4:3/&text=6" alt="Team Member image six">
                   
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.3s">
                <a href="#team-7" data-team="team-7">
                   
                           <img src="https://dummyimage.com/640x4:3/&text=7" alt="Team Member image seven">
                   
                </a>
            </li>
            <li class="wow zoomIn" data-wow-duration="1s" data-wow-delay="1.5s">
                <a href="#team-8" data-team="team-8">
                   
                           <img src="https://dummyimage.com/640x4:3/&text=8" alt="Team Member image eight">
                   
                </a>
            </li>
         </ul>      
    </div>

    选项 2

    现在,为了实现真正干净的旋转,我会使用request​Animation​Frame 。这一次,您将不再依赖 CSS 属性转换来获得平滑度,而是直接在 JavaScript 中使用角度。

    我认为在 JS 中动态生成项目可能会更好,因此您不必在 CSS 中手动设置每个项目的样式。它还允许您生成“任意数量的项目”,不过要小心,不要对数量过于贪婪。

    试试这个片段整页。

    HIH

    let ul = document.getElementById('list');
    let anglePerItem = [];
    
    generateItems(8, 0, 9);
    
    let allItems = ul.getElementsByTagName('li');
    let allItemsAsArray = Array.from(allItems);
    
    function generateItems(itemNum, initAngle, radius) {
        let angleStep = Math.PI * 2 / itemNum;
        let angle = initAngle;
    
        for (let i = 0; i < itemNum; i++) {
            let li = document.createElement('li');
            if (i === 0)
                li.classList.add('wow', 'active', 'zoomIn');
            else
                li.classList.add('wow', 'zoomIn');
    
            let a = document.createElement('a');
            a.href = '#team-' + (i + 1);
            a.setAttribute('data-team', 'team-' + (i + 1));
            li.appendChild(a);
    
            let img = document.createElement('img');
            img.src = 'https://dummyimage.com/640x4:3/&text=' + (i + 1);
            img.alt = 'Team Member image ' + (i + 1);
            a.appendChild(img);
    
            let x = Math.cos(angle) * radius, y = Math.sin(angle) * radius;
            anglePerItem.push(angle);
            angle += angleStep;
            li.style.transform = 'translate(' + x + 'em, ' + y + 'em)';
    
            ul.appendChild(li);
    
            addClickEvent(li, i, radius);
        }
    }
    
    function addClickEvent(elem, clickedIndex, radius) {
        elem.addEventListener('click', () => {
            if (anglePerItem[clickedIndex] !== 0) {
                Array.from(ul.getElementsByTagName('li')).forEach((elem, index) => {
                    let angle = anglePerItem[index] % (Math.PI * 2);
                    let endAngle = Math.PI * 2 - anglePerItem[clickedIndex] + angle;
                    if (angle > endAngle)
                        endAngle += Math.PI * 2;
    
                    function step(timestamp) {
                        let x = Math.cos(angle) * radius, y = Math.sin(angle) * radius;
                        angle += .1;
    
                        elem.style.transform = 'translate(' + x + 'em, ' + y + 'em)';
    
                        if (angle < endAngle) {
                            setTimeout(function () {
                                window.requestAnimationFrame(step);
                            }, 10);
                        } else {
                            elem.style.transform = 'translate(' + Math.cos(endAngle) * radius + 'em, ' + Math.sin(endAngle) * radius + 'em)';
                            anglePerItem[index] = endAngle;
                        }
                    }
    
                    window.requestAnimationFrame(step);
                });
            }
        });
    }
    .team-list > ul > li {
        display: block;
        position: absolute;
        top:50%;
        left: 40%;
    }
    
    #list img {
        width: 50px
    }
    
    .team-list img {
        display: block;
        width: 20%;
    }
    <div class="team-list"><ul id='list'></ul></div>


    推荐阅读