138 lines
3.3 KiB
HTML
138 lines
3.3 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html>
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<title>文字工具测试</title>
|
||
|
|
<style>
|
||
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
|
body { overflow: hidden; }
|
||
|
|
.container {
|
||
|
|
position: fixed;
|
||
|
|
top: 0; left: 0; width: 100vw; height: 100vh;
|
||
|
|
background: #333;
|
||
|
|
cursor: crosshair;
|
||
|
|
}
|
||
|
|
#canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #666; }
|
||
|
|
#input {
|
||
|
|
position: absolute;
|
||
|
|
z-index: 1000;
|
||
|
|
border: 2px solid #07C160;
|
||
|
|
border-radius: 4px;
|
||
|
|
padding: 2px 6px;
|
||
|
|
font-size: 20px;
|
||
|
|
font-family: sans-serif;
|
||
|
|
background: rgba(255,255,255,0.9);
|
||
|
|
outline: none;
|
||
|
|
min-width: 60px;
|
||
|
|
color: #333;
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div class="container" id="container">
|
||
|
|
<canvas id="canvas"></canvas>
|
||
|
|
<input id="input" />
|
||
|
|
</div>
|
||
|
|
<script>
|
||
|
|
const canvas = document.getElementById('canvas')
|
||
|
|
const ctx = canvas.getContext('2d')
|
||
|
|
const input = document.getElementById('input')
|
||
|
|
canvas.width = window.innerWidth
|
||
|
|
canvas.height = window.innerHeight
|
||
|
|
|
||
|
|
ctx.fillStyle = '#666'
|
||
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||
|
|
ctx.fillStyle = 'red'
|
||
|
|
ctx.font = '20px sans-serif'
|
||
|
|
|
||
|
|
let isSelecting = false
|
||
|
|
let box = {x: 0, y: 0, w: 0, h: 0}
|
||
|
|
let tool = 'arrow'
|
||
|
|
|
||
|
|
// 绘制选区框
|
||
|
|
function drawBox() {
|
||
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||
|
|
ctx.fillStyle = 'rgba(0,0,0,0.5)'
|
||
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||
|
|
ctx.clearRect(box.x, box.y, box.w, box.h)
|
||
|
|
ctx.strokeStyle = '#07C160'
|
||
|
|
ctx.lineWidth = 2
|
||
|
|
ctx.strokeRect(box.x, box.y, box.w, box.h)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 切换工具(模拟点击工具栏)
|
||
|
|
document.addEventListener('keydown', (e) => {
|
||
|
|
if (e.key === 't') { tool = 'text'; console.log('tool=text') }
|
||
|
|
if (e.key === 'a') { tool = 'arrow'; console.log('tool=arrow') }
|
||
|
|
if (e.key === 'Escape') {
|
||
|
|
input.style.display = 'none'
|
||
|
|
input.value = ''
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
canvas.addEventListener('mousedown', (e) => {
|
||
|
|
console.log('mousedown', e.clientX, e.clientY, 'tool=', tool)
|
||
|
|
if (box.w === 0) {
|
||
|
|
isSelecting = true
|
||
|
|
box = {x: e.clientX, y: e.clientY, w: 0, h: 0}
|
||
|
|
return
|
||
|
|
}
|
||
|
|
// 在选区内
|
||
|
|
if (e.clientX >= box.x && e.clientX <= box.x + box.w && e.clientY >= box.y && e.clientY <= box.y + box.h) {
|
||
|
|
if (tool === 'text') {
|
||
|
|
input.style.display = 'block'
|
||
|
|
input.style.left = e.clientX + 'px'
|
||
|
|
input.style.top = (e.clientY - 14) + 'px'
|
||
|
|
input.value = ''
|
||
|
|
input.focus()
|
||
|
|
console.log('show input at', e.clientX, e.clientY - 14)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
// arrow 等...
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
canvas.addEventListener('mousemove', (e) => {
|
||
|
|
if (isSelecting) {
|
||
|
|
box.w = Math.abs(e.clientX - box.x)
|
||
|
|
box.h = Math.abs(e.clientY - box.y)
|
||
|
|
box.x = Math.min(box.x, e.clientX)
|
||
|
|
box.y = Math.min(box.y, e.clientY)
|
||
|
|
drawBox()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
document.addEventListener('mouseup', () => {
|
||
|
|
isSelecting = false
|
||
|
|
})
|
||
|
|
|
||
|
|
input.addEventListener('keydown', (e) => {
|
||
|
|
if (e.key === 'Enter') {
|
||
|
|
commitText()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
input.addEventListener('blur', () => {
|
||
|
|
console.log('blur')
|
||
|
|
commitText()
|
||
|
|
})
|
||
|
|
|
||
|
|
function commitText() {
|
||
|
|
if (input.style.display === 'none') return
|
||
|
|
const text = input.value.trim()
|
||
|
|
console.log('commitText', text)
|
||
|
|
if (text) {
|
||
|
|
const rect = input.getBoundingClientRect()
|
||
|
|
ctx.fillStyle = 'red'
|
||
|
|
ctx.font = '20px sans-serif'
|
||
|
|
ctx.textBaseline = 'middle'
|
||
|
|
ctx.fillText(text, rect.left, rect.top + rect.height / 2)
|
||
|
|
}
|
||
|
|
input.style.display = 'none'
|
||
|
|
input.value = ''
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|