【问题标题】:css transition issue with slider滑块的CSS过渡问题
【发布时间】:2021-11-28 00:40:37
【问题描述】:

我在这里提供了我所有的代码似乎都很好问题是当我从最后一张幻灯片更改为第一张或相反时,在这两种情况下,所有幻灯片都会以不同的方式翻转,而不是像其他幻灯片一样旋转

render()函数是所有坐标计算的地方 我认为问题在于 CSS 过渡,因为它的主要内容是动画幻灯片,如果你能找到任何简单的解决方法,请告诉我请寻找简单的解决方案或可能性,而不会过多地混淆坐标。提前致谢

class slider {
    constructor(){
        if(typeof arguments[0] != "undefined"){
            this.init()
            arguments[0].appendChild(this.html)
            this.calculate()
            this.render(1)
        }
        else{this.init()}
    }
    init(){
        let obj = this
        this.html = `
<div class="root border-2 p-5 border-black m-auto">
    <div class="each border border-black absolute text-center">item name 1</div>
</div>
        ` 
        let el = document.createElement("div")
        el.innerHTML = this.html
        this.html = el.querySelector("*")
        this.root = this.html

        let eEl = this.root.querySelector(".each")
        this.eachTemp = eEl.cloneNode(true)
        eEl.remove()

        this.fillBoxes(6)
        this.html.addEventListener("click",function(e){
            obj.onclick(obj,e)
        })
    }

    onclick(obj,e){
        let t = e.target
        if(t.closest(".each")){
            obj.render(t.index)
        }
    }

    fillBoxes(num){
        for(let i=0;i<num;i++){
            let newEl = this.eachTemp.cloneNode(true)
            newEl.index = i+1
            newEl.innerText = "Item " + (i+1)
            this.html.appendChild(newEl)
        }
        this.els = this.html.querySelectorAll(".each")
    }

    calculate(){
        this.eCor = this.els[0].getClientRects()[0]
        this.mag = this.eCor.width
        this.per = Math.PI / (this.els.length / 2)
        this.deg = this.rtod(this.per)        
    }

    render(index){
        this.els.forEach((each,i)=>{
            let rad = (this.per * i) - this.per*(index-1),
                x = Math.sin(rad)*this.mag,
                y = Math.cos(rad)*this.mag
            if(i+1 == index){each.classList.add("active")}
            else{each.classList.remove("active")}
            each.style.transform = `translate3d(${x}px,0%,${y}px)`
            each.style.transform += `rotateY(${this.rtod(rad)}deg)`
        })
    }

    rtod(radians){
        return radians * (180/Math.PI)
    }        

}

const s = new slider(document.body)
.each{
        height: 250px;
        width: 250px;
        background: skyblue;
        opacity: 0.8;
        transform-origin: 50% 50%;
        transform-style: preserve-3d;
        user-select: none;
        filter: brightness(80%);
        transition: all 1s  cubic-bezier(0, 1.22, 0.53, 1.02);
        /* box-shadow: 0px 0px 10px 1px black; */
    }
    .each:nth-child(odd){background:lightsalmon}
    .root{
        height: 280px;
        width: 280px;
        position: relative;
        margin-top: 10%;        
        perspective: 1000px;        
        transform-style: preserve-3d;
        transition: transform 0.5s;
        /* animation: loop 4s infinite linear; */
    }
    .each:hover{
        z-index: 1000 !important;
        filter:brightness(110%);
    }
    .active{
        opacity: 1 !important;
        filter:brightness(100%) !important;
    }
&lt;link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet"&gt;

