dsh-desktop-windows 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/screenshot.html +53 -32
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-desktop-windows",
|
|
3
3
|
"productName": "DeepSeek Harness Desktop",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.6",
|
|
5
5
|
"description": "DeepSeek Harness 桌面版(Windows)· Electron desktop shell for DeepSeek Harness (dsh web) — 双击即用,无需终端 / double-click to run the harness in a standalone window",
|
|
6
6
|
"main": "src/main.js",
|
|
7
7
|
"license": "MIT",
|
package/src/screenshot.html
CHANGED
|
@@ -8,7 +8,23 @@
|
|
|
8
8
|
html, body { width: 100%; height: 100%; overflow: hidden; background: #000; cursor: crosshair; }
|
|
9
9
|
#stage { position: fixed; inset: 0; }
|
|
10
10
|
#stage img { width: 100%; height: 100%; object-fit: fill; display: block; }
|
|
11
|
-
|
|
11
|
+
/* 遮罩:全屏半透明黑 + clip-path 挖洞(GPU 加速,每帧只改字符串) */
|
|
12
|
+
#mask {
|
|
13
|
+
position: fixed; inset: 0; z-index: 2; pointer-events: none;
|
|
14
|
+
background: rgba(0, 0, 0, 0.45);
|
|
15
|
+
clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
|
|
16
|
+
}
|
|
17
|
+
/* 选区框:border div,transform 定位 + 尺寸更新 */
|
|
18
|
+
#sel {
|
|
19
|
+
position: fixed; z-index: 3; pointer-events: none;
|
|
20
|
+
border: 1.5px solid #2563eb; background: rgba(37, 99, 235, 0.08);
|
|
21
|
+
transform-origin: 0 0;
|
|
22
|
+
}
|
|
23
|
+
#sel .sz {
|
|
24
|
+
position: absolute; left: 0; top: -22px;
|
|
25
|
+
background: #2563eb; color: #fff;
|
|
26
|
+
font: 11px/18px sans-serif; padding: 0 6px; border-radius: 4px; white-space: nowrap;
|
|
27
|
+
}
|
|
12
28
|
.handle {
|
|
13
29
|
position: fixed; width: 9px; height: 9px; background: #2563eb;
|
|
14
30
|
border: 1px solid #fff; border-radius: 2px; display: none;
|
|
@@ -40,7 +56,8 @@
|
|
|
40
56
|
</head>
|
|
41
57
|
<body>
|
|
42
58
|
<div id="stage"><img id="bg" alt=""></div>
|
|
43
|
-
<
|
|
59
|
+
<div id="mask"></div>
|
|
60
|
+
<div id="sel"><div class="sz"></div></div>
|
|
44
61
|
<div id="hN" class="handle" style="cursor:n-resize"></div>
|
|
45
62
|
<div id="hS" class="handle" style="cursor:s-resize"></div>
|
|
46
63
|
<div id="hE" class="handle" style="cursor:e-resize"></div>
|
|
@@ -58,11 +75,12 @@
|
|
|
58
75
|
|
|
59
76
|
<script>
|
|
60
77
|
var bg = document.getElementById('bg')
|
|
78
|
+
var mask = document.getElementById('mask')
|
|
79
|
+
var sel = document.getElementById('sel')
|
|
80
|
+
var sz = sel.querySelector('.sz')
|
|
61
81
|
var toolbar = document.getElementById('toolbar')
|
|
62
82
|
var hint = document.getElementById('hint')
|
|
63
83
|
var tip = document.getElementById('tip')
|
|
64
|
-
var cv = document.getElementById('cv')
|
|
65
|
-
var cx = cv.getContext('2d')
|
|
66
84
|
var handles = {
|
|
67
85
|
n: document.getElementById('hN'), s: document.getElementById('hS'),
|
|
68
86
|
e: document.getElementById('hE'), w: document.getElementById('hW'),
|
|
@@ -70,7 +88,6 @@
|
|
|
70
88
|
se: document.getElementById('hSE'), sw: document.getElementById('hSW'),
|
|
71
89
|
}
|
|
72
90
|
var W = window.innerWidth, H = window.innerHeight
|
|
73
|
-
cv.width = W; cv.height = H
|
|
74
91
|
var MIN = 8
|
|
75
92
|
var rect = null
|
|
76
93
|
var mode = 'draw' // draw | adjust
|
|
@@ -80,7 +97,7 @@
|
|
|
80
97
|
window.__screenshot.onData(function (dataUrl) {
|
|
81
98
|
bg.onload = function () {
|
|
82
99
|
window.__screenshot.loaded()
|
|
83
|
-
|
|
100
|
+
update()
|
|
84
101
|
setTimeout(function () { hint.style.opacity = '0.9' }, 100)
|
|
85
102
|
}
|
|
86
103
|
bg.src = dataUrl
|
|
@@ -94,28 +111,29 @@
|
|
|
94
111
|
return { x: x, y: y, w: w, h: h }
|
|
95
112
|
}
|
|
96
113
|
|
|
97
|
-
//
|
|
98
|
-
function
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
// 每帧只更新 2 个元素:mask 的 clip-path(GPU)+ sel 的位置尺寸
|
|
115
|
+
function update() {
|
|
116
|
+
if (!rect) {
|
|
117
|
+
mask.style.clipPath = 'polygon(0px 0px, 0px 0px, 0px 0px, 0px 0px, 0px 0px)'
|
|
118
|
+
sel.style.display = 'none'
|
|
119
|
+
hideHandles()
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
var x = rect.x, y = rect.y, w = rect.w, h = rect.h
|
|
123
|
+
// clip-path:外框逆时针 + 选区顺时针 → 挖洞
|
|
124
|
+
mask.style.clipPath =
|
|
125
|
+
'polygon(0px 0px, ' + W + 'px 0px, ' + W + 'px ' + H + 'px, 0px ' + H + 'px, 0px 0px, ' +
|
|
126
|
+
x + 'px ' + y + 'px, ' + (x + w) + 'px ' + y + 'px, ' + (x + w) + 'px ' + (y + h) + 'px, ' + x + 'px ' + (y + h) + 'px, ' + x + 'px ' + y + 'px)'
|
|
127
|
+
sel.style.display = 'block'
|
|
128
|
+
sel.style.transform = 'translate(' + x + 'px, ' + y + 'px)'
|
|
129
|
+
sel.style.width = w + 'px'
|
|
130
|
+
sel.style.height = h + 'px'
|
|
131
|
+
sz.textContent = Math.round(w) + ' × ' + Math.round(h)
|
|
132
|
+
updateHandles()
|
|
112
133
|
}
|
|
113
134
|
|
|
114
135
|
function updateHandles() {
|
|
115
|
-
if (mode !== 'adjust' || !rect) {
|
|
116
|
-
for (var k in handles) handles[k].style.display = 'none'
|
|
117
|
-
return
|
|
118
|
-
}
|
|
136
|
+
if (mode !== 'adjust' || !rect) { hideHandles(); return }
|
|
119
137
|
var x = rect.x, y = rect.y, w = rect.w, h = rect.h
|
|
120
138
|
var pos = {
|
|
121
139
|
n: [x + w / 2, y], s: [x + w / 2, y + h],
|
|
@@ -129,13 +147,16 @@
|
|
|
129
147
|
}
|
|
130
148
|
}
|
|
131
149
|
|
|
132
|
-
function
|
|
150
|
+
function hideHandles() {
|
|
151
|
+
for (var k in handles) handles[k].style.display = 'none'
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function scheduleUpdate() {
|
|
133
155
|
if (rafPending) return
|
|
134
156
|
rafPending = true
|
|
135
157
|
requestAnimationFrame(function () {
|
|
136
158
|
rafPending = false
|
|
137
|
-
|
|
138
|
-
updateHandles()
|
|
159
|
+
update()
|
|
139
160
|
})
|
|
140
161
|
}
|
|
141
162
|
|
|
@@ -161,7 +182,7 @@
|
|
|
161
182
|
toolbar.style.display = 'none'
|
|
162
183
|
hint.style.opacity = '0.9'
|
|
163
184
|
drag = { type: 'draw', x0: e.clientX, y0: e.clientY }
|
|
164
|
-
|
|
185
|
+
scheduleUpdate()
|
|
165
186
|
}
|
|
166
187
|
})
|
|
167
188
|
|
|
@@ -182,7 +203,7 @@
|
|
|
182
203
|
if (drag.dir.indexOf('n') !== -1) { r.y = o.y + dy; r.h = o.h - dy }
|
|
183
204
|
rect = clampRect(r)
|
|
184
205
|
}
|
|
185
|
-
|
|
206
|
+
scheduleUpdate()
|
|
186
207
|
})
|
|
187
208
|
|
|
188
209
|
document.addEventListener('mouseup', function () {
|
|
@@ -195,11 +216,11 @@
|
|
|
195
216
|
t.style.left = Math.min(rect.x + rect.w + 10, W - 250) + 'px'
|
|
196
217
|
t.style.top = (rect.y + rect.h + 14 > H - 60 ? rect.y - 60 : rect.y + rect.h + 14) + 'px'
|
|
197
218
|
hint.style.opacity = '0'
|
|
198
|
-
|
|
219
|
+
scheduleUpdate()
|
|
199
220
|
}
|
|
200
221
|
})
|
|
201
222
|
|
|
202
|
-
//
|
|
223
|
+
// 关键:点击工具栏(确定/取消)不触发 document 的画框逻辑
|
|
203
224
|
toolbar.addEventListener('mousedown', function (e) { e.stopPropagation() })
|
|
204
225
|
|
|
205
226
|
document.getElementById('okBtn').onclick = function () {
|