是誰,在敲打我窗-CSS雨滴動畫效果

一、扯閒篇

是誰在敲打我窗  是誰在撩動琴絃  那一段被遺忘的時光css

漸漸地回升出我心坎  是誰在敲打我窗  是誰在撩動琴絃html

記憶中那歡樂的情景  慢慢地浮如今個人腦海git

那緩緩飄落的小雨  不停地打在我窗  只有那沉默不語的我github

不時地回想過去  是誰在敲打我窗  是誰在撩動琴絃框架

記憶中那歡樂的情景  慢慢地浮如今個人腦海性能

那緩緩飄落的小雨  不停地打在我窗  只有那沉默不語的我動畫

不時地回想過去  是誰在敲打我窗  是誰在撩動琴絃url

記憶中那歡樂的情景  慢慢地浮如今個人腦海spa

記憶中那歡樂的情景  慢慢地浮如今個人腦海.net

「是誰,在敲打我窗」這句歌詞是出自蔡琴所演唱的《被遺忘的時光》,提及蔡琴,真是個暴露年齡的事。當年我仍是青蔥少年的時候,看過蔡琴那時老公導的一部電影,我清楚的記得那天是晚上10點半,我打算看完12點睡覺的,結果這部電影長達4個小時,我看完的時候已是凌晨三點了,我當時很後悔爲啥看以前沒先看下電影時長。但這部電影能夠說是臺灣電影中最好的幾部之一,《牯嶺街少年殺人事件》,導演是楊德昌,順便提一句,主演是張震。

----------------------------扯完閒篇的分割線-------------------------------------------------------------------------

二、玻璃窗

今天咱們要實現的是雨滴效果,不過實現雨滴前,咱們先把毛玻璃的效果弄出來,沒有玻璃窗,雨都進屋了,還有啥好敲打的。

<div class='window'></div>
.window {
            position: absolute;
            width: 100vw;
            height: 100vh;
            background: url("https://cn.bing.com//th?id=OHR.ParrotsIndia_ZH-CN8386276023_UHD.jpg");
            background-size: cover;
            background-position: 100%;
            filter: blur(10px);
        }

其實就是給一張圖片,作了個模糊化的效果,看起來像毛玻璃的效果

三、一滴雨

雨滴的效果就很巧妙了,讓咱們看下一滴雨完整的效果圖

這滴雨其實分爲兩個部分,第一部分是底部的陰影部分,實際上是個邊框來的,代碼以下:

.border {
            position: absolute;
            margin-left: 92px;
            margin-top: 51px;
            border-radius: 100%;
            box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.6);
            transform: rotateY(0);
            width: 20px;
            height: 28px;
        }
<div class='border'></div>

經過width和height屬性和border-radius把border拉成一個橢圓形,而後用box-shadow把陰影拉出來,做爲水滴的陰影,邊框的最終效果以下:

而後是水滴的部分

.raindrop {
            filter: brightness(1.2);
            position: absolute;
            margin-left: 90px;
            margin-top: 50px;
            background-size: 5vw 5vh;
            border-radius: 100%;
            background-image: url("https://cn.bing.com//th?id=OHR.ParrotsIndia_ZH-CN8386276023_UHD.jpg");
            transform: rotate(180deg) rotateY(0);
            background-position: 48.1994160428% 54.3259834959%;
            width: 24px;
            height: 28px;
        }
<div class='raindrop'></div>
  • 水滴用background-image設置了玻璃的圖片做爲倒影,倒影之因此是倒影,是由於影子是倒着的,因此用transform的rotate()旋轉了圖片180,正好倒過來
  • 經過background-position設置圖片在水滴的顯示的位置,後面不一樣的水滴會顯示出的倒影由於圖片位置的變化都不一樣,顯得真實
  • raindrop的width比border的width多幾個像素,是爲了讓水滴的兩邊蓋住border,只留border的上下顯示陰影
  • raindrop的margin-left和margin-top和border的也是略有不一樣,是爲了raindrop能居中覆蓋在border上面,使得水滴和陰影融合的更真實

單獨無陰影的水滴效果以下:

四、隨機雨滴

雨歷來都不是一滴一滴來的,並且也不會頗有規律的來,爲了讓雨滴隨機出如今玻璃窗上,我請出了《基努·裏維斯、css-doodle、黑客帝國字幕雨和隨機藝術》用到過的大殺器,css-doodle框架。

<css-doodle use="var(--rule)"></css-doodle>

先建立一個css-doodle的自定義組件

