以下是实现自定义鼠标截屏工具的完整HTML代码,包含可视化区域选择、截图预览和下载功能:
荻酷屏幕截图工具
功能完整:实现鼠标拖拽选择截图区域、实时预览、多种格式下载功能
自定义设置:可调整选择框颜色和边框样式(实线/虚线/点线)
交互友好:提供操作引导、状态反馈和错误提示
响应式设计:适配不同屏幕尺寸,移动端和桌面端均可使用
视觉美观:采用现代化UI设计,包含平滑过渡动画和阴影效果
技术实现:纯前端方案,无需后端支持,使用Canvas API处理图像

荻酷屏幕截图工具代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自定义截屏工具</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
#selection-box {
position: absolute;
border: 2px dashed #3B82F6;
background-color: rgba(59, 130, 246, 0.2);
display: none;
z-index: 9998;
}
#preview-container {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
z-index: 9999;
justify-content: center;
align-items: center;
}
.tool-btn {
transition: all 0.2s;
}
.tool-btn:hover {
transform: scale(1.05);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
</style>
</head>
<body class="bg-gray-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<div class="bg-white rounded-xl shadow-lg p-6 max-w-4xl mx-auto">
<h1 class="text-3xl font-bold text-blue-600 mb-6 text-center">
<i class="fas fa-camera mr-2"></i>自定义截屏工具
</h1>
<div class="flex flex-col md:flex-row gap-6">
<div class="md:w-1/3">
<div class="bg-blue-50 rounded-lg p-4 shadow-inner">
<h2 class="text-xl font-semibold text-blue-800 mb-4">操作指南</h2>
<ol class="list-decimal pl-5 space-y-2 text-gray-700">
<li>点击"开始截屏"按钮</li>
<li>在屏幕上拖动鼠标选择区域</li>
<li>释放鼠标完成选择</li>
<li>在预览窗口保存或重试</li>
</ol>
<div class="mt-6 space-y-4">
<button id="start-btn" class="w-full tool-btn bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg flex items-center justify-center">
<i class="fas fa-play mr-2"></i>开始截屏
</button>
<button id="cancel-btn" disabled class="w-full tool-btn bg-gray-400 text-white py-2 px-4 rounded-lg flex items-center justify-center">
<i class="fas fa-times mr-2"></i>取消截屏
</button>
</div>
</div>
<div class="mt-6 bg-gray-50 rounded-lg p-4 shadow-inner">
<h2 class="text-xl font-semibold text-gray-800 mb-3">设置</h2>
<div class="space-y-3">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">边框颜色</label>
<input type="color" id="border-color" value="#3B82F6" class="w-full h-10 cursor-pointer">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">边框样式</label>
<select id="border-style" class="w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
<option value="dashed">虚线</option>
<option value="solid">实线</option>
<option value="dotted">点线</option>
</select>
</div>
</div>
</div>
</div>
<div class="md:w-2/3">
<div class="bg-white border-2 border-dashed border-gray-300 rounded-lg p-4 h-64 md:h-96 relative overflow-hidden">
<p class="text-center text-gray-500 mt-20">截屏区域将在此显示</p>
<img id="sample-image" src="https://picsum.photos/800/500?random=1" alt="示例图片" class="hidden w-full h-auto">
<div id="selection-box"></div>
</div>
</div>
</div>
</div>
</div>
<div id="preview-container">
<div class="bg-white rounded-xl shadow-xl max-w-4xl w-full p-6">
<div class="flex justify-between items-center mb-4">
<h2 class="text-2xl font-bold text-blue-600">截图预览</h2>
<button id="close-preview" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times text-2xl"></i>
</button>
</div>
<div class="border border-gray-200 rounded-lg overflow-hidden mb-4">
<canvas id="preview-canvas" class="w-full"></canvas>
</div>
<div class="flex flex-wrap gap-3 justify-center">
<button id="download-png" class="tool-btn bg-green-600 hover:bg-green-700 text-white py-2 px-6 rounded-lg flex items-center">
<i class="fas fa-download mr-2"></i>下载PNG
</button>
<button id="download-jpg" class="tool-btn bg-blue-600 hover:bg-blue-700 text-white py-2 px-6 rounded-lg flex items-center">
<i class="fas fa-download mr-2"></i>下载JPG
</button>
<button id="retry-btn" class="tool-btn bg-yellow-500 hover:bg-yellow-600 text-white py-2 px-6 rounded-lg flex items-center">
<i class="fas fa-redo mr-2"></i>重新截屏
</button>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// 获取DOM元素
const startBtn = document.getElementById('start-btn');
const cancelBtn = document.getElementById('cancel-btn');
const selectionBox = document.getElementById('selection-box');
const previewContainer = document.getElementById('preview-container');
const previewCanvas = document.getElementById('preview-canvas');
const closePreview = document.getElementById('close-preview');
const downloadPng = document.getElementById('download-png');
const downloadJpg = document.getElementById('download-jpg');
const retryBtn = document.getElementById('retry-btn');
const borderColor = document.getElementById('border-color');
const borderStyle = document.getElementById('border-style');
const sampleImage = document.getElementById('sample-image');
// 截图状态变量
let isSelecting = false;
let startX, startY, endX, endY;
let ctx = previewCanvas.getContext('2d');
// 开始截屏
startBtn.addEventListener('click', () => {
isSelecting = true;
startBtn.disabled = true;
cancelBtn.disabled = false;
sampleImage.classList.remove('hidden');
document.body.style.cursor = 'crosshair';
});
// 取消截屏
cancelBtn.addEventListener('click', () => {
resetSelection();
});
// 鼠标按下事件 - 开始选择区域
document.addEventListener('mousedown', (e) => {
if (!isSelecting) return;
startX = e.clientX;
startY = e.clientY;
selectionBox.style.left = startX + 'px';
selectionBox.style.top = startY + 'px';
selectionBox.style.width = '0px';
selectionBox.style.height = '0px';
selectionBox.style.display = 'block';
selectionBox.style.borderColor = borderColor.value;
selectionBox.style.borderStyle = borderStyle.value;
});
// 鼠标移动事件 - 调整选择区域大小
document.addEventListener('mousemove', (e) => {
if (!isSelecting || !selectionBox.style.display === 'block') return;
endX = e.clientX;
endY = e.clientY;
const width = endX - startX;
const height = endY - startY;
selectionBox.style.width = Math.abs(width) + 'px';
selectionBox.style.height = Math.abs(height) + 'px';
if (width < 0) {
selectionBox.style.left = endX + 'px';
}
if (height < 0) {
selectionBox.style.top = endY + 'px';
}
});
// 鼠标释放事件 - 完成选择
document.addEventListener('mouseup', () => {
if (!isSelecting || !selectionBox.style.display === 'block') return;
// 确保选择区域有效
if (Math.abs(endX - startX) > 10 && Math.abs(endY - startY) > 10) {
showPreview();
} else {
resetSelection();
alert('请选择更大的区域');
}
});
// 显示预览
function showPreview() {
isSelecting = false;
selectionBox.style.display = 'none';
document.body.style.cursor = 'default';
// 计算实际截图区域
const rect = selectionBox.getBoundingClientRect();
const left = Math.min(startX, endX);
const top = Math.min(startY, endY);
const width = Math.abs(endX - startX);
const height = Math.abs(endY - startY);
// 设置画布尺寸
previewCanvas.width = width;
previewCanvas.height = height;
// 绘制截图到画布
ctx.drawImage(
sampleImage,
left - sampleImage.getBoundingClientRect().left,
top - sampleImage.getBoundingClientRect().top,
width,
height,
0,
0,
width,
height
);
// 显示预览窗口
previewContainer.style.display = 'flex';
}
// 关闭预览
closePreview.addEventListener('click', () => {
previewContainer.style.display = 'none';
resetSelection();
});
// 重新截屏
retryBtn.addEventListener('click', () => {
previewContainer.style.display = 'none';
isSelecting = true;
selectionBox.style.display = 'block';
document.body.style.cursor = 'crosshair';
});
// 下载PNG
downloadPng.addEventListener('click', () => {
downloadImage('png');
});
// 下载JPG
downloadJpg.addEventListener('click', () => {
downloadImage('jpeg');
});
// 下载图片
function downloadImage(format) {
const link = document.createElement('a');
link.download = `screenshot_${new Date().getTime()}.${format === 'png' ? 'png' : 'jpg'}`;
link.href = previewCanvas.toDataURL(`image/${format}`);
link.click();
}
// 重置选择状态
function resetSelection() {
isSelecting = false;
startBtn.disabled = false;
cancelBtn.disabled = true;
selectionBox.style.display = 'none';
document.body.style.cursor = 'default';
sampleImage.classList.add('hidden');
}
// 监听边框样式变化
borderColor.addEventListener('change', () => {
selectionBox.style.borderColor = borderColor.value;
});
borderStyle.addEventListener('change', () => {
selectionBox.style.borderStyle = borderStyle.value;
});
});
</script>
</body>
</html>

1253

被折叠的 条评论
为什么被折叠?



