近日,一前端大神sh1zuku用react刻出乙個 windows xp,頁面中的兩個windows xp視窗可以自由拖曳,而且作者還製作了乙個踩地雷的遊戲,可以直接上手玩。作者也將這些實現的過程在medium上記錄了下來,以下全文就是infoq對其內容的整理。
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: resize;系列是不可或缺的,然而單純的 :hover 會在快速伸縮時因為超過元素範圍讓 cursor 變回 default,想了很久以後他決定蓋乙個全版 div,讓 cursor 怎麼滑都保持 resize!
在這裡,作者最後的寫法是遍歷乙個 json 檔,產生相應的目錄結構,但較麻煩的是為了符合 xp 的行為,需要自己控制選單反白的狀態。
每個下拉列表都有四欄,中間的兩欄(選項名稱和快捷鍵)長度不固定,且內容要對齊該欄左側,作者在這裡選用grid來解決:
display: grid;grid-template-columns: 16px auto auto 15px;
但後來發現 hover 時需要反藍整列,就用了 display: contents 這個屬性,作用是包住內容(一整列)但不影響 layout(欄的對齊),如此一來就能輕鬆設定整列樣式了。
為了完全模擬踩地雷的行為,將 mouse event 的 button 和 buttons 屬性組合了一下才完成,複雜的狀態則使用 usereducer 來管理。
mouseevent.button 代表觸發事件的按鍵(1 左鍵 2 右鍵)
mouseevent.buttons 代表觸發事件時按鍵的狀態(1 左鍵 2 右鍵 3 雙鍵)
手機版:
開啟關機選單時,為了讓全版畫面變成灰階但保持目錄的顏色,sh1zuku使用了 portal,讓選單 render 時可以插入特定的 dom 位置又保持事件溝通,時常用在突破 overflow: hidden; 限制。
sh1zuku還分享了一些其他細節:
多個 box shadow 會由前到後覆蓋,如下,影子會是黑色:
.dot
選單使用 filter: invert(100%) 轉負片,看到的藍色其實原本是橘色:
.container
用 user select: none、pointer event: none 防止拖曳事件受到影響。
在這個過程中為了完全符合 xp 視覺,sh1zuku不斷微調 layout 和顏色,也花了很多時間在圖示上,其實有許多次「到此為止吧」的念頭。不過也理清了他自己在 layout 的錯誤觀念,且只要發現跟原生 xp 不同的地方,不改完就覺得渾身不對勁,為此他還特地裝了 xp 虛擬機器 xd。
參考鏈結
更多鏈結
github:
用-react-刻-xp-一路上的點點滴滴-7440e8bc9b73
前端大神用React刻了乙個Windows XP
近日,一前端大神sh1zuku用react刻出乙個 windows xp,頁面中的兩個windows xp視窗可以自由拖曳,而且作者還製作了乙個踩地雷的遊戲,可以直接上手玩。作者也將這些實現的過程在medium上記錄了下來,以下全文就是infoq對其內容的整理。n n n sh1zuku表示,他原本...
前端大神用React刻了乙個Windows XP
近日,一前端大神sh1zuku用react刻出乙個 windows xp,頁面中的兩個windows xp視窗可以自由拖曳,而且作者還製作了乙個踩地雷的遊戲,可以直接上手玩。作者也將這些實現的過程在medium上記錄了下來,以下全文就是infoq對其內容的整理。sh1zuku表示,他原本是以 van...
前端大神用React刻了乙個Windows XP
近日,一前端大神sh1zuku用react刻出乙個 windows xp,頁面中的兩個windows xp視窗可以自由拖曳,而且作者還製作了乙個踩地雷的遊戲,可以直接上手玩。作者也將這些實現的過程在medium上記錄了下來,以下全文就是infoq對其內容的整理。sh1zuku表示,他原本是以 van...