Skip to content

Commit

Permalink
Merge pull request #80 from sohnjunior/feature/canvas-save-image
Browse files Browse the repository at this point in the history
μ΄λ―Έμ§€λ‘œ μ €μž₯ν•˜κΈ° κΈ°λŠ₯을 μΆ”κ°€ν•©λ‹ˆλ‹€.
  • Loading branch information
sohnjunior authored Jun 24, 2023
2 parents cb993e4 + d10d8ba commit 723a53b
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 9 deletions.
4 changes: 4 additions & 0 deletions client/public/assets/images/download.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions client/src/components/atoms/icon/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const icon = [
'fail',
'add-circle',
'close-circle',
'download',
] as const
const size = ['small', 'medium', 'large', 'xlarge'] as const

Expand Down
2 changes: 1 addition & 1 deletion client/src/components/atoms/toast/toast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ template.innerHTML = `
}
</style>
<div class="toast-container">
<v-icon size="xlarge"></v-icon>
<v-icon size="large"></v-icon>
<div class="toast-content">
<h1>
<span id="title"></span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export default class VCanvasBackgroundLayer extends VComponent<HTMLCanvasElement
this.setAttribute('color', newValue)
}

get canvas() {
return this.$root
}

afterCreated() {
refineCanvasRatioForRetinaDisplay(this.$root)
}
Expand Down
4 changes: 4 additions & 0 deletions client/src/components/molecules/canvas-layer/drawing-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export default class VCanvasDrawingLayer extends VComponent<HTMLCanvasElement> {
return ['draw', 'erase'].includes(this.phase)
}

get canvas() {
return this.$root
}

constructor() {
super(template)
}
Expand Down
4 changes: 4 additions & 0 deletions client/src/components/molecules/canvas-layer/image-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ export default class VCanvasImageLayer extends VComponent<HTMLCanvasElement> {
return takeSnapshot(this.$root)
}

get canvas() {
return this.$root
}

constructor() {
super(template)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ template.innerHTML = `
}
</style>
<v-dialog>
<span slot="title">Confirm</span>
<span slot="content"></span>
<div slot="action">
<v-button mode="outline" id="cancel-button">μ·¨μ†Œ</v-button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { VComponent } from '@/modules/v-component'
import VCanvasBackgroundLayer from '@molecules/canvas-layer/background-layer'
import VCanvasImageLayer from '@molecules/canvas-layer/image-layer'
import VCanvasDrawingLayer from '@molecules/canvas-layer/drawing-layer'
import { getOneTimeSessionId } from '@/services/session'
import { addArchive, addOrUpdateArchive } from '@/services/archive'
import type { Archive } from '@/services/archive'
import { showToast } from '@/services/toast'
import { lastOf } from '@/utils/ramda'
import {
CanvasMetaContext,
Expand Down Expand Up @@ -34,6 +36,7 @@ template.innerHTML = `

export default class VCanvasContainer extends VComponent {
static tag = 'v-canvas-container'
private backgroundLayer!: VCanvasBackgroundLayer
private imageLayer!: VCanvasImageLayer
private drawingLayer!: VCanvasDrawingLayer

Expand Down Expand Up @@ -62,14 +65,18 @@ export default class VCanvasContainer extends VComponent {
}

private initLayer() {
const backgroundLayer = this.$shadow.querySelector<VCanvasBackgroundLayer>(
'v-canvas-background-layer'
)
const imageLayer = this.$shadow.querySelector<VCanvasImageLayer>('v-canvas-image-layer')
const drawingLayer = this.$shadow.querySelector<VCanvasDrawingLayer>('v-canvas-drawing-layer')

if (!imageLayer || !drawingLayer) {
if (!backgroundLayer || !imageLayer || !drawingLayer) {
console.error('🚨 canvas container need drawing and image layer')
return
}

this.backgroundLayer = backgroundLayer
this.imageLayer = imageLayer
this.drawingLayer = drawingLayer
}
Expand All @@ -90,6 +97,7 @@ export default class VCanvasContainer extends VComponent {
protected subscribeEventBus() {
EventBus.getInstance().on(EVENT_KEY.SAVE_ARCHIVE, this.onSaveArchive.bind(this))
EventBus.getInstance().on(EVENT_KEY.CREATE_NEW_ARCHIVE, this.onCreateNewArchive.bind(this))
EventBus.getInstance().on(EVENT_KEY.DOWNLOAD, this.onDownload.bind(this))
}

private async onSaveArchive() {
Expand Down Expand Up @@ -129,4 +137,27 @@ export default class VCanvasContainer extends VComponent {

ArchiveContext.dispatch({ action: 'FETCH_ARCHIVES_FROM_IDB' })
}

private onDownload() {
const $origin = this.backgroundLayer.canvas
const $canvas = document.createElement('canvas')
$canvas.width = $origin.width
$canvas.height = $origin.height

const ctx = $canvas.getContext('2d')
if (!ctx) {
showToast('DOWNLOAD', 'FAIL')
return
}

ctx.drawImage(this.backgroundLayer.canvas, 0, 0)
ctx.drawImage(this.imageLayer.canvas, 0, 0)
ctx.drawImage(this.drawingLayer.canvas, 0, 0)

const $link = document.createElement('a')
$link.download = 'image.png'
$link.href = $canvas.toDataURL('image/png')
$link.click()
showToast('DOWNLOAD', 'SUCCESS')
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ template.innerHTML = `
<v-icon-button data-selected="false" data-phase="stroke" icon="draw" size="medium"></v-icon-button>
<v-color-tile data-selected="false" data-phase="color" color="none" size="15px"></v-color-tile>
<v-icon-button data-selected="false" data-phase="gallery" icon="gallery" size="medium"></v-icon-button>
<v-icon-button data-selected="false" data-phase="download" icon="download" size="medium"></v-icon-button>
<v-icon-button data-selected="false" data-phase="folder" icon="folder" size="medium"></v-icon-button>
<v-stroke-menu open="false"></v-stroke-menu>
Expand Down Expand Up @@ -210,6 +211,9 @@ export default class VCanvasToolbox extends VComponent {
case 'folder':
this.enterFolderPhase()
break
case 'download':
this.enterDownloadPhase()
break
default:
break
}
Expand Down Expand Up @@ -243,6 +247,10 @@ export default class VCanvasToolbox extends VComponent {
this.handleOpenArchiveMenu()
}

enterDownloadPhase() {
EventBus.getInstance().emit(EVENT_KEY.DOWNLOAD)
}

handleChangePencilColor(ev: Event) {
const color = (ev as CustomEvent).detail.value
CanvasDrawingContext.dispatch({ action: 'SET_PENCIL_COLOR', data: color })
Expand Down
1 change: 1 addition & 0 deletions client/src/event-bus/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export const enum EVENT_KEY {
'CLEAR_ALL' = 'CLEAR_ALL',
'SHOW_TOAST' = 'SHOW_TOAST',
'SHOW_CONFIRM' = 'SHOW_CONFIRM',
'DOWNLOAD' = 'DOWNLOAD',
}
24 changes: 18 additions & 6 deletions client/src/services/toast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,51 @@ const TOAST_MESSAGE = {
ADD_ARCHIVE: {
SUCCESS: {
variant: 'success',
title: '성곡',
title: '',
description: 'μΆ”κ°€λ˜μ—ˆμŠ΅λ‹ˆλ‹€.',
},
FAIL: {
variant: 'fail',
title: 'μ‹€νŒ¨',
title: '',
description: 'μž μ‹œ 후에 λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”.',
},
},
SAVE_ARCHIVE: {
SUCCESS: {
variant: 'success',
title: '성곡',
title: '',
description: 'μ €μž₯λ˜μ—ˆμŠ΅λ‹ˆλ‹€.',
},
FAIL: {
variant: 'fail',
title: 'μ‹€νŒ¨',
title: '',
description: 'μž μ‹œ 후에 λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”.',
},
},
DELETE_ARCHIVE: {
SUCCESS: {
variant: 'success',
title: '성곡',
title: '',
description: 'μ‚­μ œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.',
},
FAIL: {
variant: 'fail',
title: 'μ‹€νŒ¨',
title: '',
description: 'μž μ‹œ 후에 λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”.',
},
},
DOWNLOAD: {
SUCCESS: {
variant: 'success',
title: '',
description: 'λ‹€μš΄λ‘œλ“œμ— μ„±κ³΅ν–ˆμŠ΅λ‹ˆλ‹€.',
},
FAIL: {
variant: 'fail',
title: '',
description: 'λ‹€μš΄λ‘œλ“œμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.',
},
},
}

export function showToast(category: keyof typeof TOAST_MESSAGE, type: 'SUCCESS' | 'FAIL') {
Expand Down

1 comment on commit 723a53b

@vercel
Copy link

@vercel vercel bot commented on 723a53b Jun 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

editty – ./

editty.vercel.app
editty-git-main-sohnjunior.vercel.app
editty-sohnjunior.vercel.app

Please sign in to comment.