Skip to content
Snippets Groups Projects
Commit 5e1647a6 authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

add twitter banner template

parent ee735ffc
No related branches found
No related tags found
No related merge requests found
Pipeline #13073 passed
Showing
with 200 additions and 216 deletions
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="/static/favicon.ico"> <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"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Generátor grafiky</title> <title>Generátor grafiky</title>
</head> </head>
......
...@@ -5,10 +5,3 @@ import { RouterView } from 'vue-router' ...@@ -5,10 +5,3 @@ import { RouterView } from 'vue-router'
<template> <template>
<RouterView /> <RouterView />
</template> </template>
<script>
const pirateStylesheet = document.createElement('link')
pirateStylesheet.rel = 'stylesheet'
pirateStylesheet.href = 'https://styleguide.pirati.cz/2.12.x/css/styles.css'
document.head.appendChild(pirateStylesheet)
</script>
frontend/src/assets/previews/twitter_banner.png

27.1 KiB

frontend/src/assets/template/twitter_banner/ivan.png

1.14 MiB | W: | H:

frontend/src/assets/template/twitter_banner/ivan.png

1.19 MiB | W: | H:

frontend/src/assets/template/twitter_banner/ivan.png
frontend/src/assets/template/twitter_banner/ivan.png
frontend/src/assets/template/twitter_banner/ivan.png
frontend/src/assets/template/twitter_banner/ivan.png
  • 2-up
  • Swipe
  • Onion skin
frontend/src/assets/template/twitter_banner/jakub.png

585 KiB | W: | H:

frontend/src/assets/template/twitter_banner/jakub.png

609 KiB | W: | H:

frontend/src/assets/template/twitter_banner/jakub.png
frontend/src/assets/template/twitter_banner/jakub.png
frontend/src/assets/template/twitter_banner/jakub.png
frontend/src/assets/template/twitter_banner/jakub.png
  • 2-up
  • Swipe
  • Onion skin
frontend/src/assets/template/twitter_banner/klara.png

879 KiB | W: | H:

frontend/src/assets/template/twitter_banner/klara.png

914 KiB | W: | H:

frontend/src/assets/template/twitter_banner/klara.png
frontend/src/assets/template/twitter_banner/klara.png
frontend/src/assets/template/twitter_banner/klara.png
frontend/src/assets/template/twitter_banner/klara.png
  • 2-up
  • Swipe
  • Onion skin
frontend/src/assets/template/twitter_banner/lipo.png

3.33 MiB | W: | H:

frontend/src/assets/template/twitter_banner/lipo.png

3.7 MiB | W: | H:

frontend/src/assets/template/twitter_banner/lipo.png
frontend/src/assets/template/twitter_banner/lipo.png
frontend/src/assets/template/twitter_banner/lipo.png
frontend/src/assets/template/twitter_banner/lipo.png
  • 2-up
  • Swipe
  • Onion skin
frontend/src/assets/template/twitter_banner/olga.png

671 KiB | W: | H:

frontend/src/assets/template/twitter_banner/olga.png

692 KiB | W: | H:

frontend/src/assets/template/twitter_banner/olga.png
frontend/src/assets/template/twitter_banner/olga.png
frontend/src/assets/template/twitter_banner/olga.png
frontend/src/assets/template/twitter_banner/olga.png
  • 2-up
  • Swipe
  • Onion skin
frontend/src/assets/template/twitter_banner/twitter.png

13.8 KiB

