반응형

data.js

const main = [
    {
        num: '01',
        title: 'Section1',
        description: '내용 입력하기',
        href: '#article1'
    },
    {
        num: '02',
        title: 'Section2',
        description: '내용 입력하기',
        href: '#article2'
    },
    {
        num: '03',
        title: 'Section3',
        description: '내용 입력하기',
        href: '#article3'
    },
    {
        num: '04',
        title: 'Section4',
        description: '내용 입력하기',
        href: '#article4'
    },
    {
        num: '05',
        title: 'Section5',
        description: '내용 입력하기',
        href: '#article5'
    },
    {
        num: '06',
        title: 'Section6',
        description: '내용 입력하기',
        href: '#article6'
    },
    {
        num: '07',
        title: 'Section7',
        description: '내용 입력하기',
        href: '#article7'
    },
    {
        num: '08',
        title: 'Section8',
        description: '내용 입력하기',
        href: '#article8'
    },
    {
        num: '09',
        title: 'Section9',
        description: '내용 입력하기',
        href: '#article9'
    },
];

export default main

 

 

View.vue ( views )

<script setup>
import Header from '@components/Main/Header.vue'
import main from '@/assets/js/data.js'

</script>

<template>

    <Header />
    
    <section id="parallax_contents">
        <article :id="'article' + (index + 1)" class="content_item" v-for="(item, index) of main" :key="'a' + index">
            <span class="content_item_num">{{item.num}}</span>
            <h2 class="content_item_title">{{item.title}}</h2>
            <figure class="content_item_img_wrap">
                <div class="content_item_img"></div>
            </figure>
            <p class="content_item_description">{{item.description}}</p>
        </article>
        <!-- // article1 -->
    </section>
</template>

<style lang="scss" scoped>
    #parallax_contents {
        width: 100%;
        max-width: 1600px;
        margin: 0 auto;
        overflow: hidden;
        font-family: 'NEXONLv1Gothic';
        font-weight: 400;
    }
    .content_item {
        position: relative;
        width: 100%;
        max-width: 70vw;
        margin: 10vw 0;
        text-align: right;
        padding-top: 10vw;
        &:nth-child(even) {
            margin-left: auto;
            text-align: left;
            .content_item_num {
                right: auto;
                left: -5vw;
            }
            .content_item_description {
                margin-right: 0;
                margin-left: -3vw;
            }
        }
        &:nth-child(1) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
        &:nth-child(2) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
        &:nth-child(3) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
        &:nth-child(4) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
        &:nth-child(5) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
        &:nth-child(6) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
        &:nth-child(7) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
        &:nth-child(8) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
        &:nth-child(9) .content_item_img {
            background-image: url(https://images.unsplash.com/photo-1653559260394-ee10e61e0155?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=764&q=80);
        }
    }
    .content_item_num {
        position: absolute;
        font-size: 25vw;
        font-family: 'Lato';
        opacity: 0.07;
        right: -5vw;
        top: -5vw;
    }
    .content_item_title {
        padding-bottom: 1vw;
        font-size: 2vw;
    }
    .content_item_img_wrap {
        position: relative;
        width: 100%;
        padding-bottom: 56%;
        background-color: #000;
    }
    .content_item_img {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-repeat: no-repeat;
        background-size: cover;
        filter: saturate(0%);
        transition: all 1s;
        &:hover {
            filter: saturate(100%);
        }
    }
    .content_item_description {
        position: relative;
        font-size: 4vw;
        line-height: 1.5;
        word-break: keep-all;
        margin-top: -6vw;
        margin-right: -3vw;
        z-index: 1;
    }
</style>

 

Header.vue ( component )

<script setup>
import main from '@/assets/js/data.js'

</script>
<template>
    <nav class="parallax_nav">
        <ul>
            <li v-for="(item, index) of main" :key="'a' + index" ><a :href="item.href" v-smooth-scroll>{{item.num}}</a></li>
        </ul>
    </nav>
</template>

<style lang="scss" scoped>
    a {
        text-decoration: none;
        color: #FFF;
    }
    .parallax_nav {
        position: fixed;
        top: 0;
        right: 0;
        width: 100%;
        overflow: hidden;
        transition: all 1s;
        z-index: 100;
        > ul {
            position: relative;
            top: 0px;
            transition: all 1s;
            display: flex;
            padding: 20px;
            background-color: #D2D2D2;
            > li {
                width: 40px;
                height: 40px;
                line-height: 40px;
                text-align: center;
                border-radius: 50%;
                margin-right: 10px;
                font-size: 16px;
                font-weight: 700;
            }
            .active { background-color: #FFF; a { color: #222; } }
        }
        .list_active { top: 0px; }
    }
    .hide {
        top: -100px;
    }
</style>

<script>
    export default {
        mounted() {
            window.addEventListener("scroll", scrollProgress);
        }
    }


    let nowScrollTop;
    let lastScrollTop = 0;

    function scrollProgress(){
        nowScrollTop = true;

        setTimeout(() => {
            if(nowScrollTop) {
                nowScrollTop = false;
                hasScroll();
            }
        }, 100);
    }

    function hasScroll() {
        let scrollTop = document.documentElement.scrollTop || window.scrollY || window.pageYOffset;

        if(scrollTop > lastScrollTop){
            document.querySelector(".parallax_nav").classList.add("hide");
        } else {
            document.querySelector(".parallax_nav").classList.remove("hide");
        }

        lastScrollTop = scrollTop;

    };

    
</script>

 

반응형

+ Recent posts