Add image-handle-dimensions to show dimensions directly on image

This commit is contained in:
Henrik Giesel 2021-07-21 02:15:10 +02:00 committed by Damien Elmes
parent 0b06891771
commit 1756bca212
3 changed files with 63 additions and 42 deletions

View file

@ -6,12 +6,41 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { getContext } from "svelte"; import { getContext } from "svelte";
import { nightModeKey } from "components/context-keys"; import { nightModeKey } from "components/context-keys";
export let hidden: boolean; export let image: HTMLImageElement | null = null;
export let container: HTMLElement | null = null;
export let top: number = 0; let hidden = true;
export let left: number = 0;
export let width: number = 0; let naturalWidth = 0;
export let height: number = 0; let naturalHeight = 0;
let containerTop = 0;
let containerLeft = 0;
let top = 0;
let left = 0;
let width = 0;
let height = 0;
$: if (image) {
const imageRect = image.getBoundingClientRect();
const containerRect = (
container ?? document.documentElement
).getBoundingClientRect();
naturalWidth = image.naturalWidth;
naturalHeight = image.naturalHeight;
(containerTop = containerRect.top),
(containerLeft = containerRect.left),
(top = imageRect.top - containerTop),
(left = imageRect.left - containerLeft),
(width = image.clientWidth),
(height = image.clientHeight),
(hidden = false);
} else {
hidden = true;
}
function setPointerCapture(event: PointerEvent): void { function setPointerCapture(event: PointerEvent): void {
if (event.pointerId !== 1) { if (event.pointerId !== 1) {
@ -25,6 +54,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
if (!(event.target as Element).hasPointerCapture(event.pointerId)) { if (!(event.target as Element).hasPointerCapture(event.pointerId)) {
return; return;
} }
const dragWidth = event.clientX - containerLeft - left;
const dragHeight = event.clientY - containerTop - top;
width = dragWidth;
image!.style.width = `${dragWidth}px`;
height = dragHeight;
image!.style.height = `${dragHeight}px`;
} }
const nightMode = getContext(nightModeKey); const nightMode = getContext(nightModeKey);
@ -36,6 +73,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{hidden} {hidden}
> >
<div class="image-handle-bg" /> <div class="image-handle-bg" />
<div class="image-handle-dimensions">
{width}&times;{height} (Original: {naturalWidth}&times;{naturalHeight})
</div>
<div class:nightMode class="image-handle-control image-handle-control-nw" /> <div class:nightMode class="image-handle-control image-handle-control-nw" />
<div class:nightMode class="image-handle-control image-handle-control-ne" /> <div class:nightMode class="image-handle-control image-handle-control-ne" />
<div class:nightMode class="image-handle-control image-handle-control-sw" /> <div class:nightMode class="image-handle-control image-handle-control-sw" />
@ -66,6 +106,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
opacity: 0.2; opacity: 0.2;
} }
.image-handle-dimensions {
pointer-events: none;
user-select: none;
bottom: 3px;
right: 3px;
background-color: rgba(0 0 0 / 0.3);
border-color: black;
border-radius: 0.25rem;
padding: 0 5px;
}
.image-handle-control { .image-handle-control {
width: 7px; width: 7px;
height: 7px; height: 7px;

View file

@ -1,17 +0,0 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import ImageHandle from "./ImageHandle.svelte";
export let hidden: boolean;
export let top: number;
export let left: number;
export let width: number;
export let height: number;
</script>
<div>
<ImageHandle {hidden} {top} {left} {width} {height} />
</div>

View file

@ -5,7 +5,7 @@
@typescript-eslint/no-non-null-assertion: "off", @typescript-eslint/no-non-null-assertion: "off",
*/ */
import ImageHandleContainer from "./ImageHandleContainer.svelte"; import ImageHandle from "./ImageHandle.svelte";
import type { EditableContainer } from "./editable-container"; import type { EditableContainer } from "./editable-container";
import type { Editable } from "./editable"; import type { Editable } from "./editable";
@ -22,7 +22,7 @@ function onCutOrCopy(): void {
} }
export class EditingArea extends HTMLDivElement { export class EditingArea extends HTMLDivElement {
imageHandle: ImageHandleContainer; imageHandle: ImageHandle;
editableContainer: EditableContainer; editableContainer: EditableContainer;
editable: Editable; editable: Editable;
codable: Codable; codable: Codable;
@ -44,16 +44,10 @@ export class EditingArea extends HTMLDivElement {
document.documentElement.classList.contains("night-mode") document.documentElement.classList.contains("night-mode")
); );
this.imageHandle = new ImageHandleContainer({ this.imageHandle = new ImageHandle({
target: this, target: this,
anchor: this.editableContainer, anchor: this.editableContainer,
props: { props: { container: this.editable },
hidden: true,
top: 0,
left: 0,
width: 0,
height: 0,
},
context, context,
} as any); } as any);
@ -172,20 +166,12 @@ export class EditingArea extends HTMLDivElement {
showImageHandle(event: MouseEvent): void { showImageHandle(event: MouseEvent): void {
if (event.target instanceof HTMLImageElement) { if (event.target instanceof HTMLImageElement) {
const image = event.target;
const imageRect = image.getBoundingClientRect();
const editableRect = this.editable.getBoundingClientRect();
(this.imageHandle as any).$set({ (this.imageHandle as any).$set({
hidden: false, image: event.target,
top: imageRect.top - editableRect.top,
left: imageRect.left - editableRect.left,
width: image.clientWidth,
height: image.clientHeight,
}); });
} else { } else {
(this.imageHandle as any).$set({ (this.imageHandle as any).$set({
hidden: true, image: null,
}); });
} }
} }