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