Skip to content

Commit 9a52925

Browse files
authored
fix: blurred font (#485)
1 parent b97a942 commit 9a52925

3 files changed

Lines changed: 108 additions & 18 deletions

File tree

packages/devtools/src/runtime/plugins/view/FrameBox.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,11 @@ useEventListener(window, 'mouseleave', () => {
161161

162162
<style scoped>
163163
.nuxt-devtools-frame {
164+
width: 100%;
165+
height: 100%;
164166
position: fixed;
165167
z-index: 2147483645;
168+
-webkit-font-smoothing: antialiased;
166169
}
167170
168171
.nuxt-devtools-frame :deep(iframe) {

packages/devtools/src/runtime/plugins/view/Main.vue

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { CSSProperties } from 'vue'
44
import type { NuxtDevtoolsHostClient } from '../../../types'
55
import { settings } from '../../settings'
66
import { state } from './state'
7-
import { millisecondToHumanreadable, useEventListener, useScreenSafeArea } from './utils'
7+
import { millisecondToHumanreadable, useElementBounding, useEventListener, useScreenSafeArea } from './utils'
88
import FrameBox from './FrameBox.vue'
99
1010
const props = defineProps<{
@@ -47,7 +47,7 @@ const vars = computed(() => {
4747
}
4848
})
4949
50-
const frameBox = ref<InstanceType<typeof FrameBox>>()
50+
const frameBox = ref<HTMLDivElement>()
5151
const panelEl = ref<HTMLDivElement>()
5252
const anchorEl = ref<HTMLDivElement>()
5353
@@ -235,6 +235,8 @@ const panelStyle = computed(() => {
235235
return style
236236
})
237237
238+
const { width: frameWidth, height: frameHeight } = useElementBounding(frameBox)
239+
238240
const iframeStyle = computed(() => {
239241
// eslint-disable-next-line no-unused-expressions, no-sequences
240242
mousePosition.x, mousePosition.y
@@ -255,8 +257,9 @@ const iframeStyle = computed(() => {
255257
const maxHeight = windowSize.height - marginVertical
256258
257259
const style: CSSProperties = {
260+
position: 'fixed',
258261
zIndex: -1,
259-
pointerEvents: isDragging.value ? 'none' : 'auto',
262+
pointerEvents: isDragging.value || !state.value.open ? 'none' : 'auto',
260263
width: `min(${state.value.width}vw, calc(100vw - ${marginHorizontal}px))`,
261264
height: `min(${state.value.height}vh, calc(100vh - ${marginVertical}px))`,
262265
}
@@ -271,21 +274,21 @@ const iframeStyle = computed(() => {
271274
switch (state.value.position) {
272275
case 'top':
273276
case 'bottom':
274-
style.left = 0
275-
style.transform = 'translate(-50%, 0)'
277+
style.left = `${-frameWidth.value / 2}px`
278+
style.transform = 'translate(0, 0)'
276279
if ((anchorX - frameMargin.left) < width / 2)
277-
style.left = `${width / 2 - anchorX + frameMargin.left}px`
280+
style.left = `${width / 2 - anchorX + frameMargin.left - frameWidth.value / 2}px`
278281
else if ((windowSize.width - anchorX - frameMargin.right) < width / 2)
279-
style.left = `${windowSize.width - anchorX - width / 2 - frameMargin.right}px`
282+
style.left = `${windowSize.width - anchorX - width / 2 - frameMargin.right - frameWidth.value / 2}px`
280283
break
281284
case 'right':
282285
case 'left':
283-
style.top = 0
284-
style.transform = 'translate(0, -50%)'
286+
style.top = `${-frameHeight.value / 2}px`
287+
style.transform = 'translate(0, 0)'
285288
if ((anchorY - frameMargin.top) < height / 2)
286-
style.top = `${height / 2 - anchorY + frameMargin.top}px`
289+
style.top = `${height / 2 - anchorY + frameMargin.top - frameHeight.value / 2}px`
287290
else if ((windowSize.height - anchorY - frameMargin.bottom) < height / 2)
288-
style.top = `${windowSize.height - anchorY - height / 2 - frameMargin.bottom}px`
291+
style.top = `${windowSize.height - anchorY - height / 2 - frameMargin.bottom - frameHeight.value / 2}px`
289292
break
290293
}
291294
@@ -398,12 +401,13 @@ onMounted(() => {
398401
</button>
399402
</template>
400403
</div>
401-
<FrameBox
402-
ref="frameBox"
403-
:client="client"
404-
:style="iframeStyle"
405-
:is-dragging="isDragging"
406-
/>
404+
405+
<div ref="frameBox" :style="iframeStyle">
406+
<FrameBox
407+
:client="client"
408+
:is-dragging="isDragging"
409+
/>
410+
</div>
407411
</div>
408412
</template>
409413

packages/devtools/src/runtime/plugins/view/utils.ts

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Ref } from 'vue'
2-
import { computed, getCurrentScope, onScopeDispose, ref, watch } from 'vue'
2+
import { computed, getCurrentInstance, getCurrentScope, onMounted, onScopeDispose, ref, toValue, watch } from 'vue'
33

44
export function useObjectStorage<T>(key: string, initial: T, listenToStorage = true): Ref<T> {
55
const raw = localStorage.getItem(key)
@@ -49,6 +49,89 @@ export function useEventListener(target: EventTarget, type: string, listener: an
4949
getCurrentScope() && onScopeDispose(() => target.removeEventListener(type, listener, options))
5050
}
5151

52+
/**
53+
* @see https://vueuse.org/useElementBounding
54+
*/
55+
export function useElementBounding(target: Ref<HTMLElement | null | undefined>) {
56+
const height = ref(0)
57+
const bottom = ref(0)
58+
const left = ref(0)
59+
const right = ref(0)
60+
const top = ref(0)
61+
const width = ref(0)
62+
const x = ref(0)
63+
const y = ref(0)
64+
65+
function update() {
66+
const el = toValue(target)
67+
68+
if (!el) {
69+
height.value = 0
70+
bottom.value = 0
71+
left.value = 0
72+
right.value = 0
73+
top.value = 0
74+
width.value = 0
75+
x.value = 0
76+
y.value = 0
77+
return
78+
}
79+
80+
const rect = el.getBoundingClientRect()
81+
82+
height.value = rect.height
83+
bottom.value = rect.bottom
84+
left.value = rect.left
85+
right.value = rect.right
86+
top.value = rect.top
87+
width.value = rect.width
88+
x.value = rect.x
89+
y.value = rect.y
90+
}
91+
92+
watch(() => toValue(target), update)
93+
useEventListener(window, 'resize', update)
94+
if (getCurrentInstance())
95+
onMounted(() => update())
96+
97+
// observer resize
98+
let observer: ResizeObserver | undefined
99+
const cleanup = () => {
100+
if (observer) {
101+
observer.disconnect()
102+
observer = undefined
103+
}
104+
}
105+
const stopWatch = watch(
106+
() => toValue(target),
107+
(el) => {
108+
cleanup()
109+
if (window) {
110+
observer = new ResizeObserver(update)
111+
el && observer!.observe(el)
112+
}
113+
},
114+
{ immediate: true, flush: 'post', deep: true },
115+
)
116+
117+
getCurrentScope() && onScopeDispose(() => {
118+
cleanup()
119+
stopWatch()
120+
})
121+
122+
return {
123+
height,
124+
bottom,
125+
left,
126+
right,
127+
top,
128+
width,
129+
x,
130+
y,
131+
update,
132+
}
133+
}
134+
52135
export function millisecondToHumanreadable(ms: number): [number, string] {
53136
if (ms < 1000)
54137
return [+ms.toFixed(0), 'ms']

0 commit comments

Comments
 (0)