mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: auto crop image
This commit is contained in:
1 parent
4cc4e664df
commit
10d7fe1e75
4 files changed
+184
-41
No files matched your search
@@ -32,6 +32,7 @@
|
||||
"compare-versions": "^6.1.1",
|
||||
"fuzzysort": "^3.1.0",
|
||||
"immer": "^10.1.3",
|
||||
"jimp": "^1.6.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"markdown-to-jsx": "^7.7.13",
|
||||
"pwa-install-handler": "^2.6.3",
|
||||
|
||||
@@ -6,7 +6,8 @@ import {
|
||||
Popover,
|
||||
type ButtonProps,
|
||||
} from "@radix-ui/themes";
|
||||
import type { RefObject } from "react";
|
||||
import { Jimp } from "jimp";
|
||||
import { useCallback, type RefObject } from "react";
|
||||
import { useLocale } from "../hooks/useLocale";
|
||||
import { screenshotReadyEvent } from "./Tankopedia/HeroSection/components/TankSandbox/components/SceneProps";
|
||||
|
||||
@@ -18,6 +19,35 @@ interface Props extends ButtonProps {
|
||||
export function ScreenshotButton({ canvas, name, children, ...props }: Props) {
|
||||
const { strings } = useLocale();
|
||||
|
||||
const screenshot = useCallback(async () => {
|
||||
if (!canvas.current) {
|
||||
throw new Error("Canvas not found");
|
||||
}
|
||||
|
||||
screenshotReadyEvent.dispatch(true);
|
||||
|
||||
const blob = await new Promise<Blob>((resolve, reject) => {
|
||||
requestAnimationFrame(() => {
|
||||
canvas.current.toBlob((blob) => {
|
||||
screenshotReadyEvent.dispatch(false);
|
||||
|
||||
if (!blob) {
|
||||
reject(new Error("Failed to capture screenshot"));
|
||||
} else {
|
||||
resolve(blob);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const buffer = await blob.arrayBuffer();
|
||||
const image = await Jimp.fromBuffer(buffer);
|
||||
|
||||
image.autocrop();
|
||||
|
||||
return image;
|
||||
}, [canvas]);
|
||||
|
||||
return (
|
||||
<Popover.Root>
|
||||
<Popover.Trigger>
|
||||
@@ -37,23 +67,13 @@ export function ScreenshotButton({ canvas, name, children, ...props }: Props) {
|
||||
<Flex direction="column" gap="2">
|
||||
<Popover.Close>
|
||||
<Button
|
||||
onClick={() => {
|
||||
screenshotReadyEvent.dispatch(true);
|
||||
onClick={async () => {
|
||||
const image = await screenshot();
|
||||
const anchor = document.createElement("a");
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
if (!canvas.current) return;
|
||||
|
||||
const anchor = document.createElement("a");
|
||||
|
||||
anchor.setAttribute("download", `${name}.png`);
|
||||
anchor.setAttribute(
|
||||
"href",
|
||||
canvas.current.toDataURL("image/png")
|
||||
);
|
||||
anchor.click();
|
||||
|
||||
screenshotReadyEvent.dispatch(false);
|
||||
});
|
||||
anchor.setAttribute("download", `${name}.png`);
|
||||
anchor.setAttribute("href", await image.getBase64("image/png"));
|
||||
anchor.click();
|
||||
}}
|
||||
>
|
||||
<DownloadIcon />
|
||||
@@ -63,22 +83,16 @@ export function ScreenshotButton({ canvas, name, children, ...props }: Props) {
|
||||
<Popover.Close>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
screenshotReadyEvent.dispatch(true);
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
if (!canvas.current) return;
|
||||
|
||||
canvas.current.toBlob((blob) => {
|
||||
if (!blob) return;
|
||||
|
||||
navigator.clipboard.write([
|
||||
new ClipboardItem({ "image/png": blob }),
|
||||
]);
|
||||
});
|
||||
|
||||
screenshotReadyEvent.dispatch(false);
|
||||
onClick={async () => {
|
||||
const image = await screenshot();
|
||||
const buffer = await image.getBuffer("image/png");
|
||||
const blob = new Blob([buffer as unknown as ArrayBuffer], {
|
||||
type: "image/png",
|
||||
});
|
||||
|
||||
navigator.clipboard.write([
|
||||
new ClipboardItem({ "image/png": blob }),
|
||||
]);
|
||||
}}
|
||||
>
|
||||
<CopyIcon />
|
||||
|
||||
Reference in new issue
Block a user