出处前端之巅 近日,一前端大神sh1zuku用React刻出一個WindowsXP,页面中的两个WindowsXP窗口可以自由拖曳,而且作者还制作了一个踩地雷的游戏,可以直接上手玩。作者也将这些实现的过程在medium上记录了下来,以下全文就是InfoQ对其内容的整理。 想玩的同学,可点这个链接一试: https:winxp。now。sh从纯JS转至React sh1zuku表示,他原本是以vanillaJS写整个project的,但不得不说Parcel真的很强大,一键开始Pug,SCSS,Babel,HMR环境,马上就能进入开发模式。少了框架的帮忙,他必须手刻PWA,SPA,Codesplitting和Routing,所以。最后他决心将整个专案用React重写,但后来分离至另外一个repo了。元素拖曳、伸缩 作者一开始决定从XP视窗的拖曳以及伸缩着手,期间经历了getBoundingClientRect的left、top以及mousemove的(clientX,offsetX,pageX,screenX)各种折磨,才让他真正了解其中的区别,最后他做的是不受scroll影响的元素拖曳和伸缩。抖动的Cursor 在元素伸缩时,加入cursor:系列是不可或缺的,然而单纯的:hover会在快速伸缩时因为超过元素范围让cursor变回default,想了很久以后他决定盖一个全版p,让cursor怎麼滑都保持resize! 无限延伸子目录 在这里,作者最后的写法是遍历一个JSON档,产生相应的目录结构,但较麻烦的是为了符合XP的行为,需要自己控制选单反白的状态。 Grid栏位对齐 每个下拉选单都有四栏,中间的两栏(选项名称和快捷键)长度不固定,且内容要对齐该栏左侧,作者在这里选用grid来解决: 复制代码display: gridtemplatecolumns:16pxautoauto15 但后来发现hover时需要反蓝整列,就用了display:contents这个属性,作用是包住内容(一整列)但不影响layout(栏的对齐),如此一来就能轻松设定整列样式了。 踩地雷 為了完全模拟踩地雷的行为,将mouseevent的button和buttons属性组合了一下才完成,复杂的状态则使用useReducer来管理。 MouseEvent。button代表触发事件的按键(1左键2右键) MouseEvent。buttons代表触发事件时按键的状态(1左键2右键3双键) 手机版:https:github。comShizukuIchiminesweeper图片反蓝 為了让图片变蓝,作者一开始用了这种方式: 复制代码。img{ filter:huerotate(170deg)brightness(60)saturate(300); } 网站中使用了许多好用的filter属性,只有这个比较诡异,色相旋转、亮度还有饱和度的组合还真的让图片变蓝了。最后反蓝的的方式是给parent蓝色影子、让图案透明,达到变蓝的效果: 复制代码。container{ filter:dropshadow(00blue); } 。img{ opacity:0。5; } ReactDom。createPortal 打开关机菜单时,为了让全版画面变成灰阶但保持目录的颜色,sh1zuku使用了portal,让选单render时可以插入特定的DOM位置又保持事件沟通,时常用在突破overflow:限制。 其他 sh1zuku还分享了一些其他细节: 多个boxshadow会由前到后覆盖,如下,影子会是黑色: 复制代码。dot{ boxshadow:00black,00white,00 } 选单使用filter:invert(100)转负片,看到的蓝色其实原本是橘色: 复制代码。container{ background:e99f17;橘色 filter:invert(100); } 用userselect:none、pointerevent:none防止拖曳事件受到影响。后记 在这个过程中为了完全符合XP视觉,sh1zuku不断微调layout和颜色,也花了很多时间在图示上,其实有许多次到此为止吧的念头。不过也理清了他自己在layout的错误观念,且只要发现跟原生XP不同的地方,不改完就觉得浑身不对劲,为此他还特地装了XP虚拟机XD。 参考链接https:bitsofco。dehowdisplaycontentsworkshttp:www。colorzilla。comgradienteditorhttps:developer。mozilla。orgenUSdocsWebAPIMouseEventbuttons 更多链接 GitHub:https:github。comShizukuIchiwinXP 演示链链接:https:winxp。now。sh