深浅色切换的圆环扩散原本把圆心写死在 window.innerWidth / 2,不管点哪儿都从屏幕 正中冒出来。改成取指针落点。 半径也跟着修了。原来是 hypot(x, y),只量到左上角——圆心居中时恰好是对的,一挪到 按钮(在右上角)就不够长了,右下角会留一大块旧配色等圆环扩过去,看着像没刷新。 现在取到最远那个角的距离。 键盘触发(Enter / 空格)时 clientX/clientY 是 0,照用会让圆环从屏幕左上角冒出来, 这种情况退回按钮自身中心,用 event.detail === 0 判断。 startViewTransition 的降级判断原样保留,机房那批 Chrome 低于 94 仍然是直接切。 实测(钩住 documentElement.animate 看真实关键帧,视口 1280x633、按钮中心 1255,29): 点正中得 circle at 1255px 29px / r=1392.78,点按钮左上角 (1246,22) 得 at 1246px 22px, 说明跟的是指针不是按钮;键盘 Enter 得 at 1255px 29px,没跑到 (0,0)。三次主题都正确 翻转,无报错。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,14 +22,30 @@ const { learnStep } = useLearnProgress()
|
|||||||
|
|
||||||
const isDark = useDark()
|
const isDark = useDark()
|
||||||
|
|
||||||
function toggleDark() {
|
/**
|
||||||
const x = window.innerWidth / 2
|
* 圆环从哪儿开始扩散。正常点击就用指针落点;键盘触发(Enter / 空格)时浏览器给的
|
||||||
const y = window.innerHeight / 2
|
* clientX/clientY 是 0,照用会让圆环从屏幕左上角冒出来——那种情况退回按钮自己的中心。
|
||||||
const radius = Math.hypot(x, y)
|
* `event.detail` 是点击次数,键盘触发时为 0,用它区分最省事。
|
||||||
|
*/
|
||||||
|
function revealOrigin(event: MouseEvent) {
|
||||||
|
if (event.detail > 0) return { x: event.clientX, y: event.clientY }
|
||||||
|
const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()
|
||||||
|
return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleDark(event: MouseEvent) {
|
||||||
if (!document.startViewTransition) {
|
if (!document.startViewTransition) {
|
||||||
|
// 机房那批 Chrome 低于 94,没有 View Transitions,直接切、不做动画。
|
||||||
isDark.value = !isDark.value
|
isDark.value = !isDark.value
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const { x, y } = revealOrigin(event)
|
||||||
|
// 半径要取到**最远**那个角的距离。用 hypot(x, y) 只覆盖到左上角,
|
||||||
|
// 点在偏左上时右下角会有一块旧画面等圆环扩过去,看着像是没刷新。
|
||||||
|
const radius = Math.hypot(
|
||||||
|
Math.max(x, window.innerWidth - x),
|
||||||
|
Math.max(y, window.innerHeight - y),
|
||||||
|
)
|
||||||
document
|
document
|
||||||
.startViewTransition(() => {
|
.startViewTransition(() => {
|
||||||
isDark.value = !isDark.value
|
isDark.value = !isDark.value
|
||||||
|
|||||||
Reference in New Issue
Block a user