CSS&JS/👀Study and Copy

[WDS] Flip Card Time Turner

arancia_ 2022. 8. 17. 16:48

* WDS : https://www.youtube.com/watch?v=p_6IuhmBsfc&t=1763s
* CodePen : https://codepen.io/doriancami/full/jEJvaV
 
 

Time Turner Animation

0 0 0 0

ohikmyeong.github.io

"카운트 다운"인데 애니메이션 구현하는데 집중하다 보니 그냥 시계로 만들어 버렸다 -__-

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!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>Time Turner Animation </title>
    <link rel="stylesheet" type="text/css" href="./css/main.css"/>
    <script src="./js/main.js" type="module"></script>
</head>
<body>
    <article class="card-wrap">
        <div class="card-title">HOURS</div>
        <div class="card" data-card="hour">
            <span class="btm-bg">0</span><!-- prev -->
            <span class="top-bg">0</span>
            <div class="mv">
                <span class="top-mv">0</span><!-- prev -->
                <span class="btm-mv">0</span>
            </div>
        </div><!-- card -->
        <div class="card" data-card="hour">
            <span class="btm-bg">0</span>
            <span class="top-bg">0</span>
            <div class="mv">
                <span class="top-mv">0</span>
                <span class="btm-mv">0</span>
            </div>
        </div><!-- card -->
    </article><!-- card-wrap -->
 
    <article class="card-wrap">
        <div class="card-title">MINUTE</div>
        <div class="card" data-card="min">
            <span class="btm-bg">0</span>
            <span class="top-bg">0</span>
            <div class="mv">
                <span class="top-mv">0</span>
                <span class="btm-mv">0</span>
            </div>
        </div><!-- card -->
        <div class="card" data-card="min">
            <span class="btm-bg">0</span>
            <span class="top-bg">0</span>
            <div class="mv">
                <span class="top-mv">0</span>
                <span class="btm-mv">0</span>
            </div>
        </div><!-- card -->
    </article><!-- card-wrap -->
 
    <article class="card-wrap">
        <div class="card-title">SECOND</div>
        <div class="card" data-card="sec">
            <span class="btm-bg">0</span>
            <span class="top-bg">0</span>
            <div class="mv">
                <span class="top-mv">0</span>
                <span class="btm-mv">0</span>
            </div>
        </div><!-- card -->
        <div class="card" data-card="sec">
            <span class="btm-bg">0</span>
            <span class="top-bg">0</span>
            <div class="mv">
                <span class="top-mv">0</span>
                <span class="btm-mv">0</span>
            </div>
        </div><!-- card -->
    </article><!-- card-wrap -->
</body>
</html>
cs

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@charset "utf-8";
.card-wrap{
    width:190px;
    display:flex; flex-flow:row wrap;
    justify-content:center;align-items:flex-start;
    gap:10px;
    position:relative;
    text-align:center;}
 
.card-title{width:100%;font-size:14px;font-weight:bold;}
 
.card{
    
    position:relative; overflow:hidden;
    width:90px; aspect-ratio:1/1.3;
    background:#ccc; border-radius:var(--rad);
    border:1px solid #ccc;
    font-weight:bold; font-size:5rem;color:var(--red);
}
 
 
.top-bg{
    display:block;position:absolute; overflow:hidden;
    width:100%; height:50%;
    background:var(--gd);
    border-radius:var(--rad-top);
    line-height:120%;
}
 
.btm-bg{
    bottom:0;
    display:block;position:absolute; overflow:hidden;
    width:100%;height:50%;
    background:var(--gd);
    border-radius: var(--rad-bottom);
    line-height:5%;
}
 
/*  */
.mv{
    position:absolute;
    top:0;left:0;
    width:100%;height:50%;
    transform-style: preserve-3d;
    transform-origin:center bottom;
    transform:rotateX(0deg);
    box-shadow:0 -5px 5px rgba(0,0,0,.1);    
    transition:none;
}
 
    .mv.on{
        /* animation:spin .9s linear forwards; */
        transform:rotateX(180deg);
        transition:transform .92s;
    }
 
    /* @keyframes spin {to{transform:rotateX(180deg);}} */
 
