碉堡了!前端大神用 React 刻了一個 Windows XP
近日,一前端大神 sh1zuku 用 React 刻出一個 Windows XP,頁面中的兩個 Windows XP 視窗可以自由拖曳,而且作者還製作了一個踩地雷的遊戲,可以直接上手玩,超酷!作者也將這些實現的過程在 medium 上記錄了下來,以下全文就是前端之巔對其內容的整理。
想玩的同學,可點這個連結一試:
從純 JS 轉至 React
sh1zuku 表示,他原本是以 vanilla JS 寫整個 project 的,但不得不說 Parcel 真的很強大,一鍵開始 Pug,SCSS, Babel,HMR 環境,馬上就能進入開發模式。少了框架的幫忙,他必須手刻 PWA,SPA,Code splitting 和 Routing,所以。最後他決心將整個專案用 React 重寫,但後來分離至另外一個 repo 了。
元素拖曳、伸縮
作者一開始決定從 XP 視窗的拖曳以及伸縮著手,期間經歷 了 getBoundingClientRect 的 left、top 以及 mousemove 的( clientX, offsetX,pageX,screenX)各種折磨, 才讓他真正瞭解其中的區別,最後他做的是不受 scroll 影響的元素拖曳和伸縮。
抖動的 Cursor
在元素伸縮時,加入 cursor: resize;系列是不可或缺的,然而單純的 :hover 會在快速伸縮時因為超過元素範圍讓 cursor 變回 default,想了很久以後他決定蓋一個全版 div,讓 cursor 怎麼滑都保持 resize!
無限延伸子目錄
在這裡,作者最後的寫法是遍歷一個 JSON 檔,產生相應的目錄結構,但較麻煩的是為了符合 XP 的行為,需要自己控制選單反白的狀態。
Grid 欄位對齊
每個下拉選單都有四欄,中間的兩欄(選項名稱和快捷鍵)長度不固定,且內容要對齊該欄左側,作者在這裡選用 grid 來解決:
複製程式碼
display: grid; grid-template-columns:16pxautoauto15px;
但後來發現 hover 時需要反藍整列,就用了 display: contents 這個屬性,作用是包住內容(一整列)但不影響 layout(欄的對齊),如此一來就能輕鬆設定整列樣式了。
踩地雷
為了完全模擬踩地雷的行為,將 mouse event 的 button 和 buttons 屬性組合了一下才完成,複雜的狀態則使用 useReducer 來管理。
MouseEvent.button 代表觸發事件的按鍵(1 左鍵 2 右鍵)
MouseEvent.buttons 代表觸發事件時按鍵的狀態(1 左鍵 2 右鍵 3 雙鍵)
手機版: https://github.com/ShizukuIchi/minesweeper
圖片反藍
為了讓圖片變藍,作者一開始用了這種方式:
複製程式碼
.img{ filter:hue-rotate(170deg)brightness(60%)saturate(300%); }
網站中使用了許多好用的 filter 屬性,只有這個比較詭異,色相旋轉、亮度還有飽和度的組合還真的讓圖片變藍了。最後反藍的的方式是給 parent 藍色影子、讓圖案透明,達到變藍的效果:
複製程式碼
.container{ filter:drop-shadow(0 0 blue); } .img{ opacity:0.5; }
ReactDom.createPortal
開啟關機選單時,為了讓全版畫面變成灰階但保持目錄的顏色,sh1zuku 使用了 portal,讓選單 render 時可以插入特定的 DOM 位置又保持事件溝通,時常用在突破 overflow: hidden; 限制。
其他
sh1zuku 還分享了一些其他細節:
多個 box shadow 會由前到後覆蓋,如下,影子會是黑色:
複製程式碼
.dot { box-shadow:00black,00white,00blue; }
選單使用 filter: invert(100%) 轉負片,看到的藍色其實原本是橘色:
複製程式碼
.container{ background:#e99f17; -> 橘色 filter: invert(100%); }
用 user select: none、pointer event: none 防止拖曳事件受到影響。
後記
在這個過程中為了完全符合 XP 視覺,sh1zuku 不斷微調 layout 和顏色,也花了很多時間在圖示上,其實有許多次「到此為止吧」的念頭。不過也理清了他自己在 layout 的錯誤觀念,且只要發現跟原生 XP 不同的地方,不改完就覺得渾身不對勁,為此他還特地裝了 XP 虛擬機器 XD。
參考連結
更多連結
GitHub: https://github.com/ShizukuIchi/winXP
演示鏈連結: https://winxp.now.sh/
原文連結:
https://medium.com/@shizukuichi/ 用 -react- 刻 -xp- 一路上的點點滴滴 -7440e8bc9b73
更多內容,請關注前端之巔。