From 414cfb4c116f2997770a09db43290151f3daa017 Mon Sep 17 00:00:00 2001 From: Florian Sorg Date: Fri, 19 Apr 2024 23:12:26 +0200 Subject: [PATCH] feat(frontend): add paper size selector --- .../canvas-page/canvas-page.component.html | 36 ++++++++++- .../canvas-page/canvas-page.component.scss | 61 +++++++++++++++--- .../app/canvas-page/canvas-page.component.ts | 51 +++++++++++++-- frontend/src/app/data/paper-sizes.ts | 63 +++++++++++++++++++ frontend/src/styles.scss | 2 - 5 files changed, 196 insertions(+), 17 deletions(-) create mode 100644 frontend/src/app/data/paper-sizes.ts diff --git a/frontend/src/app/canvas-page/canvas-page.component.html b/frontend/src/app/canvas-page/canvas-page.component.html index 5032800..9e2c08c 100644 --- a/frontend/src/app/canvas-page/canvas-page.component.html +++ b/frontend/src/app/canvas-page/canvas-page.component.html @@ -1,8 +1,40 @@ +
+ +
+ + + +
+ + + {{ size.width }} × {{ size.height }} mm [{{ size.shape }}] + +
+ + + {{ paperSize.width }} × {{ paperSize.height }} mm [{{ paperSize.shape }}] + +
+
-
- +
+ +
+
+
+
diff --git a/frontend/src/app/canvas-page/canvas-page.component.scss b/frontend/src/app/canvas-page/canvas-page.component.scss index f441666..c8a44e4 100644 --- a/frontend/src/app/canvas-page/canvas-page.component.scss +++ b/frontend/src/app/canvas-page/canvas-page.component.scss @@ -1,15 +1,43 @@ -.canvas-frame { - border: 2px solid #888; - border-radius: 20px; - background: #fff; - overflow: hidden; -} - .canvas-wrapper { display: flex; justify-content: center; } + +.canvas-frame { + position: relative; + border-radius: 15px; + overflow: hidden; + + .canvas-mask { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + display: flex; + flex-direction: row; + justify-content: stretch; + gap: 15px; + pointer-events: none; + } + + .label { + flex: 1; + border: 2px solid rgba(0,0,0,0.5); + border-radius: 15px; + } + + &[data-shape="circular"] { + border-radius: 50%; + + .label { + border-radius: 50%; + } + } +} + + .controls { padding: 0.5em 0; } @@ -55,3 +83,22 @@ justify-content: center; gap: 1em; } + +.paper { + padding-bottom: 1em; +} + +.paper-size-form { + display: flex; + flex-direction: row; + gap: 0.3em; + margin: 0 0 1em; + + label { + width: 70px; + + input { + width: 100%; + } + } +} diff --git a/frontend/src/app/canvas-page/canvas-page.component.ts b/frontend/src/app/canvas-page/canvas-page.component.ts index a08404a..3463fab 100644 --- a/frontend/src/app/canvas-page/canvas-page.component.ts +++ b/frontend/src/app/canvas-page/canvas-page.component.ts @@ -1,8 +1,8 @@ import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core'; import {fabric} from 'fabric'; -import {FormBuilder, FormGroup, ReactiveFormsModule} from '@angular/forms'; +import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms'; import {CheckboxModule} from 'primeng/checkbox'; -import {NgIf} from '@angular/common'; +import {NgForOf, NgIf} from '@angular/common'; import {SliderModule} from 'primeng/slider'; import {ButtonModule} from 'primeng/button'; import {HttpClient} from '@angular/common/http'; @@ -11,6 +11,13 @@ import {ChipModule} from 'primeng/chip'; import {DropdownModule} from 'primeng/dropdown'; import {MessageService} from 'primeng/api'; import {ToastModule} from 'primeng/toast'; +import {PaperShape, PaperSize, SIZES} from '../data/paper-sizes'; +import {OverlayPanelModule} from 'primeng/overlaypanel'; +import {InputTextModule} from 'primeng/inputtext'; + +const getPx = (mm: number, dpi: number) => { + return mm / 25.4 * dpi; +} @Component({ selector: 'app-canvas-page', @@ -23,7 +30,10 @@ import {ToastModule} from 'primeng/toast'; ButtonModule, ChipModule, DropdownModule, - ToastModule + ToastModule, + OverlayPanelModule, + NgForOf, + InputTextModule ], templateUrl: './canvas-page.component.html', styleUrl: './canvas-page.component.scss' @@ -34,14 +44,26 @@ export class CanvasPageComponent implements AfterViewInit { public fabric?: fabric.Canvas; public ctx?: CanvasRenderingContext2D; public form: FormGroup; - public width = 323; - public height = 240; + public paperSizeForm: FormGroup; + public width = 0; + public height = 0; public fonts = [ 'Noto Sans', 'Noto Serif', 'Comic Sans MS' ] + public set paperSize(size: PaperSize) { + this.paperSizeForm.setValue(size); + } + + public get paperSize(): PaperSize { + return this.paperSizeForm.value; + } + + protected readonly PaperShape = PaperShape; + protected readonly SIZES = SIZES; + constructor( private formBuilder: FormBuilder, private httpClient: HttpClient, @@ -53,6 +75,23 @@ export class CanvasPageComponent implements AfterViewInit { fontSize: [30], fontFamily: [this.fonts[0]] }); + + this.paperSizeForm = this.formBuilder.group({ + width: [null, [Validators.required]], + height: [null, [Validators.required]], + dpi: [null, [Validators.required]], + shape: [null, [Validators.required]] + }); + + this.paperSizeForm.valueChanges.subscribe(size => { + this.width = getPx(size.width, size.dpi); + this.height = getPx(size.height, size.dpi); + this.fabric?.setWidth(this.width); + this.fabric?.setHeight(this.height); + this.fabric?.renderAll(); + }) + + this.paperSize = SIZES[0]; } public ngAfterViewInit() { @@ -107,7 +146,7 @@ export class CanvasPageComponent implements AfterViewInit { const file = (e as any).target.files[0]; const reader = new FileReader(); reader.onload = (f) => { - var data = (f as any).target.result; + const data = (f as any).target.result; fabric.Image.fromURL(data, (img) => { const oImg = img.set({left: 0, top: 0, angle: 0}); const scale = Math.min(1, this.width / Number(oImg.width), this.height / Number(oImg.height)); diff --git a/frontend/src/app/data/paper-sizes.ts b/frontend/src/app/data/paper-sizes.ts new file mode 100644 index 0000000..aa42bd3 --- /dev/null +++ b/frontend/src/app/data/paper-sizes.ts @@ -0,0 +1,63 @@ +export enum PaperShape { + Rectangular = 'rectangular', + Circular = 'circular', + Split = 'split' +} + +export interface PaperSize { + width: number, // in mm + height: number, // in mm + dpi: number, + shape: PaperShape, +} + +export const SIZES: PaperSize[] = [ + { + shape: PaperShape.Rectangular, + width: 40, + height: 30, + dpi: 204 + }, + { + shape: PaperShape.Rectangular, + width: 50, + height: 20, + dpi: 204 + }, + { + shape: PaperShape.Rectangular, + width: 30, + height: 20, + dpi: 204 + }, + { + shape: PaperShape.Rectangular, + width: 40, + height: 40, + dpi: 204 + }, + { + shape: PaperShape.Rectangular, + width: 50, + height: 50, + dpi: 204 + }, + { + shape: PaperShape.Circular, + width: 40, + height: 40, + dpi: 204 + }, + { + shape: PaperShape.Circular, + width: 50, + height: 50, + dpi: 204 + }, + { + shape: PaperShape.Split, + width: 42, + height: 10, + dpi: 204 + }, +]; diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 57748a1..d7a6311 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -7,7 +7,5 @@ html { } body { - max-width: 550px; - margin: 0 auto; padding: 1em; }