55

碉堡了!前端大神用 React 刻了一个 Windows XP

 5 years ago
source link: https://www.infoq.cn/article/sSZjUFhYpfK*vaWKmoJi?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

近日,一前端大神 sh1zuku 用 React 刻出一個 Windows XP,页面中的两个 Windows XP 窗口可以自由拖曳,而且作者还制作了一个踩地雷的游戏,可以直接上手玩,超酷!作者也将这些实现的过程在 medium 上记录了下来,以下全文就是前端之巅对其内容的整理。

想玩的同学,可点这个链接一试:

https://winxp.now.sh/

从纯 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!

b2aQNnj.png!web

无限延伸子目录

在这里,作者最后的写法是遍历一个 JSON 档,产生相应的目录结构,但较麻烦的是为了符合 XP 的行为,需要自己控制选单反白的状态。

EviiqyU.png!web

Grid 栏位对齐

每个下拉选单都有四栏,中间的两栏(选项名称和快捷键)长度不固定,且内容要对齐该栏左侧,作者在这里选用 grid 来解决:

复制代码

display: grid;
grid-template-columns:16pxautoauto15px;

但后来发现 hover 时需要反蓝整列,就用了 display: contents 这个属性,作用是包住内容(一整列)但不影响 layout(栏的对齐),如此一来就能轻松设定整列样式了。

R7vYFnz.png!web

踩地雷

為了完全模拟踩地雷的行为,将 mouse event 的 button 和 buttons 属性组合了一下才完成,复杂的状态则使用 useReducer 来管理。

MouseEvent.button 代表触发事件的按键(1 左键 2 右键)

MouseEvent.buttons 代表触发事件时按键的状态(1 左键 2 右键 3 双键)

eMR7ZfE.png!web

手机版: 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;
}

n6BZfie.png!web

ReactDom.createPortal

打开关机菜单时,为了让全版画面变成灰阶但保持目录的颜色,sh1zuku 使用了 portal,让选单 render 时可以插入特定的 DOM 位置又保持事件沟通,时常用在突破 overflow: hidden; 限制。

rmYBBjF.png!web

其他

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

更多内容,请关注前端之巅。

ZruUrqI.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK