mirror of
https://github.com/kunkunsh/kunkun.git
synced 2025-05-24 13:45:03 +00:00
Feature: Pin Screenshot (#22)
* feat: add pin screenshot builtin command * feat: pin screenshot command nows zoom and scroll
This commit is contained in:
parent
f29fe00dcf
commit
0600eca59a
@ -32,6 +32,7 @@
|
||||
"svelte-radix": "^2.0.1",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"sveltekit-superforms": "^2.20.0",
|
||||
"tauri-plugin-clipboard-api": "^2.1.11",
|
||||
"uuid": "^11.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -23,6 +23,7 @@
|
||||
"core:path:default",
|
||||
"core:event:default",
|
||||
"core:window:default",
|
||||
"core:window:allow-set-size",
|
||||
"core:window:allow-start-dragging",
|
||||
"core:window:allow-set-focus",
|
||||
"core:window:allow-toggle-maximize",
|
||||
|
@ -6,6 +6,7 @@ import { WebviewWindow } from "@tauri-apps/api/webviewWindow"
|
||||
import { exit } from "@tauri-apps/plugin-process"
|
||||
import { goto } from "$app/navigation"
|
||||
import { toast } from "svelte-sonner"
|
||||
import * as clipboard from "tauri-plugin-clipboard-api"
|
||||
import { v4 as uuidv4 } from "uuid"
|
||||
|
||||
export const builtinCmds: BuiltinCmd[] = [
|
||||
@ -202,6 +203,29 @@ export const builtinCmds: BuiltinCmd[] = [
|
||||
appState.clearSearchTerm()
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Pin Current Screenshot",
|
||||
iconifyIcon: "material-symbols:screenshot-monitor-outline",
|
||||
description: "Pin the current screenshot",
|
||||
function: async () => {
|
||||
appState.clearSearchTerm()
|
||||
if (!(await clipboard.hasImage())) {
|
||||
toast.error("No screenshot in clipboard")
|
||||
return
|
||||
}
|
||||
const window = new WebviewWindow(`main:pinned-screenshot-${uuidv4()}`, {
|
||||
url: "/extension/pin-screenshot",
|
||||
title: "Pinned Screenshot",
|
||||
hiddenTitle: true,
|
||||
titleBarStyle: "transparent",
|
||||
decorations: false,
|
||||
visible: false
|
||||
})
|
||||
setTimeout(() => {
|
||||
window.show()
|
||||
}, 2_000)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Toggle Hide On Blur",
|
||||
iconifyIcon: "ri:toggle-line",
|
||||
|
@ -0,0 +1,88 @@
|
||||
<script lang="ts">
|
||||
import { Button } from "@kksh/svelte5"
|
||||
import { Layouts } from "@kksh/ui"
|
||||
import { LogicalSize } from "@tauri-apps/api/dpi"
|
||||
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
|
||||
import { CircleX } from "lucide-svelte"
|
||||
import { onMount } from "svelte"
|
||||
import * as clipboard from "tauri-plugin-clipboard-api"
|
||||
|
||||
let image = $state<string | null>(null)
|
||||
const appWin = getCurrentWebviewWindow()
|
||||
let originalSize = $state<{ width: number; height: number } | null>(null)
|
||||
let originalScaleFactor = $state<number | null>(null)
|
||||
let scale = $state<number>(1)
|
||||
let currentSize = $derived(
|
||||
originalSize ? { width: originalSize.width * scale, height: originalSize.height * scale } : null
|
||||
)
|
||||
|
||||
$effect(() => {
|
||||
if (currentSize) {
|
||||
appWin.setSize(new LogicalSize(currentSize.width, currentSize.height))
|
||||
}
|
||||
})
|
||||
|
||||
async function getWindowSize() {
|
||||
const size = await appWin.outerSize()
|
||||
const scaleFactor = originalScaleFactor ?? (await appWin.scaleFactor())
|
||||
const logicalSize = size.toLogical(scaleFactor)
|
||||
return { logicalSize, scaleFactor }
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
clipboard
|
||||
.readImageBase64()
|
||||
.then((b64) => {
|
||||
image = b64
|
||||
})
|
||||
.finally(() => {
|
||||
appWin.show()
|
||||
})
|
||||
const { logicalSize, scaleFactor } = await getWindowSize()
|
||||
originalSize = { width: logicalSize.width, height: logicalSize.height }
|
||||
originalScaleFactor = scaleFactor
|
||||
})
|
||||
|
||||
async function onWheel(e: WheelEvent) {
|
||||
scale += (e.deltaY < 0 ? 1 : -1) * 0.05
|
||||
}
|
||||
|
||||
function onGestureChange(e: any) {
|
||||
e.preventDefault()
|
||||
scale = e.scale
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
document.addEventListener("wheel", onWheel)
|
||||
document.addEventListener("gesturechange", onGestureChange)
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("wheel", onWheel)
|
||||
document.removeEventListener("gesturechange", onGestureChange)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:window
|
||||
on:keydown={(e) => {
|
||||
if (e.key === "Escape") {
|
||||
appWin.close()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button size="icon" variant="ghost" class="fixed left-2 top-2" onclick={() => appWin.close()}
|
||||
><CircleX /></Button
|
||||
>
|
||||
<main class="z-50 h-screen w-screen overflow-hidden" data-tauri-drag-region>
|
||||
{#if image}
|
||||
<img
|
||||
src={`data:image/png;base64,${image}`}
|
||||
alt="screenshot"
|
||||
class="pointer-events-none h-full w-full object-contain"
|
||||
/>
|
||||
{:else}
|
||||
<Layouts.Center>
|
||||
<p class="text-2xl font-bold">No image found in clipboard</p>
|
||||
</Layouts.Center>
|
||||
{/if}
|
||||
</main>
|
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -168,6 +168,9 @@ importers:
|
||||
sveltekit-superforms:
|
||||
specifier: ^2.20.0
|
||||
version: 2.20.0(@sveltejs/kit@2.7.4(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.1.9)(vite@5.4.10(@types/node@22.8.7)(terser@5.36.0)))(svelte@5.1.9)(vite@5.4.10(@types/node@22.8.7)(terser@5.36.0)))(@types/json-schema@7.0.15)(svelte@5.1.9)(typescript@5.6.3)
|
||||
tauri-plugin-clipboard-api:
|
||||
specifier: ^2.1.11
|
||||
version: 2.1.11(typescript@5.6.3)
|
||||
uuid:
|
||||
specifier: ^11.0.2
|
||||
version: 11.0.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user