lapsha/src/App.vue

142 lines
5.0 KiB
Vue

<script setup lang="ts">
import Sidebar from "./components/Sidebar.vue";
import SidebarBlock from "./components/SidebarBlock.vue";
import ButtonsBar from "./components/ButtonsBar.vue";
import Button from "./components/Button.vue";
import Page from "./components/Page.vue";
import Input from "./components/Input.vue";
import Canvas from "./components/Canvas.vue";
import Switch from './components/Switch.vue';
import Container from './components/Container.vue';
import { ButtonSize, InputType } from "./types";
import { useStore } from "./store";
import { storeToRefs } from "pinia";
import { VARIANTS_VERTICAL_ROTATION, VARIANTS_IMAGE_SIZE } from './const';
import { ref } from "vue";
const store = useStore();
const {
imageBackgroundColor,
vMargin,
vRotation,
hMargin,
hMargin2,
marginEnable,
marginColor,
marginLeftMargin,
imageWidth,
imageHeight,
} = storeToRefs(store);
const typeSelector = ref('rus');
const savePng = async () => {
const canvas = document.getElementById("canvas") as HTMLCanvasElement;
if (canvas) {
const image = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.setAttribute("download", "image.png");
link.href = image;
link.click();
}
};
</script>
<template>
<Container>
<Sidebar>
<SidebarBlock title="Фон">
<Input v-model="imageBackgroundColor" :type="InputType.Color">Цвет {{ store.imageBackgroundColor }}</Input>
</SidebarBlock>
<div v-if="typeSelector == 'rus'">
<SidebarBlock title="Вертикальные линии">
<Input v-model="vMargin" :min="1">Отступ, мм</Input>
<Input v-model="vRotation" :min="0" :max="359">Поворот, градусы</Input>
<ButtonsBar>
<Button v-for="deg in VARIANTS_VERTICAL_ROTATION" :key="deg" :active="vRotation == deg"
:size="ButtonSize.Small" :click="() => store.setVRotation(deg)">
{{ deg }}°
</Button>
</ButtonsBar>
</SidebarBlock>
<SidebarBlock title="Горизонтальные линии">
<Input v-model="hMargin" :min="1">Отступ, мм</Input>
<Input v-model="hMargin2" :min="1">Дополнительный отступ, мм</Input>
</SidebarBlock>
<SidebarBlock title="Поля">
<Switch v-model="marginEnable" />
<div v-if="marginEnable">
<Input v-model="marginColor" :type="InputType.Color">
Цвет {{ marginColor }}
</Input>
<Input v-model="marginLeftMargin" :min="1">Отступ слева, мм</Input>
</div>
</SidebarBlock>
</div>
</Sidebar>
<Page>
<div id="typeSelector">
<Button :size="ButtonSize.Small"
:active="typeSelector == 'rus' && vRotation == 65 && vMargin == 15 && hMargin == 40 && hMargin2 == 20 && imageWidth == 210 && imageHeight == 297"
:click="() => {
typeSelector = 'rus';
vRotation = 65;
vMargin = 15;
hMargin = 40;
hMargin2 = 20;
imageWidth = 210;
imageHeight = 297;
}">Тетрадь в линию</Button>
<Button :size="ButtonSize.Small"
:active="typeSelector == 'rus' && vRotation == 90 && vMargin == 30 && hMargin == 30 && hMargin2 == 30 && imageWidth == 210 && imageHeight == 297"
:click="() => {
typeSelector = 'rus';
vRotation = 90;
vMargin = 30;
hMargin = 30;
hMargin2 = 30;
imageWidth = 210;
imageHeight = 297;
}">Тетрадь в клетку</Button>
<Button :size="ButtonSize.Small" :active="typeSelector == 'rus'"
:click="() => { typeSelector = 'rus' }">Пропись</Button>
<Button :size="ButtonSize.Small" :active="typeSelector == 'math'"
:click="() => { typeSelector = 'math' }">Математика</Button>
</div>
<Canvas />
</Page>
<Sidebar horizontalPosition="right">
<SidebarBlock title="Изображение">
<Input v-model="imageHeight" :min="1">Высота, мм</Input>
<Input v-model="imageWidth" :min="1">Ширина, мм</Input>
<ButtonsBar>
<Button v-for=" size in VARIANTS_IMAGE_SIZE " :key="size.name" :size="ButtonSize.Small"
:active="imageWidth == size.width && imageHeight == size.height || imageWidth == size.height && imageHeight == size.width"
:click="() => store.setImageSize(size)">
{{ size.name }}
</Button>
<Button :size="ButtonSize.Small" :click="store.rotateImage">
Повернуть
</Button>
</ButtonsBar>
<ButtonsBar>
<Button :click="savePng">Сохранить как png</Button>
</ButtonsBar>
</SidebarBlock>
</Sidebar>
</Container>
</template>
<style scoped>
#typeSelector {
display: flex;
justify-content: center;
margin-top: 20px;
}
</style>