banner

블로그 개편기 EP.2

#blog#nuxt#tailwindCSS

2023.08.11

깔끔하고 내 입맛대로 블로그를 꾸며보고 싶어 시작한 블로그 개편기..!

🔑 소소한 재미 요소

스크롤 시 헤더 변화 & 이미지 배너 변화

스크롤이 발생하면, 헤더의 색상이 변경되도록 했습니다.
이미지 배너 또한 스크롤 시 scale이 확장되어 보다 더 인터랙티브한 효과를 줍니다.

로고 텍스트 마우스 오버 시 선으로 그려지는 효과

로고 텍스트를 svg파일로 만들어 마우스 오버 시 선들이 다시 그려지는 효과를 주었습니다.

<svg
    :class="[
        { 'fill-white hover:animate-[stroke_1s_linear]': !isScroll },
        { 'hover:animate-[strokeBlack_1s_linear]': isScroll },
    ]"
    width="180"
    height="100%"
    viewBox="0 0 180 100"
>
    <text
        y="50%"
        :class="`text-xl animate-[${
            isScroll ? 'strokeBlack' : 'strokeBlack'
        }_1s_linear]`"
    >
        Beom Log
    </text>
</svg>
text {
    stroke-dasharray: 24px;
}

@keyframes stroke {
    0% {
        stroke: white;
        stroke-width: 1px;
        stroke-dashoffset: 24px;
    }
    70% {
        fill: transparent;
    }
    98% {
        stroke: white;
        stroke-width: 1px;
    }
    100% {
        fill: white;
        stroke-dashoffset: 0px;
    }
}

@keyframes strokeBlack {
    0% {
        stroke: black;
        stroke-width: 1px;
        stroke-dashoffset: 24px;
    }
    70% {
        fill: transparent;
    }
    98% {
        stroke: black;
        stroke-width: 1px;
    }
    100% {
        fill: black;
        stroke-dashoffset: 0px;
    }
}

프로필 사진 확대

프로필 사진에 마우스 오버를 하게되면 scale이 커지도록 애니메이션 효과를 주었습니다.
tailwindCSS로 편리하게 애니메이션 효과를 줄 수 있습니다.

<img
    class="m-auto w-24 h-24 rounded-full object-cover border-double border-2 border-slate-300 transition duration-500 hover:scale-125"
    src="~/images/profile.jpg"
    alt="profile"
/>

운영 시간 카운팅

하단 푸터에는 블로그가 현재까지 운영된 시간을 보여줍니다.
페이지 랜더링 시 랜덤하게 일/시간/분/초를 선택하여 보여주며, 바운스 효과를 주어 시간의 흐름을 보여줍니다.

<div class="flex">
    <span>{{ timer }}</span>
    <span class="mx-1 animate-[bounce_1s_infinite]">.</span>
    <span class="mr-1 animate-[bounce_1s_infinite_100ms]">.</span>
    <span class="animate-[bounce_1s_infinite_200ms]">.</span>
</div>
let diffDay = reactive({
    date: 0,
    hour: 0,
    min: 0,
    sec: 0,
});

const random = Math.floor(Math.random() * 4);
const timer = computed(() => {
    const suffix = ["일", "시간", "분", "초"];
    const diffKeys = Object.keys(diffDay);
    const selectedDiffKey = diffKeys[random] as keyof typeof diffDay;
    return `${diffDay[selectedDiffKey]}${suffix[random]} 동안 운영중`;
});

onMounted(() => {
    setInterval(() => {
        // diffDay = getDate();
        const { date, hour, min, sec } = getDate();
        diffDay.date = date;
        diffDay.hour = hour;
        diffDay.min = min;
        diffDay.sec = sec;
        // console.log(diffDay);
    }, 1000);
});

const getDate = () => {
    const startDate = new Date("2023/08/10 22:30:00");
    const curDate = new Date();
    const diff = curDate.getTime() - startDate.getTime();
    const diffDate = Math.floor(diff / (24 * 60 * 60 * 1000));
    const diffHour = Math.floor(diff / (60 * 60 * 1000));
    const diffMin = Math.floor(diff / (60 * 1000));
    const diffSec = Math.floor(diff / 1000);
    return { date: diffDate, hour: diffHour, min: diffMin, sec: diffSec };
};

카테고리 마우스 오버 효과

카테고리 필터에 마우스 오버 시 명확한 표시를 위해 확대 및 강조효과를 주었습니다.

<ul class="flex mb-8 flex-wrap">
    <li
        v-for="(category, i) of categoryList"
        :key="`category-${i}`"
        :class="[
                `mr-3 p-1 px-2 rounded-3xl transition duration-500 hover:scale-125 hover:bg-blue-400 hover:text-white`,
                { 'bg-blue-400 text-white': getIsSelected(category) },
            ]"
    >
        <a
            href="javascript:void(0)"
            @click="setCategory({ category }), getPostList()"
        >
            #{{ category }}
        </a>
    </li>
</ul>

포스트 상세 스크롤 위치에 맞게 달려가는 고양이

1yoouoo님의 블로그를 참고하여 뛰어가는 고양이를 구현했습니다.
스크롤 위치를 계산하여 그에 맞게 left 값이 변화될 수 있도록 했습니다.

<div
    ref="cat"
    :class="[
            { hidden: !catState.isShow },
            { '-scale-x-50': isScrollDown && !catState.isBack },
            `scale-50 bg-[url(~/images/cats.png)] bg-no-repeat absolute w-[112px] h-32 animate-[run_1s_steps(10)_infinite]`,
        ]"
></div>
@keyframes run {
    0% {
        background-position: 0 0;
    }

    100% {
        background-position: -1120px 0;
    }
}

복사하기 시 폭죽 터트리기 & 토스트 메세지 띄우기

wwendy님의 블로그를 참고하여 폭죽 터트리는 효과를 구현했습니다.
폭죽이 터짐과 동시에 우측하단에 토스트 메세지가 나타납니다.

import copy from 'copy-to-clipboard';
const shareRef = ref();

const { showToast } = useToast();

let particles: Array<any> = [];
onMounted(() => {
    window.setTimeout(init, 700);
});
const share = () => {
    pop();
    const route = useRoute();
    // console.log(route.fullPath);
    copy(`${window.location.host}${route.fullPath}`);
    showToast({ text: '클립보드에 복사되었습니다.' });
};
const init = () => {
    // for (let i = particles.length - 1; i--; i > -1) {
    for (let i = 0; i < particles.length; i++) {
        const p = particles[i];
        p.style.transform = `translate3d(${p.x}px, ${p.y}px, 1px)`;

        p.x += p.vel.x;
        p.y += p.vel.y;

        p.vel.y += 0.5 * p.mass;
        if (p.y > (shareRef.value as HTMLElement).offsetTop * 2) {
            p.remove();
            particles.splice(i, 1);
        }
    }
    requestAnimationFrame(init);
};

const colors = ['#eb6383', '#fa9191', '#ffe9c5', '#b4f2e1'];
const pop = () => {
    for (let i = 0; i < 150; i++) {
        const p = document.createElement('particule') as any;
        // 시작 위치
        p.x = window.innerWidth * 0.5;
        p.y = (shareRef.value as HTMLElement).offsetTop + Math.random() * window.innerHeight * 0.3;
        // 속도 ?
        p.vel = {
            x: (Math.random() - 0.5) * 10,
            y: Math.random() * -20 - 15,
        };
        p.mass = Math.random() * 0.2 + 0.8;
        particles.push(p);
        p.style.transform = `translate(${p.x}px, ${p.y}px)`;
        const size = Math.random() * 15 + 5;
        p.style.width = size + 'px';
        p.style.height = size + 'px';
        p.style.background = colors[Math.floor(Math.random() * colors.length)];
        document.body.appendChild(p);
    }
    init();
};

🎢 To Be Continued..

소소한 애니메이션 효과들을 채워넣으니 만족스럽네요.
지속적으로 운영해나가면서 재미난 요소들로 채워나가야지!

끝까지 읽어주셔서 감사합니다.

0분 동안 운영중...

Copyright © 2023, All right reserved.