【问题讨论】:

    标签: javascript html css css-animations


    【解决方案1】:

    当您在 1 和 6 张幻灯片之间切换时,您计算的 rotatedY 值会从 0deg 变为 300deg(或从 300deg 变为 0deg)。但实际上你只需要±60度更新。因此,您需要一种机制以两种方式无休止地增加/减少您的 rotateY,例如 240 -> 300 -> 360 -> 420 -> 480 ...(不是 240 -> 300 -> 0 -> 60 -> .. .)

    我建议你在你的类中拥有这些属性:

    currentIndex = 1;
    radOffset = 0;
    

    然后,当您点击元素时,您需要计算 radOffset(它会不断增加/减少):

    const totalElements = this.els.length;
    const rightDiff = t.index > this.currentIndex ? t.index - this.currentIndex : totalElements + t.index - this.currentIndex;
    const leftDiff = totalElements - rightDiff;
    const closestDiff = rightDiff < leftDiff ? - rightDiff : leftDiff;
    
    this.currentIndex = t.index;
    this.radOffset += this.per * closestDiff;
    

    然后在你的渲染函数中使用它:

    let rad = (this.per * i) + this.radOffset,
    

    class slider {
        
        currentIndex = 1;
        radOffset = 0;
    
        rotateOffset = 0;
            constructor(){
                if(typeof arguments[0] != "undefined"){
                    this.init()
                    arguments[0].appendChild(this.html)
                    this.calculate()
                    this.render(1)
                }
                else{this.init()}
            }
            init(){
                let obj = this
                this.html = `
        <div class="root border-2 p-5 border-black m-auto">
            <div class="each border border-black absolute text-center">item name 1</div>
        </div>
                ` 
                let el = document.createElement("div")
                el.innerHTML = this.html
                this.html = el.querySelector("*")
                this.root = this.html
        
                let eEl = this.root.querySelector(".each")
                this.eachTemp = eEl.cloneNode(true)
                eEl.remove()
        
                this.fillBoxes(6)
                this.html.addEventListener("click",function(e){
                    obj.onclick(obj,e)
                })
            }
        
            onclick(obj,e){
                let t = e.target
                if(t.closest(".each")){
                
                    const totalElements = this.els.length;
                    const rightDiff = t.index > this.currentIndex ? t.index - this.currentIndex : totalElements + t.index - this.currentIndex;
                    const leftDiff = totalElements - rightDiff;
                    const closestDiff = rightDiff < leftDiff ? - rightDiff : leftDiff;
    
                    this.currentIndex = t.index;
                    this.radOffset += this.per * closestDiff;
                    
                    obj.render(t.index);
                    
                }
            }
        
            fillBoxes(num){
                for(let i=0;i<num;i++){
                    let newEl = this.eachTemp.cloneNode(true)
                    newEl.index = i+1
                    newEl.innerText = "Item " + (i+1)
                    this.html.appendChild(newEl)
                }
                this.els = this.html.querySelectorAll(".each")
            }
        
            calculate(){
                this.eCor = this.els[0].getClientRects()[0]
                this.mag = this.eCor.width
                this.per = Math.PI / (this.els.length / 2)
                this.deg = this.rtod(this.per)        
            }
        
            render(index, rotateDiff){
                this.els.forEach((each,i)=>{
                    let rad = (this.per * i) + this.radOffset,
                        x = Math.sin(rad)*this.mag,
                        y = Math.cos(rad)*this.mag
                    if(i+1 == index){each.classList.add("active")}
                    else{each.classList.remove("active")}
                     
                    each.style.transform = `translate3d(${x}px,0%,${y}px)`
                    each.style.transform += `rotateY(${this.rtod(rad)}deg)`
                })
            }
        
            rtod(radians){
                return Math.round(radians * (180/Math.PI));
            }        
        
        }
        
        const s = new slider(document.body)
    .each{
            height: 250px;
            width: 250px;
            background: skyblue;
            opacity: 0.8;
            transform-origin: 50% 50%;
            transform-style: preserve-3d;
            user-select: none;
            filter: brightness(80%);
            transition: all 1s  cubic-bezier(0, 1.22, 0.53, 1.02);
            /* box-shadow: 0px 0px 10px 1px black; */
        }
        .each:nth-child(odd){background:lightsalmon}
        .root{
            height: 280px;
            width: 280px;
            position: relative;
            margin-top: 10%;        
            perspective: 1000px;        
            transform-style: preserve-3d;
            transition: transform 0.5s;
            /* animation: loop 4s infinite linear; */
        }
        .each:hover{
            z-index: 1000 !important;
            filter:brightness(110%);
        }
        .active{
            opacity: 1 !important;
            filter:brightness(100%) !important;
        }
    &lt;link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet"&gt;

    【讨论】:

    • 哇,你真的解决了这个问题,我真的搞砸了,同时卡住了,因为我正在学习数学函数,对此不太了解,你的解决方案真的很明显我感谢你的时间和知识
    猜你喜欢
    • 2019-01-17
    • 1970-01-01
    • 2012-12-30
    • 2012-04-08
    • 1970-01-01
    • 2015-07-28
    • 1970-01-01
    • 2018-01-06
    相关资源
    最近更新 更多