Files
immich/web/src/lib/components/asset-viewer/editor/crop-tool/crop-tool.svelte

155 lines
4.4 KiB
Svelte
Raw Normal View History

feat(web): image editor - panel and cropping (#11074) * cropping, panel * fix presets * types * prettier * fix lint * fix aspect ratio, performance optimization * improved tool selection, removed placeholder * fix the mouse's exit from canvas * fix error * the "save" button and change tracking * lint, format * the mini functionality of the save button * fix aspect ratio * hide editor button on mobiles * strict equality Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Use the dollar sign syntax for stores inside components * unobtrusive grid lines, circles at the corners * more correct image load, handleError * more strict equality * fix styles. unused and tailwind Co-Authored-By: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * dont store isShowEditor * if showEditor - hide navbar & shortcuts * crop-canvas decomposition (danger) I could have accidentally broken something.. but I checked the work and it seems ok. * fix lint * fix ts * callback function as props * correctly disabling shortcuts * convenient canvas borders • you can use the mouse to go beyond the boundaries and freely change the crop. • the circles on the corners of the canvas are not cut off. * -the editor button for video files, -save button * hide editor btn if panoramic || gif || live * corners instead of circles (preview), fix lint&format * confirm close editor without save * vertical aspect ratios * recovery after merge. editor's closing shortcut * fix format * move from canvas to html elements * fix changes detections * rotation * hide detail panel if showing editor * fix aspect ratios near min size * fix crop area when changing image size when rotate * fix of fix * better layout - grouping https://github.com/user-attachments/assets/48f15172-9666-4588-acb6-3cb5eda873a8 * hide the button * fix i18n, format * hide button * hide button v2 --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-08-14 17:54:50 +03:00
<script lang="ts">
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import {
cropAspectRatio,
cropImageScale,
cropImageSize,
cropSettings,
cropSettingsChanged,
normaizedRorateDegrees,
rotateDegrees,
type CropAspectRatio,
} from '$lib/stores/asset-editor.store';
import { mdiBackupRestore, mdiCropFree, mdiRotateLeft, mdiRotateRight, mdiSquareOutline } from '@mdi/js';
import { t } from 'svelte-i18n';
import { onImageLoad } from './image-loading';
import { tick } from 'svelte';
import CropPreset from './crop-preset.svelte';
let rotateHorizontal = $derived([90, 270].includes($normaizedRorateDegrees));
feat(web): image editor - panel and cropping (#11074) * cropping, panel * fix presets * types * prettier * fix lint * fix aspect ratio, performance optimization * improved tool selection, removed placeholder * fix the mouse's exit from canvas * fix error * the "save" button and change tracking * lint, format * the mini functionality of the save button * fix aspect ratio * hide editor button on mobiles * strict equality Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Use the dollar sign syntax for stores inside components * unobtrusive grid lines, circles at the corners * more correct image load, handleError * more strict equality * fix styles. unused and tailwind Co-Authored-By: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * dont store isShowEditor * if showEditor - hide navbar & shortcuts * crop-canvas decomposition (danger) I could have accidentally broken something.. but I checked the work and it seems ok. * fix lint * fix ts * callback function as props * correctly disabling shortcuts * convenient canvas borders • you can use the mouse to go beyond the boundaries and freely change the crop. • the circles on the corners of the canvas are not cut off. * -the editor button for video files, -save button * hide editor btn if panoramic || gif || live * corners instead of circles (preview), fix lint&format * confirm close editor without save * vertical aspect ratios * recovery after merge. editor's closing shortcut * fix format * move from canvas to html elements * fix changes detections * rotation * hide detail panel if showing editor * fix aspect ratios near min size * fix crop area when changing image size when rotate * fix of fix * better layout - grouping https://github.com/user-attachments/assets/48f15172-9666-4588-acb6-3cb5eda873a8 * hide the button * fix i18n, format * hide button * hide button v2 --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-08-14 17:54:50 +03:00
const icon_16_9 = `M200-280q-33 0-56.5-23.5T120-360v-240q0-33 23.5-56.5T200-680h560q33 0 56.5 23.5T840-600v240q0 33-23.5 56.5T760-280H200Zm0-80h560v-240H200v240Zm0 0v-240 240Z`;
const icon_4_3 = `M19 5H5c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 12H5V7h14v10z`;
const icon_3_2 = `M200-240q-33 0-56.5-23.5T120-320v-320q0-33 23.5-56.5T200-720h560q33 0 56.5 23.5T840-640v320q0 33-23.5 56.5T760-240H200Zm0-80h560v-320H200v320Zm0 0v-320 320Z`;
const icon_7_5 = `M200-200q-33 0-56.5-23.5T120-280v-400q0-33 23.5-56.5T200-760h560q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H200Zm0-80h560v-400H200v400Zm0 0v-400 400Z`;
interface Size {
icon: string;
name: CropAspectRatio;
viewBox: string;
rotate?: boolean;
}
let sizes: Size[] = [
{
icon: mdiCropFree,
name: 'free',
viewBox: '0 0 24 24',
rotate: false,
},
{
name: '1:1',
icon: mdiSquareOutline,
viewBox: '0 0 24 24',
rotate: false,
},
{
name: '16:9',
icon: icon_16_9,
viewBox: '50 -700 840 400',
},
{
name: '4:3',
icon: icon_4_3,
viewBox: '0 0 24 24',
},
{
name: '3:2',
icon: icon_3_2,
viewBox: '50 -720 840 480',
},
{
name: '7:5',
icon: icon_7_5,
viewBox: '50 -760 840 560',
},
{
name: '9:16',
icon: icon_16_9,
viewBox: '50 -700 840 400',
rotate: true,
},
{
name: '3:4',
icon: icon_4_3,
viewBox: '0 0 24 24',
rotate: true,
},
{
name: '2:3',
icon: icon_3_2,
viewBox: '50 -720 840 480',
rotate: true,
},
{
name: '5:7',
icon: icon_7_5,
viewBox: '50 -760 840 560',
rotate: true,
},
{
name: 'reset',
icon: mdiBackupRestore,
viewBox: '0 0 24 24',
rotate: false,
},
];
let selectedSize: CropAspectRatio = $state('free');
feat(web): image editor - panel and cropping (#11074) * cropping, panel * fix presets * types * prettier * fix lint * fix aspect ratio, performance optimization * improved tool selection, removed placeholder * fix the mouse's exit from canvas * fix error * the "save" button and change tracking * lint, format * the mini functionality of the save button * fix aspect ratio * hide editor button on mobiles * strict equality Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Use the dollar sign syntax for stores inside components * unobtrusive grid lines, circles at the corners * more correct image load, handleError * more strict equality * fix styles. unused and tailwind Co-Authored-By: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * dont store isShowEditor * if showEditor - hide navbar & shortcuts * crop-canvas decomposition (danger) I could have accidentally broken something.. but I checked the work and it seems ok. * fix lint * fix ts * callback function as props * correctly disabling shortcuts * convenient canvas borders • you can use the mouse to go beyond the boundaries and freely change the crop. • the circles on the corners of the canvas are not cut off. * -the editor button for video files, -save button * hide editor btn if panoramic || gif || live * corners instead of circles (preview), fix lint&format * confirm close editor without save * vertical aspect ratios * recovery after merge. editor's closing shortcut * fix format * move from canvas to html elements * fix changes detections * rotation * hide detail panel if showing editor * fix aspect ratios near min size * fix crop area when changing image size when rotate * fix of fix * better layout - grouping https://github.com/user-attachments/assets/48f15172-9666-4588-acb6-3cb5eda873a8 * hide the button * fix i18n, format * hide button * hide button v2 --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-08-14 17:54:50 +03:00
$effect(() => {
$cropAspectRatio = selectedSize;
});
let sizesRows = $derived([
feat(web): image editor - panel and cropping (#11074) * cropping, panel * fix presets * types * prettier * fix lint * fix aspect ratio, performance optimization * improved tool selection, removed placeholder * fix the mouse's exit from canvas * fix error * the "save" button and change tracking * lint, format * the mini functionality of the save button * fix aspect ratio * hide editor button on mobiles * strict equality Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Use the dollar sign syntax for stores inside components * unobtrusive grid lines, circles at the corners * more correct image load, handleError * more strict equality * fix styles. unused and tailwind Co-Authored-By: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * dont store isShowEditor * if showEditor - hide navbar & shortcuts * crop-canvas decomposition (danger) I could have accidentally broken something.. but I checked the work and it seems ok. * fix lint * fix ts * callback function as props * correctly disabling shortcuts * convenient canvas borders • you can use the mouse to go beyond the boundaries and freely change the crop. • the circles on the corners of the canvas are not cut off. * -the editor button for video files, -save button * hide editor btn if panoramic || gif || live * corners instead of circles (preview), fix lint&format * confirm close editor without save * vertical aspect ratios * recovery after merge. editor's closing shortcut * fix format * move from canvas to html elements * fix changes detections * rotation * hide detail panel if showing editor * fix aspect ratios near min size * fix crop area when changing image size when rotate * fix of fix * better layout - grouping https://github.com/user-attachments/assets/48f15172-9666-4588-acb6-3cb5eda873a8 * hide the button * fix i18n, format * hide button * hide button v2 --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-08-14 17:54:50 +03:00
sizes.filter((s) => s.rotate === false),
sizes.filter((s) => s.rotate === undefined),
sizes.filter((s) => s.rotate === true),
]);
feat(web): image editor - panel and cropping (#11074) * cropping, panel * fix presets * types * prettier * fix lint * fix aspect ratio, performance optimization * improved tool selection, removed placeholder * fix the mouse's exit from canvas * fix error * the "save" button and change tracking * lint, format * the mini functionality of the save button * fix aspect ratio * hide editor button on mobiles * strict equality Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Use the dollar sign syntax for stores inside components * unobtrusive grid lines, circles at the corners * more correct image load, handleError * more strict equality * fix styles. unused and tailwind Co-Authored-By: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * dont store isShowEditor * if showEditor - hide navbar & shortcuts * crop-canvas decomposition (danger) I could have accidentally broken something.. but I checked the work and it seems ok. * fix lint * fix ts * callback function as props * correctly disabling shortcuts * convenient canvas borders • you can use the mouse to go beyond the boundaries and freely change the crop. • the circles on the corners of the canvas are not cut off. * -the editor button for video files, -save button * hide editor btn if panoramic || gif || live * corners instead of circles (preview), fix lint&format * confirm close editor without save * vertical aspect ratios * recovery after merge. editor's closing shortcut * fix format * move from canvas to html elements * fix changes detections * rotation * hide detail panel if showing editor * fix aspect ratios near min size * fix crop area when changing image size when rotate * fix of fix * better layout - grouping https://github.com/user-attachments/assets/48f15172-9666-4588-acb6-3cb5eda873a8 * hide the button * fix i18n, format * hide button * hide button v2 --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-08-14 17:54:50 +03:00
async function rotate(clock: boolean) {
rotateDegrees.update((v) => {
return v + 90 * (clock ? 1 : -1);
});
await tick();
onImageLoad();
}
function selectType(size: CropAspectRatio) {
if (size === 'reset') {
selectedSize = 'free';
let cropImageSizeM = $cropImageSize;
let cropImageScaleM = $cropImageScale;
$cropSettings = {
x: 0,
y: 0,
width: cropImageSizeM[0] * cropImageScaleM - 1,
height: cropImageSizeM[1] * cropImageScaleM - 1,
};
$cropAspectRatio = selectedSize;
$cropSettingsChanged = false;
return;
}
selectedSize = size;
$cropAspectRatio = size;
}
</script>
<div class="mt-3 px-4 py-4">
<div class="flex h-10 w-full items-center justify-between text-sm">
<h2>{$t('editor_crop_tool_h2_aspect_ratios').toUpperCase()}</h2>
</div>
{#each sizesRows as sizesRow}
<ul class="flex-wrap flex-row flex gap-x-6 py-2 justify-evenly">
{#each sizesRow as size (size.name)}
<CropPreset {size} {selectedSize} {rotateHorizontal} {selectType} />
{/each}
</ul>
{/each}
<div class="flex h-10 w-full items-center justify-between text-sm">
<h2>{$t('editor_crop_tool_h2_rotation').toUpperCase()}</h2>
</div>
<ul class="flex-wrap flex-row flex gap-x-6 gap-y-4 justify-center">
<li><CircleIconButton title={$t('anti_clockwise')} onclick={() => rotate(false)} icon={mdiRotateLeft} /></li>
<li><CircleIconButton title={$t('clockwise')} onclick={() => rotate(true)} icon={mdiRotateRight} /></li>
feat(web): image editor - panel and cropping (#11074) * cropping, panel * fix presets * types * prettier * fix lint * fix aspect ratio, performance optimization * improved tool selection, removed placeholder * fix the mouse's exit from canvas * fix error * the "save" button and change tracking * lint, format * the mini functionality of the save button * fix aspect ratio * hide editor button on mobiles * strict equality Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Use the dollar sign syntax for stores inside components * unobtrusive grid lines, circles at the corners * more correct image load, handleError * more strict equality * fix styles. unused and tailwind Co-Authored-By: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * dont store isShowEditor * if showEditor - hide navbar & shortcuts * crop-canvas decomposition (danger) I could have accidentally broken something.. but I checked the work and it seems ok. * fix lint * fix ts * callback function as props * correctly disabling shortcuts * convenient canvas borders • you can use the mouse to go beyond the boundaries and freely change the crop. • the circles on the corners of the canvas are not cut off. * -the editor button for video files, -save button * hide editor btn if panoramic || gif || live * corners instead of circles (preview), fix lint&format * confirm close editor without save * vertical aspect ratios * recovery after merge. editor's closing shortcut * fix format * move from canvas to html elements * fix changes detections * rotation * hide detail panel if showing editor * fix aspect ratios near min size * fix crop area when changing image size when rotate * fix of fix * better layout - grouping https://github.com/user-attachments/assets/48f15172-9666-4588-acb6-3cb5eda873a8 * hide the button * fix i18n, format * hide button * hide button v2 --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-08-14 17:54:50 +03:00
</ul>
</div>