dsh-desktop-windows 0.2.5 → 0.2.7
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 +59 -33
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.7",
|
|
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
|
@@ -7,8 +7,28 @@
|
|
|
7
7
|
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
|
|
8
8
|
html, body { width: 100%; height: 100%; overflow: hidden; background: #000; cursor: crosshair; }
|
|
9
9
|
#stage { position: fixed; inset: 0; }
|
|
10
|
-
#stage img {
|
|
11
|
-
|
|
10
|
+
#stage img {
|
|
11
|
+
width: 100%; height: 100%; object-fit: fill; display: block;
|
|
12
|
+
-webkit-user-drag: none; user-drag: none; draggable: false;
|
|
13
|
+
pointer-events: none; /* 避免 img 拦截鼠标事件/触发拖拽 */
|
|
14
|
+
}
|
|
15
|
+
/* 遮罩:全屏半透明黑 + clip-path 挖洞(GPU 加速,每帧只改字符串) */
|
|
16
|
+
#mask {
|
|
17
|
+
position: fixed; inset: 0; z-index: 2; pointer-events: none;
|
|
18
|
+
background: rgba(0, 0, 0, 0.45);
|
|
19
|
+
clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
|
|
20
|
+
}
|
|
21
|
+
/* 选区框:border div,transform 定位 + 尺寸更新 */
|
|
22
|
+
#sel {
|
|
23
|
+
position: fixed; z-index: 3; pointer-events: none;
|
|
24
|
+
border: 1.5px solid #2563eb; background: rgba(37, 99, 235, 0.08);
|
|
25
|
+
transform-origin: 0 0;
|
|
26
|
+
}
|
|
27
|
+
#sel .sz {
|
|
28
|
+
position: absolute; left: 0; top: -22px;
|
|
29
|
+
background: #2563eb; color: #fff;
|
|
30
|
+
font: 11px/18px sans-serif; padding: 0 6px; border-radius: 4px; white-space: nowrap;
|
|
31
|
+
}
|
|
12
32
|
.handle {
|
|
13
33
|
position: fixed; width: 9px; height: 9px; background: #2563eb;
|
|
14
34
|
border: 1px solid #fff; border-radius: 2px; display: none;
|
|
@@ -40,7 +60,8 @@
|
|
|
40
60
|
</head>
|
|
41
61
|
<body>
|
|
42
62
|
<div id="stage"><img id="bg" alt=""></div>
|
|
43
|
-
<
|
|
63
|
+
<div id="mask"></div>
|
|
64
|
+
<div id="sel"><div class="sz"></div></div>
|
|
44
65
|
<div id="hN" class="handle" style="cursor:n-resize"></div>
|
|
45
66
|
<div id="hS" class="handle" style="cursor:s-resize"></div>
|
|
46
67
|
<div id="hE" class="handle" style="cursor:e-resize"></div>
|
|
@@ -58,11 +79,12 @@
|
|
|
58
79
|
|
|
59
80
|
<script>
|
|
60
81
|
var bg = document.getElementById('bg')
|
|
82
|
+
var mask = document.getElementById('mask')
|
|
83
|
+
var sel = document.getElementById('sel')
|
|
84
|
+
var sz = sel.querySelector('.sz')
|
|
61
85
|
var toolbar = document.getElementById('toolbar')
|
|
62
86
|
var hint = document.getElementById('hint')
|
|
63
87
|
var tip = document.getElementById('tip')
|
|
64
|
-
var cv = document.getElementById('cv')
|
|
65
|
-
var cx = cv.getContext('2d')
|
|
66
88
|
var handles = {
|
|
67
89
|
n: document.getElementById('hN'), s: document.getElementById('hS'),
|
|
68
90
|
e: document.getElementById('hE'), w: document.getElementById('hW'),
|
|
@@ -70,7 +92,6 @@
|
|
|
70
92
|
se: document.getElementById('hSE'), sw: document.getElementById('hSW'),
|
|
71
93
|
}
|
|
72
94
|
var W = window.innerWidth, H = window.innerHeight
|
|
73
|
-
cv.width = W; cv.height = H
|
|
74
95
|
var MIN = 8
|
|
75
96
|
var rect = null
|
|
76
97
|
var mode = 'draw' // draw | adjust
|
|
@@ -80,7 +101,7 @@
|
|
|
80
101
|
window.__screenshot.onData(function (dataUrl) {
|
|
81
102
|
bg.onload = function () {
|
|
82
103
|
window.__screenshot.loaded()
|
|
83
|
-
|
|
104
|
+
update()
|
|
84
105
|
setTimeout(function () { hint.style.opacity = '0.9' }, 100)
|
|
85
106
|
}
|
|
86
107
|
bg.src = dataUrl
|
|
@@ -94,28 +115,29 @@
|
|
|
94
115
|
return { x: x, y: y, w: w, h: h }
|
|
95
116
|
}
|
|
96
117
|
|
|
97
|
-
//
|
|
98
|
-
function
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
118
|
+
// 每帧只更新 2 个元素:mask 的 clip-path(GPU)+ sel 的位置尺寸
|
|
119
|
+
function update() {
|
|
120
|
+
if (!rect) {
|
|
121
|
+
mask.style.clipPath = 'polygon(0px 0px, 0px 0px, 0px 0px, 0px 0px, 0px 0px)'
|
|
122
|
+
sel.style.display = 'none'
|
|
123
|
+
hideHandles()
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
var x = rect.x, y = rect.y, w = rect.w, h = rect.h
|
|
127
|
+
// clip-path:外框逆时针 + 选区顺时针 → 挖洞
|
|
128
|
+
mask.style.clipPath =
|
|
129
|
+
'polygon(0px 0px, ' + W + 'px 0px, ' + W + 'px ' + H + 'px, 0px ' + H + 'px, 0px 0px, ' +
|
|
130
|
+
x + 'px ' + y + 'px, ' + (x + w) + 'px ' + y + 'px, ' + (x + w) + 'px ' + (y + h) + 'px, ' + x + 'px ' + (y + h) + 'px, ' + x + 'px ' + y + 'px)'
|
|
131
|
+
sel.style.display = 'block'
|
|
132
|
+
sel.style.transform = 'translate(' + x + 'px, ' + y + 'px)'
|
|
133
|
+
sel.style.width = w + 'px'
|
|
134
|
+
sel.style.height = h + 'px'
|
|
135
|
+
sz.textContent = Math.round(w) + ' × ' + Math.round(h)
|
|
136
|
+
updateHandles()
|
|
112
137
|
}
|
|
113
138
|
|
|
114
139
|
function updateHandles() {
|
|
115
|
-
if (mode !== 'adjust' || !rect) {
|
|
116
|
-
for (var k in handles) handles[k].style.display = 'none'
|
|
117
|
-
return
|
|
118
|
-
}
|
|
140
|
+
if (mode !== 'adjust' || !rect) { hideHandles(); return }
|
|
119
141
|
var x = rect.x, y = rect.y, w = rect.w, h = rect.h
|
|
120
142
|
var pos = {
|
|
121
143
|
n: [x + w / 2, y], s: [x + w / 2, y + h],
|
|
@@ -129,13 +151,16 @@
|
|
|
129
151
|
}
|
|
130
152
|
}
|
|
131
153
|
|
|
132
|
-
function
|
|
154
|
+
function hideHandles() {
|
|
155
|
+
for (var k in handles) handles[k].style.display = 'none'
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function scheduleUpdate() {
|
|
133
159
|
if (rafPending) return
|
|
134
160
|
rafPending = true
|
|
135
161
|
requestAnimationFrame(function () {
|
|
136
162
|
rafPending = false
|
|
137
|
-
|
|
138
|
-
updateHandles()
|
|
163
|
+
update()
|
|
139
164
|
})
|
|
140
165
|
}
|
|
141
166
|
|
|
@@ -145,6 +170,7 @@
|
|
|
145
170
|
|
|
146
171
|
document.addEventListener('mousedown', function (e) {
|
|
147
172
|
if (e.button !== 0) return
|
|
173
|
+
e.preventDefault() // 阻止 img 拖拽等默认行为,确保 mousemove 正常触发
|
|
148
174
|
if (mode === 'draw') {
|
|
149
175
|
drag = { type: 'draw', x0: e.clientX, y0: e.clientY }
|
|
150
176
|
return
|
|
@@ -161,7 +187,7 @@
|
|
|
161
187
|
toolbar.style.display = 'none'
|
|
162
188
|
hint.style.opacity = '0.9'
|
|
163
189
|
drag = { type: 'draw', x0: e.clientX, y0: e.clientY }
|
|
164
|
-
|
|
190
|
+
scheduleUpdate()
|
|
165
191
|
}
|
|
166
192
|
})
|
|
167
193
|
|
|
@@ -182,7 +208,7 @@
|
|
|
182
208
|
if (drag.dir.indexOf('n') !== -1) { r.y = o.y + dy; r.h = o.h - dy }
|
|
183
209
|
rect = clampRect(r)
|
|
184
210
|
}
|
|
185
|
-
|
|
211
|
+
scheduleUpdate()
|
|
186
212
|
})
|
|
187
213
|
|
|
188
214
|
document.addEventListener('mouseup', function () {
|
|
@@ -195,11 +221,11 @@
|
|
|
195
221
|
t.style.left = Math.min(rect.x + rect.w + 10, W - 250) + 'px'
|
|
196
222
|
t.style.top = (rect.y + rect.h + 14 > H - 60 ? rect.y - 60 : rect.y + rect.h + 14) + 'px'
|
|
197
223
|
hint.style.opacity = '0'
|
|
198
|
-
|
|
224
|
+
scheduleUpdate()
|
|
199
225
|
}
|
|
200
226
|
})
|
|
201
227
|
|
|
202
|
-
//
|
|
228
|
+
// 关键:点击工具栏(确定/取消)不触发 document 的画框逻辑
|
|
203
229
|
toolbar.addEventListener('mousedown', function (e) { e.stopPropagation() })
|
|
204
230
|
|
|
205
231
|
document.getElementById('okBtn').onclick = function () {
|