ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

CSS

๊ณ ์–‘์ด ์• ๋‹ˆ๋ฉ”์ด์…˜ (Cat animation) using pug & Scss

๊น€์ฝ”๋ฆฐ๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป 2022. 8. 20. 17:49

pug & Scss๋กœ ๊ณ ์–‘์ด animation ๋งŒ๋“ค๊ธฐ

pug & Scss ํ™œ์šฉํ•ด๋ณด๊ธฐ


๊ฒฐ๊ณผ

pug

pug๋Š” html์„ ์กฐ๊ธˆ ๋” ์„ธ๋ จ๋˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋Š” ํ…œํ”Œ๋ฆฟ ์–ธ์–ด, express ๋ทฐ ์—”์ง„์ด๋‹ค. npm์œผ๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

<p> ๋ผ๋ฉด์— ๋ฐฅ ๋ง์•„์„œ ๋จน๊ณ  ์‹ถ๋‹ค </p> ์ด๋ ‡๊ฒŒ ์“ฐ๋Š” ๊ฒƒ์„
p ๋ผ๋ฉด์— ๋ฐฅ ๋ง์•„์„œ ๋จน๊ณ  ์‹ถ๋‹ค ์ฒ˜๋Ÿผ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

.cat
.ear.ear--left
.ear.ear--right
.face
    .eye.eye--left
    .eye-pupil
    .eye.eye--right
    .eye-pupil
    .muzzle

Scss

css๋ณด๋‹ค ๊ฐ„๋‹จํ•œ scss๋กœ ์Šคํƒ€์ผ์„ ์ฃผ์—ˆ๋‹ค.

$color-black: #161616; //์ƒ‰ ๋ณ€์ˆ˜๋งŒ๋“ค๊ธฐ 
$color-white: #fff; //์ƒ‰ ๋ณ€์ˆ˜๋งŒ๋“ค๊ธฐ 
$size: 170px; // (Fully responsive)

// Cat
.cat {
    position: relative;
    height: $size;
    width: $size * 1.13;
}

// Ears
.ear {
    position: absolute;
    top: -30%;
    height: 60%;
    width: 25%;
    background: $color-white;
    
    // Ear hair
    &::before,
    &::after {
        content: '';
        position: absolute;
        bottom: 24%;
        height: 10%;
        width: 5%;
        border-radius: 50%;
        background: $color-black;
    }
    
    &::after {
        transform-origin: 50% 100%;
    }
}

.ear--left {
    left: -7%;
    border-radius: 70% 30% 0% 0% / 100% 100% 0% 0%;
    transform: rotate(-15deg);
    
    &::before,
    &::after {
        right: 10%;
    }
    
    &::after {
        transform: rotate(-45deg);  //๋ˆˆ์•Œ ์›€์ง์ž„ 
    }
}

.ear--right {
    right: -7%;
    border-radius: 30% 70% 0% 0% / 100% 100% 0% 0%;
    transform: rotate(15deg);
    
    &::before,
    &::after {
        left: 10%;
    }
    
    &::after {
        transform: rotate(45deg); //๋ˆˆ์•Œ ์›€์ง์ž„ 
    }
}

// Face
.face {
    position: absolute;
    height: 100%;
    width: 100%;
    background: $color-black;
    border-radius: 50%;
}

// Eyes
.eye {
    position: absolute;
    top: 35%;
    height: 30%;
    width: 31%;
    background: $color-white;
    border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
    
    // Eyelids
    &::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        height: 0;
        width: 100%;
        border-radius: 0 0 50% 50% / 0 0 40% 40%;
        background: $color-black;
        animation: blink 4s infinite ease-in; //4์ดˆ์— ํ•œ๋ฒˆ์”ฉ ๋ˆˆ๊นœ๋นก์ž„ 
    }
    
    @keyframes blink {
        0% { height: 0; }
        90% { height: 0; }
        92.5% { height: 100%; }
        95% { height: 0; }
        97.5% { height: 100%; }
        100% { height: 0; }
    }
    
    // Tips of the eyes
    &::before {
        content: '';
        position: absolute;
        top: 60%;
        height: 10%;
        width: 15%;
        background: $color-white;
        border-radius: 50%;
    }
}

.eye--left {
    left: 0;
    
    &::before {
        right: -5%;
    }
}

.eye--right {
    right: 0;
    
    &::before {
        left: -5%;
    }
}

// Pupils
.eye-pupil {
    position: absolute;
    top: 25%;
    height: 50%;
    width: 20%;
    background: $color-black;
    border-radius: 50%;
    animation: look-around 4s infinite;  //4์ดˆ์— ํ•œ๋ฒˆ์”ฉ ๋ˆˆ์•Œ ๊ตด๋ฆผ x ๋ฌดํ•œ 
    
    @keyframes look-around {
        0% { transform: translate(0) }
        5% { transform: translate(50%, -25%) }
        10% { transform: translate(50%, -25%) }
        15% { transform: translate(-100%, -25%) }
        20% { transform: translate(-100%, -25%) }
        25% { transform: translate(0, 0) }
        100% { transform: translate(0, 0) }
    }
    
    .eye--left & {
        right: 30%;
    }
    
    .eye--right & {
        left: 30%;
    }
    
    // Glare on the pupil
    &::after {
        content: '';
        position: absolute;
        top: 30%;
        right: -5%;
        height: 20%;
        width: 35%;
        border-radius: 50%;
        background: $color-white;
    }
}

// Muzzle ์ฝ” 
.muzzle {
    position: absolute;
    top: 60%;
    left: 50%;
    height: 6%;
    width: 10%;
    background: $color-white;
    transform: translateX(-50%); //๊ฐ€๋กœ๋กœ -50%๋งŒํผ ์ด๋™ 
    border-radius: 50% 50% 50% 50% / 30% 30% 70% 70%;
}

/* General page styling */
html {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: $color-black;
}
๊ณต์ง€์‚ฌํ•ญ