Skip to content

Commit

Permalink
feat(website): integrate image editor
Browse files Browse the repository at this point in the history
  • Loading branch information
lennartkloock committed Jan 25, 2024
1 parent d22e530 commit 8c0bcca
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 105 deletions.
54 changes: 54 additions & 0 deletions platform/website/src/assets/styles/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,60 @@ input[type="password"] {
}
}

// Style the range input
input[type="range"] {
appearance: none;
-webkit-appearance: none;
background: transparent;

&:focus {
outline: none;
}

&::-moz-range-thumb {
appearance: none;
width: 1rem;
height: 1rem;
border-radius: 50%;
background: white;
cursor: pointer;
}

&::-ms-thumb {
width: 1rem;
height: 1rem;
border-radius: 50%;
background: white;
cursor: pointer;
}

&::-webkit-slider-thumb {
-webkit-appearance: none;
margin-top: -0.25rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
background: white;
cursor: pointer;
}

&::-webkit-slider-runnable-track {
width: 100%;
height: 0.5rem;
cursor: pointer;
background: rgba($textColor, 0.25);
border-radius: 0.25rem;
}

&::-moz-range-track {
width: 100%;
height: 0.5rem;
cursor: pointer;
background: rgba($textColor, 0.25);
border-radius: 0.25rem;
}
}

// Screen reader only
// Hide but still render
.sr-only:not(:focus):not(:active) {
Expand Down
50 changes: 0 additions & 50 deletions platform/website/src/components/player.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -611,56 +611,6 @@
}
.volume {
appearance: none;
-webkit-appearance: none;
width: 8rem;
background: transparent;
}
.volume:focus {
outline: none;
}
.volume::-moz-range-thumb {
appearance: none;
width: 1rem;
height: 1rem;
border-radius: 50%;
background: white;
cursor: pointer;
}
.volume::-ms-thumb {
width: 1rem;
height: 1rem;
border-radius: 50%;
background: white;
cursor: pointer;
}
.volume::-webkit-slider-thumb {
-webkit-appearance: none;
margin-top: -0.25rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
background: white;
cursor: pointer;
}
.volume::-webkit-slider-runnable-track {
width: 100%;
height: 0.5rem;
cursor: pointer;
background: rgba($textColor, 0.25);
border-radius: 0.25rem;
}
.volume::-moz-range-track {
width: 100%;
height: 0.5rem;
cursor: pointer;
background: rgba($textColor, 0.25);
border-radius: 0.25rem;
}
</style>
110 changes: 110 additions & 0 deletions platform/website/src/components/settings/image-editor-dialog.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import Dialog from "../dialog.svelte";
import ImageEditor from "./image-editor.svelte";
import Fa from "svelte-fa";
import { faBorderAll, faCheck, faUpRightAndDownLeftFromCenter } from "@fortawesome/free-solid-svg-icons";
import Spinner from "../spinner.svelte";
export let src: string;
const dispatch = createEventDispatcher();
let loading = false;
let editor: ImageEditor;
let scale: number = 1;
let grid = false;
function onSubmit() {
if (!editor) return;
loading = true;
editor.calculateResult((blob) => {
loading = false;
dispatch("submit", { blob: blob });
});
}
</script>

