JavaScript+css 实现点击放大缩小效果

70 阅读1分钟

前几天有个需求是打开弹层时,弹层要在模块点击处逐渐放大到屏幕中心,弹层关闭时再逐渐缩小至对应模块的位置。

html:

<div class="box">
    <div id="js_video" class="video"></div>

    <div id="js_1" class="item item_1"></div>
    <div id="js_2" class="item item_2"></div>
    <div id="js_3" class="item item_3"></div>
    <div id="js_4" class="item item_4"></div>
</div>

css:

:root {
    --top: 10%;
    --left: 10%;
}

* {
    margin: 0;
    padding: 0;
}

.box {
    position: relative;
    width: 100vw;
    height: 100vh;
    background: linear-gradient(180deg, #071328, rgba(3, 8, 18, 0.50));
}

.video {
    display: none;
    position: absolute;
    width: 10px;
    height: 10px;
    transform: translate(-50%, -50%);
    background-color: rgb(255, 0, 166);
    cursor: pointer;
}

.item {
    position: absolute;
    width: 80px;
    height: 80px;
    background-color: #f60;
    cursor: pointer;
}

.item_1 {
    top: 10%;
    left: 10%;
}

.item_2 {
    top: 10%;
    left: calc(100% - 10%);
}

.item_3 {
    top: calc(100% - 10%);
    left: 10%;
}

.item_4 {
    top: calc(100% - 10%);
    left: calc(100% - 10%);
}

.apply-show {
    display: block;
    animation-name: show;
    animation-duration: 3s;
    animation-fill-mode: forwards;
}

.apply-hide {
    display: block;
    animation-name: hide;
    animation-duration: 3s;
    animation-fill-mode: forwards;
}

@keyframes show {
    0% {
        transform: scale(1);
        top: var(--top);
        left: var(--left);
    }

    100% {
        transform: scale(2);
        top: 50%;
        left: 50%;
    }
}

@keyframes hide {
    0% {
        transform: scale(2);
        top: 50%;
        left: 50%;
    }

    100% {
        transform: scale(1);
        top: var(--top);
        left: var(--left);
    }
}

javascipt:

const HOT_ZONE = {
    1: {
        top: '10%',
        left: '10%',
    },
    2: {
        top: '10%',
        left: 'calc(100% - 10%)',
    },
    3: {
        top: 'calc(100% - 10%)',
        left: '10%',
    },
    4: {
        top: 'calc(100% - 10%)',
        left: 'calc(100% - 10%)',
    }
}
const video = document.getElementById('js_video');

let current = 0;

const removeClassName = () => {
    if (current) {
        video.classList.remove('apply-show');
        video.classList.remove('apply-hide');
    }
};

const addClassName = (calssName) => {
    video.classList.add(calssName);
};

Array(4).fill(1).forEach((_, index) => {
    const hotZone = document.getElementById(`js_${index + 1}`);
    hotZone.onclick = () => {
        removeClassName();

        current = index + 1;
        document.documentElement.style.setProperty('--top', HOT_ZONE[current].top);
        document.documentElement.style.setProperty('--left', HOT_ZONE[current].left);

        setTimeout(() => {
            addClassName('apply-show');
        }, 8);
    };
});

video.onclick = () => {
    current = 0;
    removeClassName();
    addClassName('apply-hide');
};