...@@ -4,7 +4,7 @@ import textBannerImage from './assets/previews/text_banner.png' ...@@ -4,7 +4,7 @@ import textBannerImage from './assets/previews/text_banner.png'
import newspaperQuoteBottomImage from './assets/previews/newspaper_quote_bottom.png' import newspaperQuoteBottomImage from './assets/previews/newspaper_quote_bottom.png'
import newspaperQuoteMiddleImage from './assets/previews/newspaper_quote_middle.png' import newspaperQuoteMiddleImage from './assets/previews/newspaper_quote_middle.png'
import facebookSurveyImage from './assets/previews/facebook_survey.png' import facebookSurveyImage from './assets/previews/facebook_survey.png'
import twitterBannerImage from './assets/previews/facebook_survey.png' import twitterBannerImage from './assets/previews/twitter_banner.png'
const TEMPLATES = { const TEMPLATES = {
basic_photo_banner: { basic_photo_banner: {
......
...@@ -23,7 +23,9 @@ export default { ...@@ -23,7 +23,9 @@ export default {
} }
}, },
watch: { watch: {
async selectedOption (value) { selectedOption: {
async handler (value) {
console.log(value)
const mainImage = new Image() const mainImage = new Image()
await new Promise( await new Promise(
...@@ -37,8 +39,10 @@ export default { ...@@ -37,8 +39,10 @@ export default {
) )
this.$emit('update:mainImage', mainImage) this.$emit('update:mainImage', mainImage)
this.$emit('update:personName', value.personName) this.$emit('update:personName', value.title)
this.$emit('update:personTwitter', value.personTwitter) this.$emit('update:personTwitter', value.personTwitter)
},
immediate: true
} }
} }
} }
...@@ -56,6 +60,7 @@ export default { ...@@ -56,6 +60,7 @@ export default {
></InputHeading> ></InputHeading>
<VueSelect <VueSelect
:options="options" :options="options"
:clearable="false"
v-model="selectedOption" v-model="selectedOption"
label="title" label="title"
></VueSelect> ></VueSelect>
......
...@@ -21,13 +21,15 @@ import ivanImage from '../../assets/template/twitter_banner/ivan.png' ...@@ -21,13 +21,15 @@ import ivanImage from '../../assets/template/twitter_banner/ivan.png'
import jakubImage from '../../assets/template/twitter_banner/jakub.png' import jakubImage from '../../assets/template/twitter_banner/jakub.png'
import lipoImage from '../../assets/template/twitter_banner/lipo.png' import lipoImage from '../../assets/template/twitter_banner/lipo.png'
import olgaImage from '../../assets/template/twitter_banner/olga.png' import olgaImage from '../../assets/template/twitter_banner/olga.png'
import twitterLogoImage from '../../assets/template/twitter_banner/twitter.png'
</script> </script>
<script> <script>
loadFonts([ loadFonts([
'12px Bebas Neue', '12px Bebas Neue',
'12px Roboto Condensed', '12px Roboto Condensed',
'bold 12px Roboto Condensed' '12px Roboto'
]) ])
export default { export default {
...@@ -74,7 +76,8 @@ export default { ...@@ -74,7 +76,8 @@ export default {
mainText: null, mainText: null,
personName: null, personName: null,
personTwitter: null, personTwitter: null,
logoImage: defaultDarkLogoImage, logoImageSource: defaultDarkLogoImage,
twitterLogoImageSource: twitterLogoImage,
colors: { colors: {
background: COLORS.white, background: COLORS.white,
text: COLORS.black, text: COLORS.black,
...@@ -92,6 +95,9 @@ export default { ...@@ -92,6 +95,9 @@ export default {
async (value) => { async (value) => {
await this.$refs.canvas.redraw( await this.$refs.canvas.redraw(
{ {
colors: this.colors,
logoImageSource: this.logoImageSource,
twitterLogoImageSource: this.twitterLogoImageSource,
mainImage: this.mainImage, mainImage: this.mainImage,
mainText: this.mainText, mainText: this.mainText,
personName: this.personName, personName: this.personName,
...@@ -100,7 +106,8 @@ export default { ...@@ -100,7 +106,8 @@ export default {
); );
}, },
{ {
immediate: true, // Let the person chooser element run the first redraw
// immediate: true,
deep: true deep: true
} }
) )
......
import { fabric } from 'fabric' import { fabric } from 'fabric'
import { clearObjects, sortObjects, transformHighlightedText } from '../../components/canvas/utils' import { clearObjects, sortObjects, transformHighlightedText } from '../../components/canvas/utils'
let mainTextBox = null let background = null
let mainTextBoxBackground = null
let personInfoText = null let personNameTextBox = null
let personTwitterTextBox = null
let mainTextBox = null
let mainImage = null let mainImage = null
let logoImage = null let logoImage = null
let twitterLogoImage = null
let arrow = null
const redraw = async (canvas, options) => { const redraw = async (canvas, options) => {
clearObjects( clearObjects(
[ [
mainTextBox, mainTextBox,
mainTextBoxBackground, personNameTextBox,
personInfoText, personTwitterTextBox,
arrow
], ],
canvas canvas
) )
canvas.preserveObjectStacking = true canvas.preserveObjectStacking = true
const textMarginLeft = Math.ceil(canvas.width * 0.14)
const textMarginRight = Math.ceil(canvas.width * 0.075)
let mainTextMarginBottom = Math.ceil(canvas.height * 0.06) const mainImageOffsetSide = Math.ceil(canvas.width * 0.075)
const mainTextBackgroundMarginTop = Math.ceil(canvas.height * 0.14) const mainImageWidth = Math.ceil(canvas.width * 0.425)
const mainTextSize = Math.ceil(canvas.height * 0.0725) const mainImageOffsetTop = Math.ceil(canvas.height * 0.17)
const mainTextHeightLimit = Math.ceil(mainTextSize * 3.3)
const mainTextLineHeight = 0.98 // Hacky fix for highlight seam
const nameTextSize = Math.ceil(canvas.height * 0.03) const logoSideMargin = Math.ceil(canvas.width * 0.075)
const nameTextMarginTop = Math.ceil(canvas.height * 0.015) const logoWidth = Math.ceil(canvas.width * 0.25)
const nameTextExtraBottomMargin = Math.ceil(canvas.height * 0.06)
const arrowWidth = Math.ceil(canvas.width * 0.047) const twitterLogoImageWidth = Math.ceil(canvas.width * 0.08)
const arrowHeight = Math.ceil(canvas.width * 0.055) const twitterLogoOffsetTop = Math.ceil(canvas.height * 0.1)
const arrowThickness = Math.ceil(canvas.width * 0.019)
const arrowMarginLeft = Math.ceil(canvas.width * 0.065)
const arrowMarginTop = Math.ceil(canvas.height * 0.011)
const logoWidth = Math.ceil(canvas.width * 0.2) const mainTextBoxWidth = Math.ceil(canvas.width * 0.42)
const logoSideMargin = Math.ceil(canvas.width * 0.07) const mainTextBoxMarginSide = Math.ceil(canvas.width * 0.06)
const mainTextBoxMarginTop = Math.ceil(canvas.height * 0.03)
const mainTextBoxFontSize = Math.ceil(canvas.height * 0.038)
const mainTextBoxMaxHeight = Math.ceil(mainTextBoxFontSize * 12)
const mainTextBoxLineHeight = 1
const mainTextBoxCharSpacing = -Math.ceil(canvas.width * 0.015)
if (options.mainText !== null) { const nameTextFontSize = Math.ceil(canvas.height * 0.07)
/* BEGIN Name text render */ const nameTextOffsetTop = Math.ceil(canvas.height * 0.03)
if (options.personName !== null) { const twitterTextFontSize = Math.ceil(canvas.height * 0.037)
mainTextMarginBottom += nameTextExtraBottomMargin const twitterTextOffsetTop = Math.ceil(canvas.height * -0.007)
let styles = {
0: {}
}
/* BEGIN Background render */
for (let position = 0; position < options.personName.length; position++) { if (background === null) {
styles[0][position] = { background = new fabric.Rect({
fontWeight: 'bold' left: 0,
} top: 0,
fill: options.colors.background.value,
width: canvas.width,
height: canvas.height
})
canvas.add(background)
} }
let nameText = options.personName; /* END Background render */
if (options.personPosition) {
nameText += `|${options.personPosition}`
styles[0][options.personName.length] = { /* BEGIN Twitter logo render */
fontWeight: 'bold'
} if (twitterLogoImage === null) {
const twitterLogoImageElement = new Image()
await new Promise(
resolve => {
twitterLogoImageElement.onload = () => {
resolve()
} }
personInfoText = new fabric.Text( twitterLogoImageElement.src = options.twitterLogoImageSource
nameText,
{
left: textMarginLeft,
top: (
canvas.height
- mainTextMarginBottom
+ nameTextMarginTop
),
fontFamily: 'Roboto Condensed',
fontSize: nameTextSize,
styles: styles,
fill: options.colors.baseText.value,
selectable: false,
zIndex: 10
} }
) )
canvas.add(personInfoText) twitterLogoImage = new fabric.Image(twitterLogoImageElement, {selectable: false})
} twitterLogoImage.scaleToWidth(twitterLogoImageWidth)
twitterLogoImage.set({
left: (
canvas.width
- mainTextBoxMarginSide
- (
mainTextBoxWidth
+ twitterLogoImageWidth
) / 2
),
top: twitterLogoOffsetTop,
zIndex: 11
})
/* END Name text render */ canvas.add(twitterLogoImage)
}
/* END Twitter logo render */
/* BEGIN Main text render */
const highlightedData = transformHighlightedText( if (options.personName !== null) {
options.mainText, /* BEGIN Name text render */
options.colors.highlight.value,
options.colors.highlightedText.value
)
mainTextBox = new fabric.Textbox( personNameTextBox = new fabric.Textbox(
highlightedData.text, options.personName,
{ {
width: canvas.width - textMarginLeft - textMarginRight, width: mainTextBoxWidth,
left: textMarginLeft, textAlign: 'center',
textAlign: 'left', fontSize: nameTextFontSize,
fontFamily: 'Bebas Neue', fontFamily: 'Bebas Neue',
fontSize: mainTextSize, fill: options.colors.text.value,
lineHeight: mainTextLineHeight, left: (
fill: options.colors.baseText.value, canvas.width
styles: highlightedData.styles, - mainTextBoxMarginSide
- mainTextBoxWidth
),
top: (
twitterLogoImage.top
+ twitterLogoImage.getScaledHeight()
+ nameTextOffsetTop
),
selectable: false, selectable: false,
zIndex: 10 zIndex: 11
} }
) )
canvas.add(mainTextBox) canvas.add(personNameTextBox)
while (mainTextBox.height > mainTextHeightLimit) {
mainTextBox.fontSize -= 4
canvas.renderAll()
}
mainTextBox.top = ( /* END Name text render */
canvas.height
- mainTextBox.height
- mainTextMarginBottom
)
/* END Main text render */
/* BEGIN Arrow render */ if (options.personTwitter !== null) {
/* BEGIN Twitter handle text render */
arrow = new fabric.Polygon( personTwitterTextBox = new fabric.Textbox(
[ `@${options.personTwitter}`,
{x: 0, y: 0},
{x: arrowThickness, y: 0},
{
x: arrowWidth,
y: Math.ceil(arrowHeight) / 2
},
{
x: arrowThickness,
y: arrowHeight
},
{x: 0, y: arrowHeight},
{
x: arrowWidth - arrowThickness,
y: Math.ceil(arrowHeight) / 2
},
{x: 0, y: 0}
],
{ {
width: mainTextBoxWidth,
textAlign: 'center',
fontSize: twitterTextFontSize,
fontFamily: 'Roboto',
fill: options.colors.text.value,
left: (
canvas.width
- mainTextBoxMarginSide
- mainTextBoxWidth
),
top: ( top: (
mainTextBox.top personNameTextBox.top
+ arrowMarginTop + personNameTextBox.height
+ twitterTextOffsetTop
), ),
left: arrowMarginLeft,
fill: options.colors.arrow.value,
selectable: false, selectable: false,
zIndex: 10 zIndex: 11
} }
) )
canvas.add(arrow) canvas.add(personTwitterTextBox)
/* END Arrow render */ /* END Twitter handle text render */
/* BEGIN Main text background render */ /* BEGIN Main text render */
const backgroundHeight = (
canvas.height
- mainTextBox.top
+ mainTextBackgroundMarginTop
)
mainTextBoxBackground = new fabric.Rect( if (options.mainText !== null) {
{ mainTextBox = new fabric.Textbox(
width: canvas.width, options.mainText,
height: backgroundHeight,
left: 0,
top: mainTextBox.top - mainTextBackgroundMarginTop,
fill: new fabric.Gradient({
type: 'linear',
gradientUnits: 'pixels',
coords: {
x1: 0, y1: 0,
x2: 0, y2: backgroundHeight
},
colorStops: [
{
offset: 1,
color: options.colors.background.value
},
{
offset: 0.45,
color: options.colors.background.value
},
{ {
offset: 0, width: mainTextBoxWidth,
color: `${options.colors.background.value}00` textAlign: 'left',
} fontSize: mainTextBoxFontSize,
] fontFamily: 'Roboto Condensed',
}), lineHeight: mainTextBoxLineHeight,
charSpacing: mainTextBoxCharSpacing,
fill: options.colors.text.value,
left: (
canvas.width
- mainTextBoxMarginSide
- mainTextBoxWidth
),
top: (
personTwitterTextBox.top
+ personTwitterTextBox.height
+ mainTextBoxMarginTop
),
selectable: false, selectable: false,
zIndex: 9 zIndex: 11
} }
) )
canvas.add(mainTextBoxBackground) canvas.add(mainTextBox)
/* END Main text background render */ while (mainTextBox.height > mainTextBoxMaxHeight) {
mainTextBox.fontSize -= 4
canvas.renderAll()
}
}
/* END Main text render */
}
} }
/* BEGIN Logo render */ /* BEGIN Logo render */
// A logo is provided, and it either hasn't been rendered yet or is a new one. if (logoImage === null) {
const createNewLogo = ( const logoImageElement = new Image();
options.logoImage !== null
&& (
logoImage === null
|| (
options.logoImage !== null
&& options.logoImage !== logoImage._element
)
)
)
if (createNewLogo) { await new Promise(
canvas.remove(logoImage) resolve => {
logoImageElement.onload = () => {
resolve()
}
logoImageElement.src = options.logoImageSource
}
)
logoImage = new fabric.Image(options.logoImage, {selectable: false}) logoImage = new fabric.Image(logoImageElement, {selectable: false})
logoImage.scaleToWidth(logoWidth) logoImage.scaleToWidth(logoWidth)
logoImage.set({ logoImage.set({
left: ( left: logoSideMargin,
canvas.width top: (
- logoWidth canvas.height
- logoSideMargin - logoSideMargin
- logoImage.getScaledHeight()
), ),
top: logoSideMargin,
zIndex: 11, zIndex: 11,
}) })
...@@ -273,17 +254,13 @@ const redraw = async (canvas, options) => { ...@@ -273,17 +254,13 @@ const redraw = async (canvas, options) => {
mainImage = new fabric.Image( mainImage = new fabric.Image(
options.mainImage, options.mainImage,
{ {
left: 0, left: mainImageOffsetSide,
top: 0, top: mainImageOffsetTop,
selectable: false,
zIndex: 0 zIndex: 0
} }
) )
mainImage.scaleToWidth(mainImageWidth)
if (mainImage.width >= mainImage.height) {
mainImage.scaleToHeight(canvas.height)
} else {
mainImage.scaleToWidth(canvas.width)
}
canvas.add(mainImage) canvas.add(mainImage)
// canvas.centerObject(mainImage) // canvas.centerObject(mainImage)
......
...@@ -3,9 +3,10 @@ ...@@ -3,9 +3,10 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="/static/favicon.ico"> <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"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Generátor grafiky</title> <title>Generátor grafiky</title>
<script type="module" crossorigin src="/static/index-af58fe31.js"></script> <script type="module" crossorigin src="/static/index-7aa18e1b.js"></script>
<link rel="stylesheet" href="/static/index-656e3210.css"> <link rel="stylesheet" href="/static/index-656e3210.css">
</head> </head>
<body> <body>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment