change layout: add tool menu
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
e34262f494
commit
47a2365c60
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="">
|
||||
<TopMenu />
|
||||
<main class="py-6 grid grid-cols-1 gap-y-8 lg:py-12 lg:grid-cols-[1fr_2fr] lg:gap-x-20">
|
||||
<main class="pt-5 grid grid-cols-1 lg:grid-cols-[1fr_2fr] lg:gap-x-20">
|
||||
<RouterView />
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
@ -1,287 +1,330 @@
|
|||
<template>
|
||||
<div class="md:grid md:grid-cols-12 md:col-span-12">
|
||||
<div class="col-span-3 flex flex-col gap-4 lg:gap-6">
|
||||
<div class="drop-shadow-md rounded-md md:border border-zinc-300 p-5">
|
||||
<div>
|
||||
<TextareaForm
|
||||
id="heading"
|
||||
v-model="heading"
|
||||
label="Heading"
|
||||
/>
|
||||
<RangeForm
|
||||
id="heading-size"
|
||||
v-model="headingSize"
|
||||
min="1"
|
||||
max="10"
|
||||
step="0.1"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="col-span-3 lg:mr-4 tools"
|
||||
ref="tools"
|
||||
>
|
||||
<div class="mb-2">
|
||||
<button
|
||||
class="p-3 mr-2 rounded"
|
||||
:class="{'bg-slate-300': this.tool == 'heading'}"
|
||||
@click="this.tool = 'heading'"
|
||||
>Heading</button>
|
||||
|
||||
<div class="py-6">
|
||||
<TextareaForm
|
||||
id="subheading"
|
||||
v-model="subheading"
|
||||
label="Subheading"
|
||||
/>
|
||||
<RangeForm
|
||||
id="subheading-size"
|
||||
v-model="subheadingSize"
|
||||
min="1"
|
||||
max="10"
|
||||
step="0.1"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
class="p-3 mr-2 rounded"
|
||||
:class="{'bg-slate-300': this.tool == 'author'}"
|
||||
@click="this.tool = 'author'"
|
||||
>Author</button>
|
||||
|
||||
<div class="pb-6">
|
||||
<CheckboxForm
|
||||
id="allow-html"
|
||||
v-model="allowHtml"
|
||||
label="Allow HTML"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
class="p-3 mr-2 rounded"
|
||||
:class="{'bg-slate-300': this.tool == 'background'}"
|
||||
@click="this.tool = 'background'"
|
||||
>Background</button>
|
||||
|
||||
<div class="pb-6">
|
||||
<RangeForm
|
||||
id="content-padding"
|
||||
v-model="contentPadding"
|
||||
min="0"
|
||||
max="50"
|
||||
step="0.05"
|
||||
label="Padding"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pb-3">
|
||||
<InputForm
|
||||
id="text-color"
|
||||
v-model="textColor"
|
||||
label="Text color"
|
||||
type="color"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pb-6">
|
||||
<SelectForm
|
||||
id="font"
|
||||
v-model="font"
|
||||
:items="fonts"
|
||||
label="Font"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="text-center stroke-gray-400">
|
||||
<AlignForm v-model="headingAlign" />
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="p-3 rounded"
|
||||
:class="{'bg-slate-300': this.tool == 'size'}"
|
||||
@click="this.tool = 'size'"
|
||||
>Size</button>
|
||||
</div>
|
||||
|
||||
<div class="drop-shadow-md rounded-md md:border border-zinc-300 p-5">
|
||||
<div>
|
||||
<InputForm
|
||||
id="author"
|
||||
v-model="author"
|
||||
label="Author"
|
||||
/>
|
||||
</div>
|
||||
<div class="py-6">
|
||||
<FileForm
|
||||
id="avatar"
|
||||
v-model="avatar"
|
||||
label="Avatar"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FileForm
|
||||
id="logo"
|
||||
v-model="logo"
|
||||
label="Logo"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="stroke-gray-400 py-6">
|
||||
<RangeForm
|
||||
id="author-margin-bottom"
|
||||
v-model="authorMarginBottom"
|
||||
min="0"
|
||||
max="500"
|
||||
step="0.1"
|
||||
label="Position"
|
||||
/>
|
||||
<RangeForm
|
||||
id="author-padding"
|
||||
v-model="authorPadding"
|
||||
min="0"
|
||||
max="50"
|
||||
step="0.05"
|
||||
label="Padding"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pb-3">
|
||||
<InputForm
|
||||
id="author-text-color"
|
||||
v-model="authorTextColor"
|
||||
label="Text color"
|
||||
type="color"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<InputForm
|
||||
id="background-color"
|
||||
v-model="authorBackgroundColor"
|
||||
label="Background color"
|
||||
type="color"
|
||||
/>
|
||||
<RangeForm
|
||||
id="author-background-opacity"
|
||||
v-model="authorBackgroundOpacity"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="text-center stroke-gray-400 pt-5">
|
||||
<AlignForm v-model="authorAlign" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-3 md:px-10 flex flex-col gap-4 lg:gap-6">
|
||||
<div class="drop-shadow-md rounded-md md:border border-zinc-300 p-5">
|
||||
<div class="py-6">
|
||||
<FileForm
|
||||
id="background"
|
||||
v-model="background"
|
||||
label="Background"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<InputForm
|
||||
id="background-hover"
|
||||
v-model="backgroundHover"
|
||||
label="Background hover"
|
||||
type="color"
|
||||
/>
|
||||
<RangeForm
|
||||
id="background-hover-opacity"
|
||||
v-model="backgroundHoverOpacity"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drop-shadow-md rounded-md md:border border-zinc-300 p-5">
|
||||
<div>
|
||||
<label
|
||||
class="block text-sm font-medium text-gray-700"
|
||||
for="width"
|
||||
>Size and quality</label>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-4">
|
||||
<InputForm
|
||||
id="width"
|
||||
v-model="width"
|
||||
type="number"
|
||||
<div
|
||||
:class="{hidden: this.tool !== 'heading'}"
|
||||
class="drop-shadow-md rounded-md md:border border-zinc-300 tool"
|
||||
>
|
||||
<div class="p-5">
|
||||
<div>
|
||||
<TextareaForm
|
||||
id="heading"
|
||||
v-model="heading"
|
||||
label="Heading"
|
||||
/>
|
||||
<InputForm
|
||||
id="height"
|
||||
v-model="height"
|
||||
type="number"
|
||||
<RangeForm
|
||||
id="heading-size"
|
||||
v-model="headingSize"
|
||||
min="1"
|
||||
max="20"
|
||||
step="0.1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<RangeForm
|
||||
id="quality"
|
||||
v-model="quality"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
/>
|
||||
<div class="py-6">
|
||||
<TextareaForm
|
||||
id="subheading"
|
||||
v-model="subheading"
|
||||
label="Subheading"
|
||||
/>
|
||||
<RangeForm
|
||||
id="subheading-size"
|
||||
v-model="subheadingSize"
|
||||
min="1"
|
||||
max="20"
|
||||
step="0.1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pb-6">
|
||||
<CheckboxForm
|
||||
id="allow-html"
|
||||
v-model="allowHtml"
|
||||
label="Allow HTML"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pb-6">
|
||||
<RangeForm
|
||||
id="content-padding"
|
||||
v-model="contentPadding"
|
||||
min="0"
|
||||
max="300"
|
||||
step="0.05"
|
||||
label="Padding"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pb-3">
|
||||
<InputForm
|
||||
id="text-color"
|
||||
v-model="textColor"
|
||||
label="Text color"
|
||||
type="color"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pb-6">
|
||||
<SelectForm
|
||||
id="font"
|
||||
v-model="font"
|
||||
:items="fonts"
|
||||
label="Font"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="text-center stroke-gray-400">
|
||||
<AlignForm v-model="headingAlign" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
:class="{hidden: this.tool !== 'author'}"
|
||||
class="drop-shadow-md rounded-md md:border border-zinc-300 tool"
|
||||
>
|
||||
<div class="p-5">
|
||||
<div>
|
||||
<InputForm
|
||||
id="author"
|
||||
v-model="author"
|
||||
label="Author"
|
||||
/>
|
||||
</div>
|
||||
<div class="py-6">
|
||||
<FileForm
|
||||
id="avatar"
|
||||
v-model="avatar"
|
||||
label="Avatar"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FileForm
|
||||
id="logo"
|
||||
v-model="logo"
|
||||
label="Logo"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="stroke-gray-400 py-6">
|
||||
<RangeForm
|
||||
id="author-margin-bottom"
|
||||
v-model="authorMarginBottom"
|
||||
min="0"
|
||||
max="500"
|
||||
step="0.1"
|
||||
label="Position"
|
||||
/>
|
||||
<RangeForm
|
||||
id="author-padding"
|
||||
v-model="authorPadding"
|
||||
min="0"
|
||||
max="50"
|
||||
step="0.05"
|
||||
label="Padding"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pb-3">
|
||||
<InputForm
|
||||
id="author-text-color"
|
||||
v-model="authorTextColor"
|
||||
label="Text color"
|
||||
type="color"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<InputForm
|
||||
id="background-color"
|
||||
v-model="authorBackgroundColor"
|
||||
label="Background color"
|
||||
type="color"
|
||||
/>
|
||||
<RangeForm
|
||||
id="author-background-opacity"
|
||||
v-model="authorBackgroundOpacity"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="text-center stroke-gray-400 pt-5">
|
||||
<AlignForm v-model="authorAlign" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
:class="{hidden: this.tool !== 'background'}"
|
||||
class="drop-shadow-md rounded-md md:border border-zinc-300 tool"
|
||||
>
|
||||
<div class="p-5">
|
||||
<div class="pb-6">
|
||||
<FileForm
|
||||
id="background"
|
||||
v-model="background"
|
||||
label="Background"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<InputForm
|
||||
id="background-hover"
|
||||
v-model="backgroundHover"
|
||||
label="Background hover"
|
||||
type="color"
|
||||
/>
|
||||
<RangeForm
|
||||
id="background-hover-opacity"
|
||||
v-model="backgroundHoverOpacity"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
:class="{hidden: this.tool !== 'size'}"
|
||||
class="drop-shadow-md rounded-md md:border border-zinc-300 tool"
|
||||
>
|
||||
<div class="p-5">
|
||||
<div>
|
||||
<label
|
||||
class="block text-sm font-medium text-gray-700"
|
||||
for="width"
|
||||
>Size</label>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-4">
|
||||
<InputForm
|
||||
id="width"
|
||||
v-model="width"
|
||||
type="number"
|
||||
/>
|
||||
<InputForm
|
||||
id="height"
|
||||
v-model="height"
|
||||
type="number"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
ref="ogwrapper"
|
||||
class="col-span-6 space-y-6"
|
||||
class="og-wrapper col-span-9 lg:pl-10"
|
||||
>
|
||||
<div
|
||||
ref="og"
|
||||
class="og"
|
||||
:style="ogStyle()"
|
||||
>
|
||||
<div class="og-wrapper-content">
|
||||
<div
|
||||
class="og-image"
|
||||
:style="ogImageStyle()"
|
||||
ref="og"
|
||||
class="og"
|
||||
:style="ogStyle()"
|
||||
>
|
||||
<div
|
||||
class="og-image-hover"
|
||||
:style="ogImageHoverStyle()"
|
||||
class="og-image"
|
||||
ref="ogimage"
|
||||
:style="ogImageStyle()"
|
||||
>
|
||||
<div
|
||||
class="h-full flex flex-col justify-between"
|
||||
:style="ogContentStyle()"
|
||||
class="og-image-hover"
|
||||
:style="ogImageHoverStyle()"
|
||||
>
|
||||
<div v-if="allowHtml">
|
||||
<h1
|
||||
class="leading-none"
|
||||
:style="ogHeadingStyle()"
|
||||
v-html="heading"
|
||||
/>
|
||||
<p
|
||||
class="mt-10 mb-16 leading-tight"
|
||||
:style="ogSubheadingStyle()"
|
||||
v-html="subheading"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<h1
|
||||
class="leading-none"
|
||||
:style="ogHeadingStyle()"
|
||||
v-text="heading"
|
||||
/>
|
||||
<p
|
||||
class="mt-10 mb-16 leading-tight"
|
||||
:style="ogSubheadingStyle()"
|
||||
v-text="subheading"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="w-full flex flex-row items-center og-image--footer"
|
||||
:style="ogAuthorStyle()"
|
||||
class="h-full flex flex-col justify-between"
|
||||
:style="ogContentStyle()"
|
||||
>
|
||||
<img
|
||||
v-if="avatar"
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="avatar"
|
||||
>
|
||||
<div v-if="allowHtml">
|
||||
<h1
|
||||
class="leading-none"
|
||||
:style="ogHeadingStyle()"
|
||||
v-html="heading"
|
||||
/>
|
||||
<p
|
||||
class="mt-10 mb-16 leading-tight"
|
||||
:style="ogSubheadingStyle()"
|
||||
v-html="subheading"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<h1
|
||||
class="leading-none"
|
||||
:style="ogHeadingStyle()"
|
||||
v-text="heading"
|
||||
/>
|
||||
<p
|
||||
class="mt-10 mb-16 leading-tight"
|
||||
:style="ogSubheadingStyle()"
|
||||
v-text="subheading"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<span
|
||||
class="mx-4"
|
||||
:style="ogAuthorTextStyle()"
|
||||
v-text="author"
|
||||
/>
|
||||
|
||||
<img
|
||||
v-if="logo"
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="logo"
|
||||
<div
|
||||
class="w-full flex flex-row items-center og-image--footer"
|
||||
:style="ogAuthorStyle()"
|
||||
>
|
||||
<img
|
||||
v-if="avatar"
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="avatar"
|
||||
>
|
||||
|
||||
<span
|
||||
class="mx-4"
|
||||
:style="ogAuthorTextStyle()"
|
||||
v-text="author"
|
||||
/>
|
||||
|
||||
<img
|
||||
v-if="logo"
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="logo"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<div class="text-center mt-3">
|
||||
<DownloadButton
|
||||
class="rounded-l-md"
|
||||
label="PNG"
|
||||
|
@ -294,6 +337,8 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bottom"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -322,6 +367,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
tool: localStorage.getItem('tool') ?? 'heading',
|
||||
author: localStorage.getItem('author'),
|
||||
authorPadding: localStorage.getItem('authorPadding') ?? 0,
|
||||
authorAlign: localStorage.getItem('authorAlign') ?? 'left',
|
||||
|
@ -343,7 +389,6 @@ export default {
|
|||
subheadingSize: localStorage.getItem('subheadingSize') ?? 2,
|
||||
width: localStorage.getItem('width') ?? 1920,
|
||||
height: localStorage.getItem('height') ?? 1080,
|
||||
quality: localStorage.getItem('quality') ?? 0.9,
|
||||
contentPadding: localStorage.getItem('contentPadding') ?? 2.5,
|
||||
allowHtml: localStorage.getItem('allowHtml'),
|
||||
ogMaxWidth: 100,
|
||||
|
@ -363,6 +408,9 @@ export default {
|
|||
}
|
||||
},
|
||||
watch: {
|
||||
tool(value) {
|
||||
localStorage.setItem('tool', value)
|
||||
},
|
||||
author(value) {
|
||||
localStorage.setItem('author', value)
|
||||
},
|
||||
|
@ -423,9 +471,6 @@ export default {
|
|||
height(value) {
|
||||
localStorage.setItem('height', value)
|
||||
},
|
||||
quality(value) {
|
||||
localStorage.setItem('quality', value)
|
||||
},
|
||||
contentPadding(value) {
|
||||
localStorage.setItem('contentPadding', value)
|
||||
},
|
||||
|
@ -444,18 +489,25 @@ export default {
|
|||
ogStyle() {
|
||||
return {
|
||||
color: this.textColor,
|
||||
width: `${this.width}px`,
|
||||
maxWidth: `${this.ogMaxWidth}px`,
|
||||
fontFamily: this.font,
|
||||
maxHeight: `${this.ogMaxHeight}px`,
|
||||
maxWidth: `${this.ogMaxWidth}px !important`,
|
||||
aspectRatio: `${this.width}/${this.height}`,
|
||||
}
|
||||
},
|
||||
ogImageStyle() {
|
||||
if (this.background) {
|
||||
return {
|
||||
background: `url(${this.background}) center`,
|
||||
backgroundSize: 'cover',
|
||||
}
|
||||
let value = {
|
||||
maxHeight: `${this.ogMaxHeight}px`,
|
||||
maxWidth: `${this.ogMaxWidth}px`,
|
||||
aspectRatio: `${this.width}/${this.height}`,
|
||||
}
|
||||
|
||||
if (this.background) {
|
||||
value.background = `url(${this.background}) center`
|
||||
value.backgroundSize = 'cover'
|
||||
}
|
||||
|
||||
return value
|
||||
},
|
||||
ogHeadingStyle() {
|
||||
return {
|
||||
|
@ -513,7 +565,9 @@ export default {
|
|||
|
||||
return {
|
||||
background,
|
||||
aspectRatio: `${this.width}/${this.height}`
|
||||
aspectRatio: `${this.width}/${this.height}`,
|
||||
maxHeight: `${this.ogMaxHeight}px`,
|
||||
maxWidth: `${this.ogMaxWidth}px`,
|
||||
}
|
||||
},
|
||||
ogContentStyle() {
|
||||
|
@ -530,12 +584,12 @@ export default {
|
|||
return this.download(toJpeg, 'image.jpg')
|
||||
},
|
||||
download(callback, filename) {
|
||||
const element = this.$refs.og
|
||||
const element = this.$refs.ogimage
|
||||
|
||||
callback(this.$refs.og, {
|
||||
callback(element, {
|
||||
canvasWidth: this.width,
|
||||
canvasHeight: this.height,
|
||||
quality: this.quality,
|
||||
quality: 1,
|
||||
})
|
||||
.then((dataUrl) => {
|
||||
const link = document.createElement('a')
|
||||
|
@ -552,7 +606,8 @@ export default {
|
|||
},
|
||||
updateOgMaxWidth() {
|
||||
this.$refs.og.style.display = 'none'
|
||||
this.ogMaxWidth = this.$refs.ogwrapper.offsetWidth
|
||||
this.ogMaxWidth = this.$refs.ogwrapper.offsetWidth - 30
|
||||
this.ogMaxHeight = this.$refs.tools.offsetHeight - 50
|
||||
this.$refs.og.style.display = 'block'
|
||||
},
|
||||
}
|
||||
|
@ -560,12 +615,31 @@ export default {
|
|||
</script>
|
||||
|
||||
<style>
|
||||
#bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.tool {
|
||||
max-height: calc(100vh - 250px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.tools {
|
||||
height: calc(100vh - 250px);
|
||||
}
|
||||
|
||||
.og {
|
||||
background: #cecece;
|
||||
max-width: 10px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.og-wrapper-content {
|
||||
background-color: #c1c1c1;
|
||||
background-image: linear-gradient(45deg, #646464 25%, transparent 25%, transparent 75%, #646464 75%), linear-gradient(45deg, #646464 25%, transparent 25%, transparent 75%, #646464 75%);
|
||||
background-size: 20px 20px;
|
||||
background-position: 0 0, 10px 10px;
|
||||
}
|
||||
|
||||
.og-heading {
|
||||
font-size: 5em;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue