手把手教你實現飛機上的開窗關窗效果

效果圖

前言

接著上個小飛機的效果,在這個動畫的基礎上,用CSS實現的一個在飛機上開窗關窗的效果。整個實現過程比較簡單,大家可以先看到下面的效果預覽部分,十分簡單,沒有花里胡哨的技巧。話不多說,咱們直接進入主題。

效果預覽

最終實現的相關效果如下。
效果預覽

HTML部分

首先我們看到HTML部分,相關代碼如下。

<input type="checkbox" class="toggle">
<figure class="window">
    <div class="curtain"></div>
    <div class="clouds">
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
</figure>

首先創建一個隱藏的複選框輸入元素,用作互動觸發器,通過CSS的:checked偽類實現狀態切換。然後使用<figure>語義化標籤作為窗戶的主要容器,作為窗簾和雲朵背景的父元素,通常通過CSS設置窗戶的邊框、陰影和整體樣式,curtain代表窗戶的窗簾部分,通過CSS實現窗簾的樣式和動畫效果。最後創建了多個<span>元素,每個代表一朵雲。

CSS部分

首先我們看到類名toggle的樣式,相關代碼如下。

.toggle {
    position: absolute;
    filter: opacity(0);
    width: 25em;
    height: 35em;
    font-size: var(--font-size);
    cursor: pointer;
    z-index: 3;
}

這裡定義了一個隱藏但可點擊的切換開關元素。通過視覺隱藏 (filter: opacity(0)),使用濾鏡將元素透明度設為0(完全透明),比opacity: 0visibility: hidden更好的選擇,因為它可以保持元素完全可點擊和可聚焦,不影響佈局(元素仍佔據空間),不會阻止滑鼠事件。

配合CSS選擇器如:checked,可以實現複雜的互動效果而無需JavaScript。

然後是窗戶和窗簾的CSS部分,相關代碼如下。

.toggle:checked ~ .window .curtain {
    top: -90%;
}
.window .curtain::before {
    content: '';
    position: absolute;
    width: 40%;
    height: 0.8em;
    background-color: #808080;
    left: 30%;
    bottom: 1.6em;
    border-radius: 0.4em;
}
.window .curtain::after {
    content: '';
    position: absolute;
    width: 1.6em;
    height: 0.8em;
    bottom: 1.6em;
    background-image: radial-gradient(orange, orangered);
    left: calc((100% - 1.6em) / 2);
    border-radius: 0.4em;
}
.toggle:checked ~ .window .curtain::after {
    background-image: radial-gradient(lightgreen, limegreen);
}

這裡實現了窗簾的互動效果和樣式細節。首先是窗簾開合動畫控制,當複選框被選中時,將窗簾向上移動90%的高度,:checked是匹配被選中的複選框,~是通用兄弟選擇器,選擇.toggle之後的所有.window元素,最終選擇.toggle之後.window內的.curtain元素。

所以最終的動畫效果是當隱藏的複選框被點擊時,窗簾會移動到頂部-90%的位置,實現"打開"效果。

當複選框被選中時,將把手顏色變為綠色漸變,當窗簾打開時,把手顏色從橙紅色變為綠色,提供視覺回饋,表示狀態已改變。

這裡展示了如何通過純CSS創建具有狀態回饋的互動式組件,利用CSS的:checked偽類實現互動,使用::before::after添加裝飾元素,無需額外HTML,通過顏色變化提供狀態指示。

最後是窗外的雲的CSS樣式,相關代碼如下。

.window .clouds {
    position: relative;
    width: 20em;
    height: 30em;
    background-color: deepskyblue;
    left: calc((100% - 20em) / 2);
    top: calc((100% - 30em) / 2);
    border-radius: 7em;
    box-shadow: 0 0 0 0.4em #808080;
    overflow: hidden;
}
.clouds span {
    position: absolute;
    width: 10em;
    height: 4em;
    background-color: white;
    top: 20%;
    border-radius: 4em;
    animation: move 4s linear infinite;
}
@keyframes move {
    from { left: -150%; }
    to { left: 150%; }
}

這裡創建了一個天空背景和飄動的雲朵動畫效果:

精確定位

  • 使用calc()函數實現天空區域的完美居中
  • left: calc((100% - 20em) / 2) 水平居中
  • top: calc((100% - 30em) / 2) 垂直居中

雲朵形狀

  • 通過border-radius: 4em創建椭圓形雲朵
  • 高度(4em)是寬度(10em)的40%,形成扁平椭圓形狀

動畫設計

  • 使用linear線性動畫確保均速移動
  • infinite無限循環創造持續飄動效果
  • 從-150%到150%確保雲朵完全穿過可見區域

視覺層次

  • 天藍色背景與白色雲朵形成鮮明對比
  • 灰色邊框定義天空區域邊界
  • overflow: hidden確保動畫元素不會破壞佈局

這裡創建了一個視覺上吸引人的天空背景,雲朵從左側進入,橫穿天空區域,然後從右側離開,形成連續循環的飄動效果。

總結

以上就是整個效果的實現過程了,代碼簡單易懂。另外,有興趣的小伙伴們還可以在現有基礎上發散思維,比如增加點其他效果,或者更改顏色等等。關於該效果如果大家有更好的想法歡迎在評論區分享,互相學習。最後,完整代碼在碼上掘金裡可以查看,如果有什麼問題大家在評論區裡討論~


原文出處:https://juejin.cn/post/7545489282000060462


共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝11   💬8   ❤️16
518
🥈
我愛JS
📝1   💬5   ❤️4
86
🥉
酷豪
📝1   ❤️1
49
#4
AppleLily
📝1   💬4   ❤️1
37
#5
💬3  
10
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次