<Dialog width={25} on:close>
<div class="container">
<div class="editor">
<ImageEditor size={20 * 16} minScale={1} maxScale={2} bind:this={editor} bind:scale={scale} src={src} gridOverlay={grid} />
<div class="input-row">
<Fa icon={faUpRightAndDownLeftFromCenter} fw />
<input class="scale" type="range" min="1" max="2" step="0.01" bind:value={scale} />
<button class="button" class:secondary={!grid} class:primary={grid} on:click={() => (grid = !grid)}>
<Fa icon={faBorderAll} fw />
</button>
</div>
</div>
<div class="buttons">
<button class="button secondary" on:click={() => dispatch("close")}>Cancel</button>
<button class="button primary submit" on:click={onSubmit}>
Submit
{#if loading}
<Spinner />
{:else}
<Fa icon={faCheck} />
{/if}
</button>
</div>
</div>
</Dialog>

<style lang="scss">
@import "../../assets/styles/variables.scss";
.container {
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
}
.editor {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
& > .input-row {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
color: $textColorLight;
& > .button {
padding: 0.5rem 0.6rem;
display: flex;
align-items: center;
justify-content: center;
}
& > .scale {
width: 100%;
}
}
}
.buttons {
width: 100%;
display: flex;
justify-content: space-between;
gap: 1rem;
& > .button {
padding: 0.4rem 0.8rem;
&.submit {
display: flex;
align-items: center;
gap: 0.5rem;
}
}
}
</style>
79 changes: 30 additions & 49 deletions platform/website/src/components/settings/image-editor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
export let overlay = true;
export let gridOverlay = false;
export let size = 40 * 16;
export let minScale = 1;
export let maxScale = 2;
// between minScale and maxScale
export let scale = 1;
export let minScale: number;
export let maxScale: number;
export let src: string;
let mouseStartX: number;
Expand All @@ -36,9 +38,6 @@
let x = 0;
let y = 0;
// between minScale and maxScale
let scale = 1;
$: applyLimits(), scale;
// If the image is currently grabbed
Expand Down Expand Up @@ -125,7 +124,7 @@
scale = Math.min(Math.max(minScale, scale), maxScale);
}
export function calculateResult() {
export function calculateResult(callback: BlobCallback) {
if (!moveable) return;
const canvas = document.createElement('canvas');
Expand Down Expand Up @@ -155,7 +154,7 @@
ctx.drawImage(moveable, xrl, yrt, rw, rh, ox, oy, rw, rh);
return canvas.toDataURL('image/png');
canvas.toBlob(callback, "image/png");
}
function updateAspectRatio() {
Expand All @@ -167,52 +166,30 @@

<svelte:window on:mousemove={mouseMove} on:mouseup={mouseUp} />

<div class="content">
<div class="images">
<div class="wrapper" style="--size: {size}px">
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<img class="moveable" src={src} bind:this={moveable} draggable="false" on:mousedown={mouseDown} on:wheel={wheel} on:load={updateAspectRatio} class:wide={aspectRatio > 1} class:high={aspectRatio < 1} style="--scale: {scale}; --x: {x * size}px; --y: {y * size}px" alt="upload a file" />
{#if overlay}
<div class="mask"></div>
{/if}
{#if gridOverlay}
<div class="grid">
<div></div>
<div class="y-axis"></div>
<div></div>
<div class="x-axis"></div>
<div class="center"></div>
<div class="x-axis"></div>
<div></div>
<div class="y-axis"></div>
<div></div>
</div>
{/if}
<div class="wrapper" style="--size: {size}px">
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<img class="moveable" src={src} bind:this={moveable} draggable="false" on:mousedown={mouseDown} on:wheel={wheel} on:load={updateAspectRatio} class:wide={aspectRatio > 1} class:high={aspectRatio < 1} style="--scale: {scale}; --x: {x * size}px; --y: {y * size}px" alt="upload a file" />
{#if overlay}
<div class="mask"></div>
{/if}
{#if gridOverlay}
<div class="grid">
<div></div>
<div class="y-axis"></div>
<div></div>
<div class="x-axis"></div>
<div class="center"></div>
<div class="x-axis"></div>
<div></div>
<div class="y-axis"></div>
<div></div>
</div>
</div>
{/if}
</div>

<style lang="scss">
@import "../../assets/styles/variables.scss";
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100vw;
height: 100%;
}
.images {
display: flex;
justify-content: center;
gap: 2rem;
width: 100%;
margin-bottom: 2rem;
margin: 5rem;
}
.wrapper {
width: var(--size);
height: var(--size);
Expand All @@ -230,7 +207,7 @@
left: 0;
bottom: 0;
right: 0;
background: radial-gradient(transparent 70.5%, rgba(0, 0, 0, 0.75) 70.5%);
background: radial-gradient(transparent 70.5%, rgba(0, 0, 0, 0.5) 70.5%);
pointer-events: none;
&:after {
Expand All @@ -240,7 +217,7 @@
left: 0;
bottom: 0;
right: 0;
border: 5px solid white;
border: 2px solid white;
border-radius: 50%;
pointer-events: none;
}
Expand Down Expand Up @@ -285,15 +262,19 @@
transform: translate(var(--x), var(--y)) scale(var(--scale));
min-width: 100%;
min-height: 100%;
max-width: 100%;
max-height: 100%;
&.wide {
min-width: 100%;
max-width: unset;
max-height: 100%;
}
&.high {
min-height: 100%;
max-width: 100%;
max-height: unset;
}
}
</style>
Loading

0 comments on commit 8c0bcca

Please sign in to comment.