Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 75f9590e45 |
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
- 프로젝트명: 10 Minute Planner 웹 UI
|
- 프로젝트명: 10 Minute Planner 웹 UI
|
||||||
- 기술 스택: Vue 3 + Vite + TailwindCSS + JavaScript
|
- 기술 스택: Vue 3 + Vite + TailwindCSS + JavaScript
|
||||||
- 현재 기준 버전: `v0.1.2`
|
- 현재 기준 버전: `v0.1.3`
|
||||||
|
|
||||||
## 기준 디자인
|
## 기준 디자인
|
||||||
|
|
||||||
@@ -49,6 +49,8 @@
|
|||||||
- `PRINT 2-UP`은 현재 날짜와 다음 날짜를 A4 가로 기준으로 나란히 출력하는 용도다.
|
- `PRINT 2-UP`은 현재 날짜와 다음 날짜를 A4 가로 기준으로 나란히 출력하는 용도다.
|
||||||
- 인쇄는 일반 화면을 그대로 찍는 방식이 아니라, 별도의 `print-only` 전용 레이아웃을 사용한다.
|
- 인쇄는 일반 화면을 그대로 찍는 방식이 아니라, 별도의 `print-only` 전용 레이아웃을 사용한다.
|
||||||
- A5 원본 비율을 유지한 채 A4 가로 안에 들어가도록 `1-UP` / `2-UP` 각각 별도 배율로 압축한다.
|
- A5 원본 비율을 유지한 채 A4 가로 안에 들어가도록 `1-UP` / `2-UP` 각각 별도 배율로 압축한다.
|
||||||
|
- `PRINT 1-UP`은 A4 세로, `PRINT 2-UP`은 A4 가로 기준으로 분리해서 처리한다.
|
||||||
|
- 브라우저 기본 인쇄 머리말/꼬리말이 켜져 있어도 2장으로 넘어가지 않도록 실제 인쇄 영역은 종이보다 조금 작게 잡는다.
|
||||||
|
|
||||||
## 확정된 결정사항
|
## 확정된 결정사항
|
||||||
|
|
||||||
|
|||||||
1
TODO.md
1
TODO.md
@@ -72,6 +72,7 @@
|
|||||||
- [ ] 공유가 아닌 개인 보관용 서비스 흐름으로 요구사항을 정리한다.
|
- [ ] 공유가 아닌 개인 보관용 서비스 흐름으로 요구사항을 정리한다.
|
||||||
- [x] 향후 출력 기능을 위한 인쇄 레이아웃 요구사항을 정리한다.
|
- [x] 향후 출력 기능을 위한 인쇄 레이아웃 요구사항을 정리한다.
|
||||||
- [x] A4 가로 기준 2장 출력 모드를 지원한다.
|
- [x] A4 가로 기준 2장 출력 모드를 지원한다.
|
||||||
|
- [x] `1-UP` 세로 인쇄 / `2-UP` 가로 인쇄 기준을 분리한다.
|
||||||
- [ ] 공유를 위한 이미지 저장 기능을 추가한다.
|
- [ ] 공유를 위한 이미지 저장 기능을 추가한다.
|
||||||
|
|
||||||
## 메모
|
## 메모
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ten-minute-planner",
|
"name": "ten-minute-planner",
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ten-minute-planner",
|
"name": "ten-minute-planner",
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vue": "^3.5.13"
|
"vue": "^3.5.13"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ten-minute-planner",
|
"name": "ten-minute-planner",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
22
src/App.vue
22
src/App.vue
@@ -21,6 +21,7 @@ const hours = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const timetableCellCount = hours.length * 6
|
const timetableCellCount = hours.length * 6
|
||||||
|
let printPageStyleElement = null
|
||||||
|
|
||||||
function createEmptyTimetable() {
|
function createEmptyTimetable() {
|
||||||
return Array.from({ length: timetableCellCount }, () => false)
|
return Array.from({ length: timetableCellCount }, () => false)
|
||||||
@@ -601,8 +602,29 @@ function clearTaskLabels(record) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function applyPrintPageStyle(layout) {
|
||||||
|
if (typeof document === 'undefined') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageRule =
|
||||||
|
layout === 'double'
|
||||||
|
? '@page { size: A4 landscape; margin: 0; }'
|
||||||
|
: '@page { size: A4 portrait; margin: 0; }'
|
||||||
|
|
||||||
|
if (!printPageStyleElement) {
|
||||||
|
printPageStyleElement = document.createElement('style')
|
||||||
|
printPageStyleElement.setAttribute('data-print-page-style', 'true')
|
||||||
|
document.head.appendChild(printPageStyleElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
printPageStyleElement.textContent = pageRule
|
||||||
|
document.body.dataset.printLayout = layout
|
||||||
|
}
|
||||||
|
|
||||||
async function printSelectedPlanner(layout = 'single') {
|
async function printSelectedPlanner(layout = 'single') {
|
||||||
printLayout.value = layout
|
printLayout.value = layout
|
||||||
|
applyPrintPageStyle(layout)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
window.print()
|
window.print()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
@page {
|
|
||||||
size: A4 landscape;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
background: #ffffff !important;
|
background: #ffffff !important;
|
||||||
@@ -53,24 +48,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.print-paper {
|
.print-paper {
|
||||||
width: 297mm;
|
|
||||||
height: 210mm;
|
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: #ffffff !important;
|
background: #ffffff !important;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-print-layout='single'] .print-paper {
|
||||||
|
width: 202mm;
|
||||||
|
height: 289mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-paper--double {
|
.print-paper--double {
|
||||||
display: grid !important;
|
display: grid !important;
|
||||||
grid-template-columns: repeat(2, 148mm);
|
grid-template-columns: repeat(2, 143mm);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-paper--single .print-sheet-frame {
|
body[data-print-layout='double'] .print-paper {
|
||||||
|
width: 289mm;
|
||||||
|
height: 202mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-print-layout='single'] .print-paper--single .print-sheet-frame {
|
||||||
width: 148mm;
|
width: 148mm;
|
||||||
height: 210mm;
|
height: 210mm;
|
||||||
}
|
}
|
||||||
@@ -83,29 +87,29 @@
|
|||||||
background: #ffffff !important;
|
background: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-paper--double .print-sheet-frame {
|
body[data-print-layout='double'] .print-paper--double .print-sheet-frame {
|
||||||
width: 148.5mm;
|
width: 143mm;
|
||||||
height: 210mm;
|
height: 202mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
.planner-sheet {
|
.planner-sheet {
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-paper--single .print-sheet-frame .planner-sheet {
|
body[data-print-layout='single'] .print-paper--single .print-sheet-frame .planner-sheet {
|
||||||
width: 762px !important;
|
width: 762px !important;
|
||||||
max-width: none !important;
|
max-width: none !important;
|
||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
transform: scale(0.732);
|
transform: scale(0.718);
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
background: #ffffff !important;
|
background: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-paper--double .print-sheet-frame .planner-sheet {
|
body[data-print-layout='double'] .print-paper--double .print-sheet-frame .planner-sheet {
|
||||||
width: 762px !important;
|
width: 762px !important;
|
||||||
max-width: none !important;
|
max-width: none !important;
|
||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
transform: scale(0.731);
|
transform: scale(0.703);
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
background: #ffffff !important;
|
background: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user