Skip to content

Commit

Permalink
feat: add confirmModal ui
Browse files Browse the repository at this point in the history
  • Loading branch information
fabienwnklr committed Jan 15, 2024
1 parent 61315b8 commit f2a46e8
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 66 deletions.
53 changes: 27 additions & 26 deletions src/Drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Drawer extends History {
declare $canvas: HTMLCanvasElement;
$sourceElement: HTMLElement;
$drawerContainer!: HTMLDivElement;
#dragStartLocation!: Position;
#dragStartLocation!: Position | undefined;
#snapshot!: ImageData;
#availableShape: Array<keyof typeof DrawTools> = [
'rect',
Expand Down Expand Up @@ -540,6 +540,7 @@ class Drawer extends History {
*/
setLineWidth(width: number) {
try {
// TODO : manage eraser/brush independently
this.options.lineThickness = width;
this.options.eraserThickness =
width > this.options.minEraserThickness ? width * 2 : this.options.minEraserThickness;
Expand Down Expand Up @@ -609,7 +610,7 @@ class Drawer extends History {

if (this.activeTool !== 'brush' && this.activeTool !== 'eraser' && this.options.guides) {
this._drawGuides(position);
this._drawPointerDownArc(this.#dragStartLocation);
this._drawPointerDownArc(this.#dragStartLocation as Position);
this._drawRubberBandReference(position);
}

Expand Down Expand Up @@ -650,7 +651,7 @@ class Drawer extends History {
this.ctx.fillStyle = this.options.color; // passing selectedColor as fill style
this.ctx.lineCap = this.options.cap;
const angle =
(Math.atan2(this.#dragStartLocation.y - position.y, this.#dragStartLocation.x - position.x) * 20) / Math.PI;
(Math.atan2(this.#dragStartLocation!.y - position.y, this.#dragStartLocation!.x - position.x) * 20) / Math.PI;

switch (this.activeTool) {
case 'brush':
Expand Down Expand Up @@ -708,33 +709,33 @@ class Drawer extends History {

private _drawLine({ x, y }: Position) {
this.ctx.beginPath();
this.ctx.moveTo(this.#dragStartLocation.x, this.#dragStartLocation.y);
this.ctx.moveTo(this.#dragStartLocation!.x, this.#dragStartLocation!.y);
this.ctx.lineTo(x, y);
this.ctx.stroke();
}

private _drawRect({ x, y }: Position) {
const w = x - this.#dragStartLocation.x;
const h = y - this.#dragStartLocation.y;
const w = x - this.#dragStartLocation!.x;
const h = y - this.#dragStartLocation!.y;
this.ctx.beginPath();
this.ctx.rect(this.#dragStartLocation.x, this.#dragStartLocation.y, w, h);
this.ctx.rect(this.#dragStartLocation!.x, this.#dragStartLocation!.y, w, h);
}

private _drawCircle({ x, y }: Position) {
const radius = Math.sqrt(Math.pow(this.#dragStartLocation.x - x, 2) + Math.pow(this.#dragStartLocation.y - y, 2));
const radius = Math.sqrt(Math.pow(this.#dragStartLocation!.x - x, 2) + Math.pow(this.#dragStartLocation!.y - y, 2));
this.ctx.beginPath();
this.ctx.arc(this.#dragStartLocation.x, this.#dragStartLocation.y, radius, 0, 2 * Math.PI);
this.ctx.arc(this.#dragStartLocation!.x, this.#dragStartLocation!.y, radius, 0, 2 * Math.PI);
}

private _drawArrow({ x, y }: Position) {
const angle = Math.atan2(y - this.#dragStartLocation.y, x - this.#dragStartLocation.x);
const angle = Math.atan2(y - this.#dragStartLocation!.y, x - this.#dragStartLocation!.x);
const hyp = Math.sqrt(
(x - this.#dragStartLocation.x) * (x - this.#dragStartLocation.x) +
(y - this.#dragStartLocation.y) * (y - this.#dragStartLocation.y)
(x - this.#dragStartLocation!.x) * (x - this.#dragStartLocation!.x) +
(y - this.#dragStartLocation!.y) * (y - this.#dragStartLocation!.y)
);

this.ctx.save();
this.ctx.translate(this.#dragStartLocation.x, this.#dragStartLocation.y);
this.ctx.translate(this.#dragStartLocation!.x, this.#dragStartLocation!.y);
this.ctx.rotate(angle);

// line
Expand All @@ -759,14 +760,14 @@ class Drawer extends History {
}

private _drawEllipse({ x, y }: Position) {
const w = x - this.#dragStartLocation.x;
const h = y - this.#dragStartLocation.y;
const w = x - this.#dragStartLocation!.x;
const h = y - this.#dragStartLocation!.y;
const angle = Math.atan2(y - 100, x - 100);
this.ctx.beginPath();

this.ctx.ellipse(
this.#dragStartLocation.x,
this.#dragStartLocation.y,
this.#dragStartLocation!.x,
this.#dragStartLocation!.y,
Math.abs(w),
Math.abs(h),
angle,
Expand All @@ -792,12 +793,12 @@ class Drawer extends History {

private _drawPolygon({ x, y }: Position, sides: number, angle: number) {
const coordinates = [],
radius = Math.sqrt(Math.pow(this.#dragStartLocation.x - x, 2) + Math.pow(this.#dragStartLocation.y - y, 2));
radius = Math.sqrt(Math.pow(this.#dragStartLocation!.x - x, 2) + Math.pow(this.#dragStartLocation!.y - y, 2));

for (let index = 0; index < sides; index++) {
coordinates.push({
x: this.#dragStartLocation.x + radius * Math.cos(angle),
y: this.#dragStartLocation.y - radius * Math.sin(angle),
x: this.#dragStartLocation!.x + radius * Math.cos(angle),
y: this.#dragStartLocation!.y - radius * Math.sin(angle),
});
angle += (2 * Math.PI) / sides;
}
Expand Down Expand Up @@ -878,20 +879,20 @@ class Drawer extends History {
*/
private _drawRubberBandReference({ x, y }: Position) {
const rubberBandRect: any = {};
if (this.#dragStartLocation.x < x) {
rubberBandRect.left = this.#dragStartLocation.x;
if (this.#dragStartLocation!.x < x) {
rubberBandRect.left = this.#dragStartLocation!.x;
} else {
rubberBandRect.left = x;
}

if (this.#dragStartLocation.y < y) {
rubberBandRect.top = this.#dragStartLocation.y;
if (this.#dragStartLocation!.y < y) {
rubberBandRect.top = this.#dragStartLocation!.y;
} else {
rubberBandRect.top = y;
}

rubberBandRect.width = Math.abs(this.#dragStartLocation.x - x);
rubberBandRect.height = Math.abs(this.#dragStartLocation.y - y);
rubberBandRect.width = Math.abs(this.#dragStartLocation!.x - x);
rubberBandRect.height = Math.abs(this.#dragStartLocation!.y - y);
this.ctx.save();
this.ctx.strokeStyle = 'black';
this.ctx.lineWidth = 1;
Expand Down
29 changes: 24 additions & 5 deletions src/css/drawer.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
:root {
--drawer-primary: rgba(100, 108, 255, 1);
--drawer-bg-hover: rgba(100, 108, 255, 0.4);
--drawer-primary-bg-hover: rgba(100, 108, 255, 0.4);
--drawer-neutral-bg-hover: rgba(124, 124, 124, 0.4);
--drawer-danger-bg-hover: rgba(228, 21, 21, 0.4);
--drawer-success-bg-hover: rgba(35, 156, 55, 0.4);
--drawer-primary-active-color: rgba(248, 248, 248, 1);
--drawer-primary-active-bg: rgba(79, 87, 192, 1);
--drawer-primary-active-bg-hover: rgb(93, 102, 224);
Expand Down Expand Up @@ -216,17 +219,33 @@
background-color: transparent;
}

.drawer-container .btn:not(:disabled):not(.active):hover,
.drawer-menu .btn:not(:disabled):not(.active):hover,
.drawer-modal .btn:not(:disabled):not(.active):hover {
background-color: var(--drawer-bg-hover);
.drawer-container .btn.btn-primary:not(:disabled):not(.active):hover,
.drawer-menu .btn.btn-primary:not(:disabled):not(.active):hover,
.drawer-modal .btn.btn-primary:not(:disabled):not(.active):hover {
background-color: var(--drawer-primary-bg-hover);
}

.drawer-container .btn.btn-neutral:not(:disabled):not(.active):hover,
.drawer-menu .btn.btn-neutral:not(:disabled):not(.active):hover,
.drawer-modal .btn.btn-neutral:not(:disabled):not(.active):hover {
background-color: var(--drawer-neutral-bg-hover);
}

.drawer-container .btn.btn-danger:not(:disabled):not(.active):hover,
.drawer-menu .btn.btn-danger:not(:disabled):not(.active):hover,
.drawer-modal .btn.btn-danger:not(:disabled):not(.active):hover {
background-color: var(--drawer-danger-bg-hover);
}

.drawer-container .btn:disabled,
.drawer-menu .btn:disabled .drawer-modal .btn:disabled {
cursor: not-allowed;
}

.drawer-container .p-2 {
padding: .7em;
}

.drawer-container .btn.active,
.drawer-menu .btn.active,
.drawer-modal .btn.active {
Expand Down
6 changes: 3 additions & 3 deletions src/css/modal.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
position: absolute;
background-color: #fff;
min-width: 200px;
min-height: 300px;
/* min-width: 200px; */
/* min-height: 300px; */
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
border-radius: 0.5rem;
flex-direction: column;
Expand Down Expand Up @@ -69,7 +69,7 @@
}

.drawer-modal .drawer-modal-header .btn-close:not(:disabled):hover {
background-color: var(--drawer-bg-hover);
background-color: var(--drawer-primary-bg-hover);
}

.drawer-modal .drawer-modal-body {
Expand Down
76 changes: 76 additions & 0 deletions src/ui/ConfirmModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Drawer from '../Drawer';
import { deepMerge } from '../utils/utils';
import { Modal } from './Modal';

type ConfirmModalOptions = {
message: string,
cancelLabel: string,
confirmLabel: string,
onCancel: (modal: ConfirmModal) => void,
onConfirm: (modal: ConfirmModal) => void,
}
const defaultOptions = {
message: 'Would you confirm action ?',
cancelLabel: 'Cancel',
confirmLabel: 'Confirm',
onCancel: (modal: ConfirmModal) => {
modal.hide();
},
onConfirm: (modal: ConfirmModal) => {
modal.drawer.clear();
modal.hide();
},
};

export class ConfirmModal extends Modal {
drawer: Drawer;
$cancelBtn!: HTMLButtonElement | undefined;
$confirmBtn!: HTMLButtonElement | undefined;
message: string;
cancelLabel: string;
onCancel: (modal: ConfirmModal) => void;
confirmLabel: string;
onConfirm: (modal: ConfirmModal) => void;
_options: ConfirmModalOptions;

constructor(drawer: Drawer, options: Partial<ConfirmModalOptions> = {}) {
super(drawer, { headerContent: 'Confirm' });

this._options = deepMerge<ConfirmModalOptions>(defaultOptions, options);
this.drawer = drawer;
this.message = this._options.message;
this.cancelLabel = this._options.cancelLabel;
this.onCancel = this._options.onCancel;
this.confirmLabel = this._options.confirmLabel;
this.onConfirm = this._options.onConfirm;

this.fill();
this._setupElements();
this._initEvents();
}

fill() {
this.setBodyContent(`<p class="p-2">${this.message}</p>`);
this.setFooterContent(
/*html*/ `<button id="confirm-modal-cancel-${this.drawer.options.id}" class="btn btn-neutral">${this.cancelLabel}</button><button id="confirm-modal-confirm-${this.drawer.options.id}" class="btn btn-danger">${this.confirmLabel}</button>`
);
}

private _setupElements() {
this.$cancelBtn = this.$modalFooter.querySelector(
`#confirm-modal-cancel-${this.drawer.options.id}`
) as HTMLButtonElement;
this.$confirmBtn = this.$modalFooter.querySelector(
`#confirm-modal-confirm-${this.drawer.options.id}`
) as HTMLButtonElement;
}

private _initEvents() {
this.$cancelBtn?.addEventListener('click', () => {
this.onCancel(this);
});
this.$confirmBtn?.addEventListener('click', () => {
this.onConfirm(this);
});
}
}
Loading

0 comments on commit f2a46e8

Please sign in to comment.