Weilory
Weilory

Reputation: 3111

CSS parent with 3d perspective but not text child

const wrapper = document.querySelector('.conveyor');
var rows;
const [rowLeft, rowTop, rowRight, rowBottom] = rows = wrapper.querySelectorAll('.row');

var config = {
    timing: 300, 
}

function clockwise(){
    let rights = [...rowTop.querySelectorAll('.row-item')];
    let tops = [...rowLeft.querySelectorAll('.row-item')];
    let lefts = [...rowBottom.querySelectorAll('.row-item')];
    let bottoms = [...rowRight.querySelectorAll('.row-item')];
    const row_items = [...rights, ...tops, ...lefts, ...bottoms];
    function reachPos(){
        let l1 = tops.shift();
        let t1 = rights.pop();
        let r1 = bottoms.pop();
        let b1 = lefts.shift();
        rights.unshift(l1);
        bottoms.unshift(t1);
        lefts.push(r1);
        tops.push(b1);
        rights.forEach(e=>rowTop.appendChild(e));
        tops.forEach(e=>rowLeft.appendChild(e));
        lefts.forEach(e=>rowBottom.appendChild(e));
        bottoms.forEach(e=>rowRight.appendChild(e));
        console.log(rowTop.isConnected);
    }
    wrapper.classList.add('clockwise');
    setTimeout(()=>{
        row_items.forEach(r=>r.remove());
        wrapper.classList.remove('clockwise');
        reachPos();
    }, config.timing);
}

window.addEventListener('click', ()=>{
    clockwise();
});
:root{
    --total-w: 500px;
    --row-w: 100px;
    --item-w: 80px;
    --margin: 10px;
    --side-padding: 35px;
    --item-count: 4;
    --trans: calc(var(--item-w) + var(--side-padding) + var(--margin) * 2);
    --timing: 300ms;
}

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body{
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.conveyor{
    position: relative;
    width: var(--total-w);
    height: var(--total-w);
    border: 1px solid;
    perspective: 800px;
    transform-origin: center center;
    transform-style: preserve-3d;
    transform: rotateX(65deg) rotateZ(45deg);
    background: linear-gradient(to right, cadetblue, lightgreen);
}

.conveyor .center-text{
    position: absolute;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;

    /*transform-origin: center center;
    transform: rotateX(-65deg) rotateZ(-45deg);*/
}

.row-top,
.row-bottom{
    position: absolute;
    height: var(--row-w);
    width: calc(100% - var(--row-w));
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
}

.row-top{
    left: 0;
    top: 0;
    padding-right: var(--side-padding);
    border: 1px solid yellow;
}
.row-bottom{
    right: 0;
    bottom: 0;
    padding-left: var(--side-padding);
    border: 1px solid green;
}

.row-left,
.row-right{
    position: absolute;
    height: calc(100% - var(--row-w));
    width: var(--row-w);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
}

.row-left{
    bottom: 0;
    left: 0;
    padding-top: var(--side-padding);
    border: 1px solid red;
}
.row-right{
    top: 0;
    right: 0;
    padding-bottom: var(--side-padding);
    border: 1px solid blue;
}

.row-item{
    width: var(--item-w);
    height: var(--item-w);
    background-color: wheat;
    margin: var(--margin);
    transform-style: flat;
    position: relative;
}

.conveyor .row .row-item .row-text{
    transform-style: flat;
    -webkit-transform-style: flat;
}

@keyframes cw-right{
    100%{
        transform: translateX(var(--trans));
    }
}

@keyframes cw-bottom{
    100%{
        transform: translateY(var(--trans));
    }
}

@keyframes cw-left{
    100%{
        transform: translateX(calc(0px - var(--trans)));
    }
}

@keyframes cw-top{
    100%{
        transform: translateY(calc(0px - var(--trans)));
    }
}

.conveyor.clockwise .row-top .row-item{
    animation: cw-right var(--timing) ease-out;
}
.conveyor.clockwise .row-right .row-item{
    animation: cw-bottom var(--timing) ease-out;
}
.conveyor.clockwise .row-bottom .row-item{
    animation: cw-left var(--timing) ease-out;
}
.conveyor.clockwise .row-left .row-item{
    animation: cw-top var(--timing) ease-out;
}
<div class="conveyor">
    <div class="row row-left">
        <div class="row-item">
            <div class="row-text">1 one</div>
        </div>
        <div class="row-item">2 two</div>
        <div class="row-item">3 three</div>
    </div>
    <div class="row row-top">
        <div class="row-item">12 twelve</div>
        <div class="row-item">11 eleven</div>
        <div class="row-item">10 ten</div>
    </div>
    <div class="row row-right">
        <div class="row-item">9 nine</div>
        <div class="row-item">8 eight</div>
        <div class="row-item">7 seven</div>
    </div>
    <div class="row row-bottom">
        <div class="row-item">4 four</div>
        <div class="row-item">5 five</div>
        <div class="row-item">6 six</div>
    </div>

    <div class="center-text">
        CENTER
    </div>
</div>

trying to dev a 3d conveyor belt in css, the logic is pretty simple:

  1. parent set a 3d pespective transformation
  2. four rows, each only occpy one cornor
  3. js click to rearrange positions
  4. toggle css .clockwise to translate item

but there is a BIG issue I CANNOT SOLVE, text at center and texts on each item, should not display that way as 3d, instead, I seek for a way to display the text normally facing the audience.

thinking about this all day, have not come up with an elegant approach, will be more than glad if u can give me a hand.

Upvotes: 0

Views: 24

Answers (0)

Related Questions