Skip to content

Commit 6504686

Browse files
committed
wip: beautify highlight style
1 parent 2adb464 commit 6504686

File tree

1 file changed

+90
-17
lines changed

1 file changed

+90
-17
lines changed

packages/core/index.ts

+90-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { type ComponentInternalInstance } from 'vue'
22

3+
let ctx: CanvasRenderingContext2D | null = null
4+
const updateCounters = new WeakMap<HTMLElement, number>()
5+
const elements = new Set<HTMLElement>()
6+
37
export function VueChangeMarker() {
4-
const ctx = initCanvas()
8+
ctx = initCanvas()
9+
510
function emit(event: string, ...payload: any[]) {
611
if (event === 'component:updated') {
712
const updatedInstance = payload[3] as ComponentInternalInstance
@@ -15,24 +20,11 @@ export function VueChangeMarker() {
1520
if (!el) return
1621
// 注释节点之类的 transition 这类组件
1722
if (!el.getBoundingClientRect) return
18-
const rect = el.getBoundingClientRect()
19-
const width = ctx.canvas.width
20-
const height = ctx.canvas.height
21-
22-
ctx.font = '14px Arial'
23-
ctx.fillStyle = 'red'
24-
25-
ctx.fillText('updated component: ' + componentName, rect.x, rect.y - 5)
26-
27-
ctx.fillStyle = 'blue'
28-
ctx.strokeStyle = 'red'
29-
ctx.lineWidth = 1
30-
ctx.strokeRect(rect.x, rect.y, rect.width, rect.height)
31-
setTimeout(() => {
32-
ctx.clearRect(0, 0, width, height)
33-
}, 100)
23+
24+
scheduler.addTask(() => highlight(ctx!, el, componentName))
3425
}
3526
}
27+
3628
if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__?.id !== 'vue-change-marker') {
3729
const oldEmit = window.__VUE_DEVTOOLS_GLOBAL_HOOK__.emit
3830
window.__VUE_DEVTOOLS_GLOBAL_HOOK__.emit = function (...args: any[]) {
@@ -71,3 +63,84 @@ function initCanvas() {
7163

7264
return ctx
7365
}
66+
67+
function clearCanvas(ctx: CanvasRenderingContext2D) {
68+
const width = ctx.canvas.width
69+
const height = ctx.canvas.height
70+
ctx.clearRect(0, 0, width, height)
71+
}
72+
function resetAllUpdateCounters() {
73+
elements.forEach((el) => {
74+
updateCounters.set(el, 0) // 将每个元素的更新计数器重置为 0
75+
})
76+
}
77+
78+
type HighlightTask = {
79+
fn: () => void
80+
}
81+
82+
class HighlightScheduler {
83+
taskQueue: HighlightTask[] = []
84+
addTask(fn: () => void) {
85+
this.taskQueue.push({ fn })
86+
}
87+
88+
// 执行队列中的所有任务
89+
async executeTasks() {
90+
if (this.taskQueue.length === 0) return
91+
while (this.taskQueue.length) {
92+
const task = this.taskQueue.shift()!
93+
task.fn()
94+
await new Promise((resolve) => setTimeout(resolve, 30))
95+
}
96+
if (this.taskQueue.length === 0) {
97+
await new Promise((resolve) => setTimeout(resolve, 100))
98+
clearCanvas(ctx!)
99+
resetAllUpdateCounters()
100+
}
101+
}
102+
}
103+
104+
// 测试
105+
const scheduler = new HighlightScheduler()
106+
executeTasks()
107+
108+
async function executeTasks() {
109+
if (scheduler.taskQueue.length) {
110+
await scheduler.executeTasks()
111+
}
112+
await new Promise((resolve) => setTimeout(resolve, 100))
113+
await executeTasks()
114+
}
115+
116+
function highlight(
117+
ctx: CanvasRenderingContext2D,
118+
el: HTMLElement,
119+
componentName: string,
120+
) {
121+
clearCanvas(ctx!)
122+
123+
let updateCounter = updateCounters.get(el) || 0
124+
updateCounter++
125+
126+
updateCounters.set(el, updateCounter)
127+
elements.add(el)
128+
129+
const opacity = Math.min(0.7, updateCounter * 0.2)
130+
const rect = el.getBoundingClientRect()
131+
132+
ctx.fillStyle = `rgba(255, 0, 0, ${opacity})`
133+
ctx.fillRect(rect.x, rect.y - 20, rect.width, 20)
134+
135+
ctx.fillStyle = `white`
136+
ctx.font = '14px Arial'
137+
ctx.fillText(
138+
'updated component: ' + componentName + ' x:' + updateCounter,
139+
rect.x,
140+
rect.y - 5,
141+
)
142+
143+
ctx.strokeStyle = `rgba(255, 0, 0, ${opacity})`
144+
ctx.lineWidth = 1
145+
ctx.strokeRect(rect.x, rect.y, rect.width, rect.height)
146+
}

0 commit comments

Comments
 (0)