我开发了一款防止摸鱼被发现的工具,现已开源

头两天用电脑摸鱼,突然领导从角落里走过来了,结果我紧急打开文档,但是文档程序启动需要时间。

领导撇了一眼我的屏幕,啥也没说就走了。

我发现除非我之前就将文档或者网页打开,调好到预定位置,否则如果有别人过来我很难反应过来。

即便是我反应过来了,电脑打开程序也是需要时间的。

所以我紧急开发了一款防摸鱼被发现神器 ------ 秒切(miao-qie)

需求

可以预先将 文档 / 网页 进行截图,上传到程序中,预设好展示截图的快捷键。

当触发快捷键 的时候,瞬间打开截图,并全屏窗口,看起来好像在浏览某个页面一样。

使用截图 规避快捷键打开程序需要的冷启动时间。

技术选型

需求看起来比较简单,实现起来还是存在一点门槛的。

首先考虑的是在浏览器中开发,但如果是浏览器插件的话,只能在浏览器中触发。

所以考虑开发一款PC端的程序,这样无论当前在干什么都能及时调出来。

前端使用 Vite + Vue3 + Ts 的老三样。

框架使用 Tauri 2.0 版本,打出来的包比较小,存储直接放在 localStore 里面。

实现代码

输入框捕获快捷键方法

js 复制代码
const handleInputFocus = (row: Setting) => {
	focusedRow.value = row
}

const handleInputBlur = () => {
	focusedRow.value = null
}

const handleKeyDown = (event: KeyboardEvent) => {
	if (!focusedRow.value) return

	const modifiers: string[] = []

	if (event.ctrlKey || event.metaKey) {
		modifiers.push('Ctrl')
	}
	if (event.shiftKey) {
		modifiers.push('Shift')
	}
	if (event.altKey) {
		modifiers.push('Alt')
	}

	let key = event.key

	if (key === ' ') {
		key = 'Space'
	} else if (key.length === 1 && key.match(/^[a-zA-Z]$/)) {
		key = key.toUpperCase()
	} else if (key.startsWith('Arrow')) {
		key = key.replace('Arrow', '')
	} else if (key === 'Backspace' || key === 'Delete') {
		return
	}

	if (modifiers.length > 0 || (!['Control', 'Shift', 'Alt', 'Meta', 'Tab', 'Enter', 'Escape'].includes(key))) {
		const shortcut = [...modifiers, key].join(' + ')
		focusedRow.value.shortcut = shortcut
		event.preventDefault()
	}
}

if (typeof window !== 'undefined') {
	window.addEventListener('keydown', handleKeyDown)
}

上传的图片直接转为Base64进行存储,这里基本不考虑分辨率的问题。

js 复制代码
const handleImageBeforeUpload = (file: File, row: Setting) => {
	// 图片转base64编码
	const reader = new FileReader()
	reader.readAsDataURL(file)
	reader.onload = (e) => {
		if (e.target?.result) {
			row.image = e.target.result as string
		}
	}
	return true
}

快捷键触发创建一个全屏窗口 ,这里要注意,Tauri创建新窗口以后,webView渲染的 html页面 需要放在 public 下。

js 复制代码
const createFullScreenWindow = async (imageBase64: string) => {
	const appWindow = new Window('uniqueLabel', {
		title: '图片',
		fullscreen: true
	});

	appWindow.once('tauri://created', async function () {
		console.log('Window窗口创建成功')

		const webview = new Webview(appWindow, 'theUniqueLabel', {
			url: '/image.html',
			x: 0,
			y: 0,
			width: 1920,
			height: 1080
		});

		webview.once('tauri://webview-created', async function () {
			console.log('webview 创建成功')
		});
		webview.once('tauri://error', function (e) {
			console.error('创建 webview 失败:', e)
		});

		await webview.listen("page-loaded", () => {
			// 页面加载完成
			webview.emit("image-base64", imageBase64);
		});
		// unlisten();
	});
}

快捷键注册方法,批量注册快捷键。

这里还存在一点儿小问题,快捷键冲突的时候还没有想好怎么解决。

js 复制代码
const registerShortcut = async () => {
	// 注销所有快捷键
	await unregisterAll()
	// 批量注册快捷键
	await Promise.allSettled(dataSrouce.value.map(async (item) => {
		let shortcutArr = item.shortcut.trim().replace(/\s+/g, '').split('+')
		// 判断出现Ctrl的话转为CommandOrControl
		if (shortcutArr.includes('Ctrl')) {
			shortcutArr = shortcutArr.map(item => item.replace('Ctrl', 'CommandOrControl'))
		}
		// 重组快捷键
		let shortcut = shortcutArr.join('+')
		console.log(shortcut)
		await register(shortcut, () => {
			console.log(`快捷键触发 ${shortcut} ✅`)
			// 这里写你要执行的逻辑
			createFullScreenWindow(item.image)
		})
	}))
}

总结

其实实现起来感觉非常简单,但是真正从零开始实现你才能踩到那些坑点。

Tauri 2.0 本身权限划分的非常细,所以权限记得给够。

快捷键的绑定操作、窗口创建关闭、托盘菜单等等Tauri都提供了相应的插件,但是开发的时候仍然觉得比较麻烦。

最最关键的,现在用AI开发 Tauri 2.0 的程序很多时候他仍然在使用 1.x 的代码,但是代码不兼容。

代码地址:gitee.com/maple2133/m...

相关推荐
启山智软1 小时前
从零搭建商城系统前端:技术选型与核心架构实践
前端·架构
ZC跨境爬虫1 小时前
跟着 MDN 学CSS day_5:掌握属性选择器的存否匹配与子字符串匹配
前端·javascript·css·ui·html
ZC跨境爬虫1 小时前
跟着 MDN 学CSS day_4:(深入理解CSS选择器的核心机制)
前端·javascript·css·交互
Mapmost1 小时前
三步搞定3DGS和3Dtiles单体化,这个免费工具能省你半天时间
前端
运维自动化&云计算1 小时前
修复chrome把mp4视频识别为音频、firefox不能加载mp4问题
服务器·前端·iis·mp4播放
恋猫de小郭1 小时前
Android 发布全新性能分析器,实用性和性能大升级
android·前端·flutter
ZC跨境爬虫1 小时前
模块化烹饪小程序开发日记 Day5:(后端Flask接口开发与AI智能解析菜谱的实现)
前端·人工智能·后端·python·ui·flask
燐妤1 小时前
前端HTML编程6:ES6与前后端交互
前端·javascript·学习·html5