hd0013's picture
Upload folder using huggingface_hub
8fdc036 verified
raw
history blame contribute delete
No virus
4.24 kB
<script lang="ts">
import { getContext, onDestroy, onMount, tick } from "svelte";
import { type ToolContext, TOOL_KEY } from "./Tools.svelte";
import { type EditorContext, EDITOR_KEY } from "../ImageEditor.svelte";
import { crop_canvas, resize_and_reposition, type CropCommand } from "./crop";
import Cropper from "./Cropper.svelte";
const { active_tool, register_tool } = getContext<ToolContext>(TOOL_KEY);
const {
dimensions,
editor_box,
pixi,
crop,
command_manager,
current_history
} = getContext<EditorContext>(EDITOR_KEY);
let cropper: CropCommand | null;
export let crop_constraint: [number, number] | `${string}:${string}` | null;
let _crop_constraint: number | null = null;
$: {
if (typeof crop_constraint === "string") {
const [w, h] = crop_constraint.split(":");
_crop_constraint = parseInt(w) / parseInt(h);
} else if (Array.isArray(crop_constraint)) {
_crop_constraint = crop_constraint[0] / crop_constraint[1];
}
}
let w_p = 1;
let h_p = 1;
let l_p = 0;
let t_p = 0;
let current_opacity = 0;
let manually_cropped = false;
$: {
if (!manually_cropped && _crop_constraint && $pixi && $active_tool) {
requestAnimationFrame(() => {
initial_crop();
});
}
}
let c: CropCommand | null = null;
async function initial_crop(): Promise<void> {
if (c || $current_history.previous) return;
const { new_height, new_width, x_offset, y_offset } = resize_and_reposition(
$editor_box.child_width,
$editor_box.child_height,
"c",
_crop_constraint!,
$editor_box.child_width,
$editor_box.child_height
);
w_p = new_width / $editor_box.child_width;
h_p = new_height / $editor_box.child_height;
l_p = x_offset / $editor_box.child_width;
t_p = y_offset / $editor_box.child_height;
c = crop_canvas($pixi!.renderer, $pixi!.mask_container, crop, 0.2);
c.start(...$dimensions, current_crop, false);
c.continue(
[
l_p * $dimensions[0],
t_p * $dimensions[1],
w_p * $dimensions[0],
h_p * $dimensions[1]
],
false
);
c.stop();
c.execute();
c = null;
current_opacity = 0;
}
function handle_crop(
type: "start" | "stop" | "continue",
{
x,
y,
width,
height
}: {
x: number;
y: number;
width: number;
height: number;
}
): void {
if (!$pixi) return;
if (type === "start") {
if (cropper) {
current_opacity = cropper.stop();
cropper = null;
}
cropper = crop_canvas(
$pixi?.renderer,
$pixi.mask_container,
crop,
current_opacity
);
cropper.start(...$dimensions, current_crop);
} else if (type === "continue") {
if (!cropper) return;
cropper.continue([
x * $dimensions[0],
y * $dimensions[1],
width * $dimensions[0],
height * $dimensions[1]
]);
} else if (type === "stop") {
if (!cropper) return;
command_manager.execute(cropper);
}
manually_cropped = true;
}
let measured = false;
function get_measurements(): void {
if (measured) return;
if (!$editor_box.child_height) return;
const _height = $editor_box.child_height;
const _width = $editor_box.child_width;
const _top = $editor_box.child_top - $editor_box.parent_top;
const _left = $editor_box.child_left - $editor_box.parent_left;
w_p = _width / $editor_box.child_width;
h_p = _height / $editor_box.child_height;
l_p =
(_left - $editor_box.child_left + $editor_box.parent_left) /
$editor_box.child_width;
t_p =
(_top - $editor_box.child_top + $editor_box.parent_top) /
$editor_box.child_height;
measured = true;
}
let current_crop: [number, number, number, number];
$: current_crop = [
l_p * $dimensions[0],
t_p * $dimensions[1],
w_p * $dimensions[0],
h_p * $dimensions[1]
];
$: {
l_p = $crop[0];
t_p = $crop[1];
w_p = $crop[2];
h_p = $crop[3];
}
$: $editor_box && get_measurements();
onMount(() => register_tool("crop"));
</script>
{#if $active_tool === "crop" && measured}
<Cropper
crop_constraint={_crop_constraint}
{w_p}
{h_p}
{l_p}
{t_p}
{editor_box}
on:crop_start={({ detail }) => handle_crop("start", detail)}
on:crop_continue={({ detail }) => handle_crop("continue", detail)}
on:crop_end={({ detail }) => handle_crop("stop", detail)}
/>
{/if}