这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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