diff --git a/frontend/src/templates.js b/frontend/src/templates.js index 91e1555652721d76324de839e4883a54847629af..6493ba9caac57feb60363ecd6694c8422aaebc01 100644 --- a/frontend/src/templates.js +++ b/frontend/src/templates.js @@ -6,6 +6,8 @@ import newspaperQuoteBottomImage from './assets/previews/newspaper_quote_bottom. import newspaperQuoteMiddleImage from './assets/previews/newspaper_quote_middle.png' import facebookSurveyImage from './assets/previews/facebook_survey.png' import twitterBannerImage from './assets/previews/twitter_banner.png' +import posterImage from './assets/previews/basic_photo_banner.png' + const TEMPLATES = { basic_photo_banner: { @@ -71,6 +73,15 @@ const TEMPLATES = { title: 'Facebook anketa', } }, + poster: { + name: 'Plakát', + image: posterImage, + path: '/poster', + component: () => import('./views/poster/Poster.vue'), + meta: { + title: 'Plakát' + } + }, twitter_banner: { name: 'Twitter banner', image: twitterBannerImage, diff --git a/frontend/src/views/poster/Poster.vue b/frontend/src/views/poster/Poster.vue new file mode 100644 index 0000000000000000000000000000000000000000..935283ee0dfd9bae799526c32099d8331f26aa52 --- /dev/null +++ b/frontend/src/views/poster/Poster.vue @@ -0,0 +1,266 @@ +<script setup> +import { watch, ref } from 'vue' + +import COLORS from '../../colors' +import PEOPLE from '../../people' +import TEMPLATES from '../../templates' +import DEFAULT_CONTRACTOR from '../../contractors' +import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils' + +import Canvas from '../../components/canvas/Canvas.vue' +import redraw from './canvas' + +import Navbar from '../../components/Navbar.vue' +import MainContainer from '../../components/MainContainer.vue' +import ImageInput from '../../components/inputs/ImageInput.vue' +import LongTextInput from '../../components/inputs/text/LongTextInput.vue' +import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue' +import RangeInput from '../../components/inputs/RangeInput.vue' +import InputSeparator from '../../components/inputs/InputSeparator.vue' +import SelectInput from '../../components/inputs/SelectInput.vue' +import MultipleColorPicker from '../../components/inputs/colors/MultipleColorPicker.vue' +import ReloadButton from '../../components/reload/ReloadButton.vue' +import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue' +</script> + +<script> +await loadFonts([ + '12px Bebas Neue', + '12px Roboto Condensed', + 'bold 12px Roboto Condensed' +]) + +export default { + components: { + Canvas, + Navbar, + MainContainer, + ImageInput, + LongTextInput, + ShortTextInput, + RangeInput, + SelectInput, + InputSeparator, + MultipleColorPicker + }, + data () { + const predefinedColors = { + base: { + name: 'Základní barvy', + colors: { + background: COLORS.black, + highlight: COLORS.yellow1, + arrow: COLORS.yellow1, + baseText: COLORS.white, + highlightedText: COLORS.black, + contractedByText: COLORS.gray1 + } + } + } + + return { + mainImage: null, + personName: null, + + personPosition: null, + firstColumn: null, + secondColumn: null, + + socialMedia1: null, + socialMedia2: null, + socialMedia3: null, + + contractedBy: DEFAULT_CONTRACTOR, + + colorLabels: { + background: 'Pozadí', + highlight: 'Zvýraznění', + arrow: 'Šipka', + baseText: 'Text', + highlightedText: 'Zvýrazněný text' + }, + + predefinedColors: predefinedColors, + colors: predefinedColors.base.colors, + autoRedraw: false + } + }, + async created () { + await loadCanvasStorage(this) + }, + methods: { + async reloadCanvasProperties () { + const canvasProperties = { + mainImage: this.mainImage, + personName: this.personName, + personPosition: this.personPosition, + firstColumn: this.firstColumn, + secondColumn: this.secondColumn, + socialMedia1: this.socialMedia1, + socialMedia2: this.socialMedia2, + socialMedia3: this.socialMedia3, + contractedBy: this.contractedBy, + colors: this.colors + } + + await this.$refs.canvas.redraw(canvasProperties) + + delete canvasProperties.colors + setCanvasStorage(canvasProperties) + } + }, + mounted () { + this.$watch( + vm => [ + vm.mainImage, + vm.personName, + vm.personPosition, + vm.firstColumn, + vm.secondColumn, + vm.socialMedia1, + vm.socialMedia2, + vm.socialMedia3, + vm.contractedBy, + vm.colors + ], + async (value) => { + if (this.autoRedraw) { + await this.reloadCanvasProperties() + } + }, + { + immediate: true, + deep: true + } + ) + + this.$watch( + vm => [vm.autoRedraw], + async (value) => { + updateAutoRedrawStorage(this.autoRedraw) + + if (this.autoRedraw) { + await this.reloadCanvasProperties() + } + } + ) + }, +} +</script> + +<template> + <header> + <Navbar + :defaultTemplate="TEMPLATES.poster" + ></Navbar> + </header> + <main> + <MainContainer> + <template v-slot:left> + <Canvas + ref="canvas" + :redrawFunction="redraw" + width="2000" + height="2000" + /> + </template> + + <template v-slot:right> + <ReloadButton + :parentRefs="$refs" + @click="reloadCanvasProperties" + /> + <AutoReloadCheckbox + v-model="autoRedraw" + /> + <ImageInput + name="Obrázek" + v-model="mainImage" + :important="true" + zIndex="10" + /> + + <ShortTextInput + name="Jméno osoby" + v-model="personName" + v-model:relatedModel="personPosition" + :predefinedValues="PEOPLE" + :important="true" + zIndex="9" + /> + <LongTextInput + ref="refPersonPosition" + name="Pozice osoby" + v-model="personPosition" + :important="false" + zIndex="8" + /> + + <LongTextInput + name="Sloupec 1" + v-model="firstColumn" + :important="true" + :highlightable="true" + zIndex="7" + /> + <LongTextInput + name="Sloupec 2" + v-model="secondColumn" + :important="true" + :highlightable="true" + zIndex="6" + /> + + <InputSeparator /> + + <ShortTextInput + name="Sociální médium 1 (např. @tvůj_instagram)" + v-model="socialMedia1" + v-model:relatedModel="socialMedia1" + :important="true" + zIndex="9" + /> + + <ShortTextInput + name="Sociální médium 2 (např. @pirati.cz)" + v-model="socialMedia2" + v-model:relatedModel="socialMedia2" + :important="true" + zIndex="8" + /> + + <ShortTextInput + name="Sociální médium 3 (např. tvuj@ema.il)" + v-model="socialMedia3" + v-model:relatedModel="socialMedia3" + :important="true" + zIndex="7" + /> + + <InputSeparator /> + + <MultipleColorPicker + name="Barvy" + v-model="colors" + :important="false" + :colorLabels="colorLabels" + :predefinedColors="predefinedColors" + :defaultPredefinedColors="predefinedColors.base" + zIndex="5" + ></MultipleColorPicker> + + <ShortTextInput + name="Zadavatel a zpracovatel" + v-model="contractedBy" + :defaultValue="DEFAULT_CONTRACTOR" + :important="false" + zIndex="4" + /> + </template> + </MainContainer> + </main> +</template> + +<style> +@import "vue-select/dist/vue-select.css"; +</style> diff --git a/frontend/src/views/poster/canvas.js b/frontend/src/views/poster/canvas.js new file mode 100644 index 0000000000000000000000000000000000000000..09aba1394f9fd6a26cc4e3ac6791279a3f5a24bc --- /dev/null +++ b/frontend/src/views/poster/canvas.js @@ -0,0 +1,17 @@ +import { fabric } from 'fabric' +import { clearObjects, sortObjects, transformHighlightedText, checkTextBoxHeight } from '../../components/canvas/utils' +import { PaddedHighlightingTextbox } from '../../components/canvas/textbox' + +const redraw = async (canvas, options) => { + clearObjects( + [ + ], + canvas + ) + + canvas.preserveObjectStacking = true + + sortObjects(canvas) +} + +export default redraw diff --git a/server/server/templates/index.html b/server/server/templates/index.html index 04621c3a8640c6fc0bc78961536cf1ce2ebe0a94..b895de36b757c249aedee5e42bf22f5ab9f72e15 100644 --- a/server/server/templates/index.html +++ b/server/server/templates/index.html @@ -5,12 +5,20 @@ <link rel="icon" href="/static/favicon.ico"> <link rel="stylesheet" href="https://styleguide.pirati.cz/2.12.x/css/styles.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <script> + ;(function () { + var src = '//cdn.jsdelivr.net/npm/eruda'; + if (!/eruda=true/.test(window.location) && localStorage.getItem('active-eruda') != 'true') return; + document.write('<scr' + 'ipt src="' + src + '"></scr' + 'ipt>'); + document.write('<scr' + 'ipt>eruda.init();</scr' + 'ipt>'); + })(); + </script> <title>Generátor grafiky</title> - <script type="module" crossorigin src="/static/index-5f383c1e.js"></script> - <link rel="stylesheet" href="/static/index-ba72a822.css"> + <script type="module" crossorigin src="/static/index-ec81bc4e.js"></script> + <link rel="stylesheet" href="/static/index-636cacf0.css"> </head> <body> <div id="app"></div> - + </body> </html>