AI 摘要

这篇文章记录了作者自制「困ります」按钮的过程,使用Astro框架开发,强调环保和节能。文章详细描述了技术选型、浏览器适配问题、音频处理、用户体验优化等方面的挑战与解决方案,最终实现了一个小巧且功能完整的Web应用,并探讨了未来的项目计划。

引子

最近刷小红书的时候老是看到这个。正好雪先生@yuki 去日本现充,就拜托他去DAISO看看有没有机会碰到。然而雪先生去的DAISO都没有...

然后一天晚上(11点半)雪先生给我发这个照片:

给你图 你看看来做个适配手机的
非常环保减塑

那既然都这么说了,为了地球母亲!开干!

技术选型很简单。既然要节能减排,那么就将它贯彻到底,在保障开发体验的前提下怎么小怎么来。自然动辄几百K包体的React是不必考虑了,于是选用了最近也在学习的Astro。在三小时的激爽爆肝后,请看!传输大小仅7.7kB的绝赞第一版!(所有阶段展示都是部署在Vercel上的大陆不一定打得开请见谅)

作为POC,这一版的语音试着调用了TTS API。TTS虽然是最省空间的方案,但由于各操作系统与浏览器的实现不一样,效果不能得到保证,例如在Chrome Windows实测正常的语音到Safari上语速会变得超级快(spoiler alert,这只是个开始)

所以后面用了雪先生不知道从哪整来的生成语音,挂Web Audio API小整了一些特效,只是音频文件是真的大,光这几秒钟就要14k。另外空出手来在整体的还原度方面做了些微小的工作:怎么让人觉得这个铃很还原呢?除了各个组件的比例都尽量贴合现实,还有就是这块亮光的玻璃最好能尽可能真实。这块走了个模拟现实的情况的思路:让光线穿过红色的玻璃。在调整颜色混合后,做出来还挺像那么一回事的。请看,第二版:

那么这就成了!吗?当我打开Firefox后傻眼了,这黑圈圈是从哪来的啊?

Firefox下中心的发光元素产生的奇怪黑圈
Firefox下中心的发光元素产生的奇怪黑圈

浏览器适配:本当に困ります!!!

debug了下发现相关问题是filtermix-blend-mode共同导致的,并且问题会随着blur size变化,直至在特定的值下消失,十分神奇。尝试了一些别的方式不好解决,filter要用来模糊光源也不得不加(其实现在想想或许可以用svg filter来试试)所以最后的解决方案就是在效果和bug之间找一个均衡的点。

更多的时间是在解决iOS上的体验问题。毕竟Firefox还可以说用的人太少不适配,Safari可是绕不过的。尤其有些问题实在太weird,气得我修bug的时候狂按按钮。

苹果特色AudioContext: 播音频不播开头部分