.top-mv,.btm-mv{
    display:block;position:absolute; overflow:hidden;
    top:0;left:0;
    width:100%;height:100%;
    transform-origin:center bottom;
    backface-visibility: hidden;}
 
    .top-mv{
        transform:rotateX(0deg);
        line-height:120%;background:var(--gd);}
    .btm-mv{
        transform-origin:center center;
        transform:rotateX(180deg);
        line-height:5%; background:var(--gd);}
 
cs

main.js

1
2
3
4
import { Clock } from "./Clock.js";
 
const CLOCK = new Clock();
CLOCK.repeat();
cs

fn.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
export function get_time(){
    const DATE = new Date();
    const hh = DATE.getHours();
    const mm = DATE.getMinutes();
    const ss = DATE.getSeconds();
    return [hh,mm,ss];
}//get_time
 
export function get_string_time(time){
    return String(time).padStart(2,"0").split('');
}//get_string_time
 
export function change_text_conetnt(str,...rest){
    rest.forEach($rest => $rest.textContent = str);
}//change_text_conetnt
 
export function is_same_now($$card,time){
    const textTime = get_text_time($$card, "top-bg");
    const result = parseInt(textTime) == time; 
    // console.log(textTime, time, result);
    return result;
}//is_same_now
 
export function get_text_time($$card,clsName){
    return Array.from($$card).map($card =>{
        return $card.getElementsByClassName(clsName)[0].textContent;
    }).join('');
}//get_text_time
 
export function is_same_content($el_1,$el_2){
    return $el_1.textContent == $el_2.textContent;
}//is_same_content
cs

Clock.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { get_time, get_string_time, change_text_conetnt, is_same_now, is_same_content } from "./fn.js";
 
export class Clock{
    constructor(){
        this.$$cardH = document.querySelectorAll('[data-card="hour"]');
        this.$$cardM = document.querySelectorAll('[data-card="min"]');
        this.$$cardS = document.querySelectorAll('[data-card="sec"]');
    }//constructor
 
    //[init]
    init = ()=> {
        const [hh,mm,ss] = get_time();
        this.display_time(ss,this.$$cardS);
        this.display_time(mm,this.$$cardM);
        this.display_time(hh,this.$$cardH,"hour");
    }//init
 
    repeat(){ setInterval(this.init,1000);}
 
    /* [display_time] */
    display_time(time,$$card,type = null){
        if(is_same_now($$card,time)) return;
 
        const prevTime = (time - 1 < 0) ? (type == "hour" ? 23 : 59) : time - 1;
        const [$card1, $card2] = $$card;
        const pt = get_string_time(prevTime);
        const nt = get_string_time(time);
        // console.log(pt,nt);
 
        this.change_time($card1,pt[0],nt[0]);
        this.change_time($card2,pt[1],nt[1]);
    }//display_time
 
    /* change time */
    change_time($card,prevTime,nowTime){
        const [$bBg,$tBg,$tMv,$bMv] = Array.from($card.getElementsByTagName('SPAN'));
        change_text_conetnt(prevTime, $bBg, $tMv);
        change_text_conetnt(nowTime, $tBg, $bMv);
        /* 💚 여기가 관건 ㅎㅎ */
        if(!is_same_content($bBg,$tBg)){
            this.toggle_mv($card,nowTime,$bBg,$tMv);
        }//if
    }//change_time
 
    /* $mv 에 클래스 on toggle 및, 텍스트 갈아치우기 */
    toggle_mv($card,nowTime,$bBg,$tMv){
        const $mv = $card.getElementsByClassName('mv')[0];
        $mv.classList.add('on');
        $mv.addEventListener('transitionend',()=>{
            $mv.classList.remove('on');
            change_text_conetnt(nowTime,$bBg,$tMv);
        },{once:true});
    }//toggle_mv
}//Clock
cs

'CSS&JS > 👀Study and Copy' 카테고리의 다른 글

WDS-Snake Game  (0) 2022.08.22
[WDS]Intro.js 바닐라 자바스크립트로 구현하기  (0) 2022.08.18
WDS,OT - Magic CSS Indicator  (0) 2022.08.09
WDS- Sortable Drag & Drop List  (0) 2022.08.09
[WDS] CSS + JS Review Card  (0) 2022.08.08