refactoring
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
c99d41fd53
commit
2e3f3dcc99
147
src/App.vue
147
src/App.vue
|
@ -1,60 +1,82 @@
|
|||
<script setup lang="ts">
|
||||
import Sidebar from './components/Sidebar.vue';
|
||||
import Page from './components/Page.vue';
|
||||
import Input from './components/Input.vue';
|
||||
import Canvas from './components/Canvas.vue';
|
||||
import { ref } from 'vue';
|
||||
import { DEFAULT_HORIZONTAL_MARGIN, DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH, DEFAULT_VERTICAL_MARGIN, DEFAULT_IMAGE_BACKGROUND_COLOR } from './const';
|
||||
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 { ref } from "vue";
|
||||
import {
|
||||
DEFAULT_HORIZONTAL_MARGIN,
|
||||
DEFAULT_IMAGE_HEIGHT,
|
||||
DEFAULT_IMAGE_WIDTH,
|
||||
DEFAULT_VERTICAL_MARGIN,
|
||||
DEFAULT_IMAGE_BACKGROUND_COLOR,
|
||||
} from "./const";
|
||||
import { ButtonSize, InputType } from "./types";
|
||||
|
||||
const vMargin = ref(DEFAULT_VERTICAL_MARGIN)
|
||||
const hMargin = ref(DEFAULT_HORIZONTAL_MARGIN)
|
||||
const imageWidth = ref(DEFAULT_IMAGE_WIDTH)
|
||||
const imageHeight = ref(DEFAULT_IMAGE_HEIGHT)
|
||||
const imageBackgroundColor = ref(DEFAULT_IMAGE_BACKGROUND_COLOR)
|
||||
const vMargin = ref(DEFAULT_VERTICAL_MARGIN);
|
||||
const hMargin = ref(DEFAULT_HORIZONTAL_MARGIN);
|
||||
const imageWidth = ref(DEFAULT_IMAGE_WIDTH);
|
||||
const imageHeight = ref(DEFAULT_IMAGE_HEIGHT);
|
||||
const imageBackgroundColor = ref(DEFAULT_IMAGE_BACKGROUND_COLOR);
|
||||
|
||||
const savePng = async () => {
|
||||
const canvas = document.getElementById("canvas") as HTMLCanvasElement;
|
||||
|
||||
if (canvas) {
|
||||
const image = canvas.toDataURL("image/png")
|
||||
const image = canvas.toDataURL("image/png");
|
||||
const link = document.createElement("a");
|
||||
link.setAttribute("download", "image.png");
|
||||
link.href = image
|
||||
link.href = image;
|
||||
link.click();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const rotatePage = () => {
|
||||
const tmp = imageHeight.value;
|
||||
imageHeight.value = imageWidth.value;
|
||||
imageWidth.value = tmp;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<Sidebar>
|
||||
<div class="l-sidebar-block">
|
||||
<h1>Фон</h1>
|
||||
<div class="input">
|
||||
<label class="l-label">
|
||||
<SidebarBlock title="Фон">
|
||||
<Input v-model="imageBackgroundColor" :type="InputType.Color">
|
||||
Цвет {{ imageBackgroundColor }}
|
||||
</label>
|
||||
<br>
|
||||
<input class="l-input" type="color" v-model="imageBackgroundColor">
|
||||
</div>
|
||||
</div>
|
||||
<div class="l-sidebar-block">
|
||||
<h1>Линии</h1>
|
||||
</Input>
|
||||
</SidebarBlock>
|
||||
<SidebarBlock title="Линии">
|
||||
<Input v-model="vMargin">Отступ по горизонтали, мм</Input>
|
||||
<Input v-model="hMargin">Отступ по вертикали, мм</Input>
|
||||
</div>
|
||||
<div class="l-sidebar-block">
|
||||
<h1>Изображение</h1>
|
||||
</SidebarBlock>
|
||||
<SidebarBlock title="Изображение">
|
||||
<Input v-model="imageHeight">Высота, мм</Input>
|
||||
<Input v-model="imageWidth">Ширина, мм</Input>
|
||||
<div class="l-mini-buttons-bar">
|
||||
<button class="l-base-button l-mini-button" @click="imageWidth = 148; imageHeight = 210">A5</button>
|
||||
<button class="l-base-button l-mini-button" @click="imageWidth = 210; imageHeight = 297">A4</button>
|
||||
<button class="l-base-button l-mini-button"
|
||||
@click="var tmp; tmp = imageHeight; imageHeight = imageWidth; imageWidth = tmp">Повернуть</button>
|
||||
</div>
|
||||
<button class="l-base-button l-button" @click="savePng">Сохранить как png</button>
|
||||
</div>
|
||||
<ButtonsBar>
|
||||
<Button :size="ButtonSize.Small" :click="() => {
|
||||
imageWidth = 148;
|
||||
imageHeight = 210;
|
||||
}
|
||||
">
|
||||
A5
|
||||
</Button>
|
||||
<Button :size="ButtonSize.Small" :click="() => {
|
||||
imageWidth = 210;
|
||||
imageHeight = 297;
|
||||
}
|
||||
">
|
||||
A4
|
||||
</Button>
|
||||
<Button :size="ButtonSize.Small" :click="rotatePage">
|
||||
Повернуть
|
||||
</Button>
|
||||
</ButtonsBar>
|
||||
<Button :click="savePng">Сохранить как png</Button>
|
||||
</SidebarBlock>
|
||||
</Sidebar>
|
||||
<Page>
|
||||
<Canvas :vMargin="vMargin" :hMargin="hMargin" :imageWidth="imageWidth" :imageHeight="imageHeight"
|
||||
|
@ -83,57 +105,4 @@ html {
|
|||
body {
|
||||
background-color: aqua;
|
||||
}
|
||||
|
||||
.l-base-button {
|
||||
color: #22333B;
|
||||
background-color: #EAE0D5;
|
||||
border: 1px solid #5E503F;
|
||||
}
|
||||
|
||||
.l-base-button:hover {
|
||||
background-color: #d7c7b6;
|
||||
}
|
||||
|
||||
.l-button {
|
||||
border-radius: 10px;
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.l-mini-button {
|
||||
border-radius: 3px;
|
||||
margin: 3px;
|
||||
padding: 2px 10px;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'MPLUS1p';
|
||||
font-style: normal;
|
||||
src: local('MPLUS1p'), url(/fonts/ttf/MPLUS1p-Light.ttf) format('truetype');
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #C6AC8F;
|
||||
}
|
||||
|
||||
.l-sidebar-block {
|
||||
border: 1px solid #C6AC8F;
|
||||
border-radius: 10px;
|
||||
margin: 0 0 30px 0;
|
||||
padding: 20px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.l-mini-buttons-bar {
|
||||
padding: 0 0 20px 5px;
|
||||
}
|
||||
|
||||
.input {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.l-input {
|
||||
margin: 10px 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<script setup lang="ts">
|
||||
import { ButtonSize } from '../types';
|
||||
|
||||
interface Props {
|
||||
click: (payload?: MouseEvent) => void;
|
||||
size?: ButtonSize;
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
size: ButtonSize.Medium,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
:class="{
|
||||
button: true,
|
||||
'button--small': size === ButtonSize.Small,
|
||||
}"
|
||||
@click="click"
|
||||
>
|
||||
<slot></slot>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.button {
|
||||
border-radius: 10px;
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
color: #22333B;
|
||||
background-color: #EAE0D5;
|
||||
border: 1px solid #5E503F;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #d7c7b6;
|
||||
}
|
||||
|
||||
.button--small {
|
||||
border-radius: 3px;
|
||||
margin: 3px;
|
||||
padding: 2px 10px;
|
||||
font-size: 10pt;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,11 @@
|
|||
<template>
|
||||
<div class="buttons-bar">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.buttons-bar {
|
||||
padding: 0 0 20px 5px;
|
||||
}
|
||||
</style>
|
|
@ -1,19 +1,33 @@
|
|||
<script setup lang="ts">
|
||||
import { InputType } from '../types';
|
||||
|
||||
interface Props {
|
||||
type: InputType;
|
||||
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
type: InputType.Number,
|
||||
})
|
||||
|
||||
const modelValue = defineModel();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="input">
|
||||
<label class="l-label">
|
||||
<div class="input-container">
|
||||
<label class="label">
|
||||
<slot></slot>
|
||||
</label>
|
||||
<br>
|
||||
<input class="l-input" type="number" v-model="modelValue" />
|
||||
<br />
|
||||
<input :class="{
|
||||
input: true,
|
||||
'input--color': type === InputType.Color,
|
||||
}" :type="type" v-model="modelValue" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.input {
|
||||
.input-container {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
|
@ -21,10 +35,19 @@ input {
|
|||
border: #333 1px solid;
|
||||
}
|
||||
|
||||
.l-input {
|
||||
.input {
|
||||
margin: 10px 0;
|
||||
border: 1px solid #C6AC8F;
|
||||
border: 1px solid #c6ac8f;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.input--color {
|
||||
padding: 0;
|
||||
background-color: v-bind(modelValue);
|
||||
}
|
||||
|
||||
.input--color::-webkit-color-swatch {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
title: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="sidebar-block">
|
||||
<h1>{{ title }}</h1>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.sidebar-block {
|
||||
border: 1px solid #c6ac8f;
|
||||
border-radius: 10px;
|
||||
margin: 0 0 30px 0;
|
||||
padding: 20px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #c6ac8f;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,5 @@
|
|||
@font-face {
|
||||
font-family: "MPLUS1p";
|
||||
font-style: normal;
|
||||
src: local("MPLUS1p"), url(/fonts/ttf/MPLUS1p-Light.ttf) format("truetype");
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
export enum ButtonSize {
|
||||
Small = 'small',
|
||||
Medium = 'medium',
|
||||
}
|
||||
|
||||
export enum InputType {
|
||||
Number = 'number',
|
||||
Color = 'color',
|
||||
}
|
Loading…
Reference in New Issue