别家是音频源有多长,就播多长,然而有且仅有Safari会很神秘地跳过音频的开头部分。找了网上没看到好的解决方案,包括调整latencyHint和currentTime都不大行,还好裁切音频能解决。(顺带也是减少体积了

缩放控制:杜绝点着点着放大了

移动Web App控制缩放是题中之义了。当你要做一个需要支持反复点击的按钮的时候,双击放大这些不必要的手势操作就得禁一禁了。按照相关规范,viewport自然要填,但是感觉现在浏览器基本不care这个值,手势操作还得从阻止手势操作的角度下手去处理。还好preventDefault()还是被支持的。

长按怎么呼出放大镜了:按钮到底该用什么元素?

经常写网页的朋友都知道,虽然很多元素都可以用<div><span>替代,但是为了满足语义化的要求,专元素专用会更好。所以一开始点按区域我设置的是<button>。但是Safari上,<button>长按后会有一个黑边,并且似乎不是:focus或者:focus-visible附加的样式(或者只是我没找到,反正没去用调试器看)。被迫换到<div>后发现,虽然黑边是没有了,但是即使user-select设为了none,长按后依然会显示选中区域的放大镜。这个其实还能忍,不能忍的是松手后,屏幕上会出现一个消不掉的共享按钮。最后解决方案很神奇,思路是想了下一个<div><button>会相差在哪里,想到role是肯定会不一样的。于是给<div>加上个role="switch"后就没有这个问题了。这样来看,Safari iOS这样的移动平台中ARIA可能会起着更大的作用。

进阶:改用pointerdown

刚开始的时候按钮的监听事件用的是click事件。毕竟按钮就是click click的东西嘛,没啥毛病。但是反复观看「困ります」ボタン实物演示以后,发现它的触发时机实际上是按下的时候,而不是弹起的时候。所以使用click实现时,手感会不大还原。于是切换到了触摸和鼠标通吃的pointer事件组。由于我们的音效本身就是用AudioContext去播放的,时间操控上没有什么问题,重叠也可以上效果器处理,所以不用太在意。按着按着发现,还是少点什么。再反复观看视频发现,除去标志性的「困ります」语音,按钮本身的咔哒声也很大,也是声觉印象的重要部分。于是找了个塑料按钮的咔哒声,分别接到downup上,好,爽到了!

可惜Safari不打算支持震动API,不然高低还得做个震动进去(

进阶:可以HDR吗?

怎么把按钮做的更真一点呢?首先想到的是按钮的红光能不能更亮一些,更像是一颗LED。那么要让设备显示的更亮,就得请出HDR。想起之前在B站有看到这个视频:

看到这个视频的时候超惊讶。虽然在苹果把HDR屏幕大面积地搬上自家产品后,拥有可以观看HDR内容的设备的用户越来越多,但是一直以来很多软件的支持做的不好。n年没有更新的QQ空间就不多说了,图像的色彩空间支持都还没做。怎么广告还更先用上HDR了?

那时我还以为CSS HDR实装了,查了一下发现截止目前,Web各个标准的HDR支持都仍处于草案阶段。那毕竟广色域的标准也才搞出来不久,HDR估计还要些时间吧。

也测试了一下使用sRGB以外的颜色能不能触发HDR,似乎是不行。毕竟宽色域和HDR应该也不是相等的概念。不过写的时候顺带给几个颜色指定了宽色域的版本,这样在支持P3显示的设备上会更鲜艳一些。顺带一提,现在似乎有用LCH指定颜色的风潮,例如daisyUI,不仅在宽色域设备上颜色表现会更鲜艳,制作的渐变的过渡也可能会更自然。不过lch()是2023年才进stable的新功能,要支持老设备的话估计得加上@support

看了那个B站视频评论区的小伙伴肯定已经发现了诀窍:给元素加brightness。似乎是这个filter在Safari上会有独特的解释,会显示出比当前屏幕显示的白色更白的白。看翻拍的效果很惊艳,在自己的设备上跑的时候,虽然能看出区别,但还是没有真正的HDR照片的那种感觉。不过现在HDR工作流也一团糟就是。

网上也有个示例:比白更白。所以我想,既然示例给了个10,那我给100岂不是亮爆了?也不是。实测效果没啥区别,但是调太高(调到了100)在特定的Safari版本上会变成白色(于是作罢

雪先生还提到这版的字不是很真,所以这版还更改了文本的色彩混合方式。调整了后更像是玻璃上的字了。配合新指定的背景色,个人感觉这版看着还是很舒服的。

以上就是这次自制「困ります」ボタン的全部内容啦!感谢阅读。

进阶:PWA支持

虽然咱们的网页受益于78.3k 9个资源的超小体积,本身加载速度就已经很快了(153ms load completed!),但是如果你碰巧必须呆在一个没有网的地方,没有别的事情能干,无以抒发自己的情绪呢?所以很贴心地为各位设计了PWA缓存,只需要运行一次整个包体就会缓存在本地。

雪先生操刀的icon设计还致敬了某神秘app图标:(也许以后开坑还原一个)

Vercel居然也会用这个icon有点意思

下一步,JR铃?

其实在做这个Web版的铃之前是打算用单片机来做的。毕竟这东西的结构很简单,只要用3D打印机把外壳全部打出来就好了。还好被拉住了毕竟这个坑可是更大。

另外一个想进行的项目就是JR铃!不过最让我印象深刻的是东京线路的站内大厅时不时的“so mi”的声音。

另外一个想进行的项目就是JR铃!不过最让我印象深刻的是东京线路的站内大厅时不时的“so mi”的声音。

尤其车站没人的时候这个声音真的很酷好吧(pakutaso@すしぱく

顺带推一下这个网站https://hassyaberu.com/rosen/Shinagawa1bansen.html,有很多站点的发车铃!

感觉不会太难,其实就是按按钮播音乐嘛。雪先生建议把线路选择放在侧面。

已经在看ESP32相关的东西了。看看什么时候能做完再水篇文章(笑

封面图像:https://www.bus.or.jp/magazine/17/