--rule: ( :doodle {
                    @grid: 10x10/ 100%;
                    overflow: visible;
                }

打出10*10個grid,這樣最多能夠出現100滴雨

transform: scale(@rand(.5, .9));

經過transform:scale讓雨滴隨機變大變小

:before {
                        content: '';
                        position: absolute;
                        margin-left: @var(--mleft);
                        margin-top: @var(--mtopb);
                        border-radius: 100%;
                        box-shadow: 0 0 0 @var(--shadow-size) rgba(0, 0, 0, 0.6);
                        transform: rotateY(0);
                        width: @var(--widthb);
                        height: @var(--height);
                    }

                    :after {
                        content: '';
                        filter: brightness(1.2);
                        position: absolute;
                        margin-left: @var(--mleft);
                        margin-top: @var(--mtopa);
                        background-size: 5vw 5vh;
                        border-radius: 100%;
                        background-image: url("https://cn.bing.com//th?id=OHR.ParrotsIndia_ZH-CN8386276023_UHD.jpg");
                        transform: rotate(180deg) rotateY(0);
                        background-position: @r(1%, 100%) @r(1%, 100%);
                        width: @var(--widtha);
                        height: @var(--height);

                    }
  • 這裏的:before和:after你們看的是否是很眼熟,其實:before裏面的內容就是前面border的樣式,:after裏面的就是前面raindrop的樣式。
  • content必需要有,由於在僞元素(before,after)裏若是沒有設置「content」屬性,僞元素是無用的,整個:before和:after裏面的配置就都無效了。
  • 爲了讓雨滴顯得更清晰,加了filter: brightness(1.2)讓雨滴顯得更亮一些。

這裏面比較奇怪的是@var(),它其實就是css的變量,在css-doodle作了一層包裝,做用和css的var()是同樣的,咱們看下這些變量的定義

--size:(4 + @r(1, 8));
                    --shadow-size: calc(((@var(--size)*0.3) - 1)*1px);
                    --mleft:@r(1, 100)px;
                    --mtop:@r(1, 100);
                    --mtop1:(@var(--mtop) - 1);
                    --mtopb:calc(@var(--mtop)*1px);
                    --mtopa:calc(@var(--mtop1)*1px);
                    --height:@r(15, 25)px;
                    --width:@r(8, 20);
                    --width1:(@var(--width) + 5);
                    --widthb:calc(@var(--width)*1px);
                    --widtha:calc(@var(--width1)*1px);

這裏有幾個坑要說明一下:

  • 1號坑:css-doodle提供了@calc(),可是這裏計算仍是要用css的calc(),使用@calc()無效。
  • 2號坑:在使用@var作加減法的時候,+-號的兩遍要有空格,不然計算無效,切記切記。
  • 3號不是坑:計算好數值後,怎麼帶上px單位呢,用calc(value*1px)這種方法就能夠了,其餘的單位也能夠用這種方法。
  • 4號說明:爲何要用變量?是由於before和after不在一塊兒,爲了讓boder和raindrop的margin-left、margin-top、width、height等屬性可以保持一致,就須要用變量在before和after外面定義好,傳值到裏面去。

最終的效果以下:

五、沒動畫效果怎麼敲打我窗

雨點若是隻是這樣灑在窗戶,那就沒有敲打的意思,爲了體現敲打,我決定讓雨點動起來。

:before {
                        content: '';
                        position: absolute;
                        margin-left: @var(--mleft);
                        margin-top: @var(--mtopb);
                        border-radius: 100%;
                        box-shadow: 0 0 0 @var(--shadow-size) rgba(0, 0, 0, 0.6);
                        transform: rotateY(0);
                        width: @var(--widthb);
                        height: @var(--height);
                        opacity: 0;
                        animation: raindrop-fall 500ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
                        animation-fill-mode: forwards;
                        animation-delay: @var(--delay);
                    }

                    :after {
                        content: '';
                        filter: brightness(1.2);
                        position: absolute;
                        margin-left: @var(--mleft);
                        margin-top: @var(--mtopa);
                        background-size: 5vw 5vh;
                        border-radius: 100%;
                        background-image: url("https://cn.bing.com//th?id=OHR.ParrotsIndia_ZH-CN8386276023_UHD.jpg");
                        transform: rotate(180deg) rotateY(0);
                        background-position: @r(1%, 100%) @r(1%, 100%);
                        width: @var(--widtha);
                        height: @var(--height);
                        opacity: 0;
                        animation: raindrop-fall 500ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
                        animation-fill-mode: forwards;
                        animation-delay: @var(--delay);
                    }

重點是:before和:after裏面的最後三行,是用來實現動畫效果的。

  • cubic-bezier()控制動畫的速度,使得雨滴落到玻璃窗的效果更逼真
  • animation-delay 雨點出現的時間隨機,一樣是爲了效果更逼真,逼真的效果然麻煩

再來看看raindrop-fall的@keyframe設置

@keyframes raindrop-fall {
                    0% {
                        opacity: 0;
                        transform: rotate(180deg) scale(2.5, 2.3) rotateY(0);
                    }

                    100% {
                        opacity: 1;
                        transform: rotate(180deg) scale(1, 1) rotateY(0);
                    }
                }

最後的動畫效果以下:

在線效果

源代碼地址

番外篇

阿愷:是誰,在敲打我窗~

媽媽:有誰來了嗎

阿愷:沒有,是下雨

媽媽:不像啊,好像是有人在敲窗戶

阿愷:是很大的雨點而已,是誰,在敲打我窗~

窗外的聲音:開門,敲了半天都沒人理

阿愷:你是誰

窗外的聲音:查水錶的...

阿愷:爲何不敲門?

窗外的聲音:門口堆滿了東風快遞...

相關文章
相關標籤/搜索