Browse Source

🎨 Cleaned up code, and added accessibility features

main
Nichole Mattera 4 months ago
parent
commit
8a700a0442
  1. 4
      babel.config.js
  2. 10
      package.json
  3. 2
      src/App.vue
  4. BIN
      src/assets/logo.png
  5. 9
      src/components/AddIcon.vue
  6. 9
      src/components/CodeIcon.vue
  7. 9
      src/components/DownloadIcon.vue
  8. 14
      src/components/IconButton.vue
  9. 9
      src/components/RemoveIcon.vue
  10. 99
      src/image-preview/ImagePreview.vue
  11. 74
      src/image-preview/composables/useRendering.js
  12. 16
      src/side-bar/SideBar.vue
  13. 390
      src/side-bar/components/FlagSettings.vue
  14. 2
      src/side-bar/components/ImageSettings.vue
  15. 378
      src/side-bar/composables/useFlagTypes.js
  16. 2
      vue.config.js

4
babel.config.js

@ -1,5 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
'@vue/cli-plugin-babel/preset',
],
}

10
package.json

@ -39,7 +39,15 @@
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
"rules": {
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline"
}],
"semi": ["error", "never"]
}
},
"browserslist": [
"> 1%",

2
src/App.vue

@ -18,7 +18,7 @@ import ImagePreview from './image-preview/ImagePreview.vue'
const settings = reactive({
width: 0,
height: 0,
flags: []
flags: [],
})
function onSettingChanged(value) {

BIN
src/assets/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

9
src/components/AddIcon.vue

@ -1,13 +1,17 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
aria-labelledby="title"
:height="height"
role="img"
viewBox="0 0 448 512"
:width="width">
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<title id="title">{{ label }}</title>
<path
d="M432 256C432 269.3 421.3 280 408 280h-160v160c0 13.25-10.75 24.01-24 24.01S200 453.3 200 440v-160h-160c-13.25 0-24-10.74-24-23.99C16 242.8 26.75 232 40 232h160v-160c0-13.25 10.75-23.99 24-23.99S248 58.75 248 72v160h160C421.3 232 432 242.8 432 256z"
:fill="color" />
:fill="color"
role="presentation" />
</svg>
</template>
@ -17,6 +21,7 @@ import { defineProps } from 'vue'
defineProps({
color: String,
height: String,
width: String
label: String,
width: String,
})
</script>

9
src/components/CodeIcon.vue

@ -1,13 +1,17 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
aria-labelledby="title"
:height="height"
role="img"
viewBox="0 0 448 512"
:width="width">
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<title id="title">{{ label }}</title>
<path
d="M160 80C160 115.8 136.5 146.1 104 156.3V255.1C124.1 240.9 148.1 232 176 232H272C311.8 232 344 199.8 344 160V156.3C311.5 146.1 288 115.8 288 80C288 35.82 323.8 0 368 0C412.2 0 448 35.82 448 80C448 115.8 424.5 146.1 392 156.3V160C392 226.3 338.3 280 272 280H176C136.2 280 104 312.2 104 352V355.7C136.5 365.9 160 396.2 160 432C160 476.2 124.2 512 80 512C35.82 512 0 476.2 0 432C0 396.2 23.54 365.9 56 355.7V156.3C23.54 146.1 0 115.8 0 80C0 35.82 35.82 0 80 0C124.2 0 160 35.82 160 80V80zM80 112C97.67 112 112 97.67 112 80C112 62.33 97.67 48 80 48C62.33 48 48 62.33 48 80C48 97.67 62.33 112 80 112zM368 48C350.3 48 336 62.33 336 80C336 97.67 350.3 112 368 112C385.7 112 400 97.67 400 80C400 62.33 385.7 48 368 48zM80 464C97.67 464 112 449.7 112 432C112 414.3 97.67 400 80 400C62.33 400 48 414.3 48 432C48 449.7 62.33 464 80 464z"
:fill="color" />
:fill="color"
role="presentation" />
</svg>
</template>
@ -17,6 +21,7 @@ import { defineProps } from 'vue'
defineProps({
color: String,
height: String,
width: String
label: String,
width: String,
})
</script>

9
src/components/DownloadIcon.vue

@ -1,13 +1,17 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
aria-labelledby="title"
:height="height"
role="img"
viewBox="0 0 512 512"
:width="width">
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<title id="title">{{ label }}</title>
<path
d="M480 352h-133.5l-45.25 45.25C289.2 409.3 273.1 416 256 416s-33.16-6.656-45.25-18.75L165.5 352H32c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h448c17.67 0 32-14.33 32-32v-96C512 366.3 497.7 352 480 352zM432 456c-13.2 0-24-10.8-24-24c0-13.2 10.8-24 24-24s24 10.8 24 24C456 445.2 445.2 456 432 456zM233.4 374.6C239.6 380.9 247.8 384 256 384s16.38-3.125 22.62-9.375l128-128c12.49-12.5 12.49-32.75 0-45.25c-12.5-12.5-32.76-12.5-45.25 0L288 274.8V32c0-17.67-14.33-32-32-32C238.3 0 224 14.33 224 32v242.8L150.6 201.4c-12.49-12.5-32.75-12.5-45.25 0c-12.49 12.5-12.49 32.75 0 45.25L233.4 374.6z"
:fill="color" />
:fill="color"
role="presentation" />
</svg>
</template>
@ -17,6 +21,7 @@ import { defineProps } from 'vue'
defineProps({
color: String,
height: String,
width: String
label: String,
width: String,
})
</script>

14
src/components/IconButton.vue

@ -1,5 +1,8 @@
<template>
<button :class="type">
<button
:aria-label="label"
:class="type"
:title="label">
<slot></slot>
</button>
</template>
@ -8,7 +11,8 @@
import { defineProps } from 'vue'
defineProps({
type: String
label: String,
type: String,
})
</script>
@ -38,8 +42,8 @@ button.primary {
}
button.primary:focus, button.primary:active, button.primary:hover {
background: #F06595;
border-color: #F06595;
background: #F389AD;
border-color: #F389AD;
}
button.secondary {
@ -50,4 +54,4 @@ button.secondary {
button.secondary:focus, button.secondary:active, button.secondary:hover {
border-color: #EC407A;
}
</style>
</style>

9
src/components/RemoveIcon.vue

@ -1,13 +1,17 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
aria-labelledby="title"
:height="height"
role="img"
viewBox="0 0 320 512"
:width="width">
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<title id="title">{{ label }}</title>
<path
d="M312.1 375c9.369 9.369 9.369 24.57 0 33.94s-24.57 9.369-33.94 0L160 289.9l-119 119c-9.369 9.369-24.57 9.369-33.94 0s-9.369-24.57 0-33.94L126.1 256L7.027 136.1c-9.369-9.369-9.369-24.57 0-33.94s24.57-9.369 33.94 0L160 222.1l119-119c9.369-9.369 24.57-9.369 33.94 0s9.369 24.57 0 33.94L193.9 256L312.1 375z"
:fill="color" />
:fill="color"
role="presentation" />
</svg>
</template>
@ -17,6 +21,7 @@ import { defineProps } from 'vue'
defineProps({
color: String,
height: String,
width: String
label: String,
width: String,
})
</script>

99
src/image-preview/ImagePreview.vue

@ -11,10 +11,11 @@
</template>
<script setup>
import { computed, defineEmits, defineProps, reactive, ref, watch } from 'vue'
import { computed, defineEmits, defineProps, onMounted, reactive, ref, watch } from 'vue'
import useRendering from './composables/useRendering'
const props = defineProps({
settings: Object
settings: Object,
})
const emit = defineEmits(['ready'])
@ -27,9 +28,6 @@ const resizeObserver = reactive(new ResizeObserver(() => {
height.value = container.value.clientHeight
width.value = container.value.clientWidth
}))
watch(container, (newContainer) => {
resizeObserver.observe(newContainer)
})
// Handles sizing of the canvas
const canvasStyle = computed(() => {
@ -46,7 +44,7 @@ const canvasStyle = computed(() => {
return {
height: `${props.settings.height * bestRatio}px`,
width: `${props.settings.width * bestRatio}px`
width: `${props.settings.width * bestRatio}px`,
}
})
@ -54,78 +52,7 @@ const canvas = ref(null)
let context = ref(null)
// Main rendering routine.
function renderPreview(settings) {
if (!context.value) return
const size = Math.sqrt(Math.pow(settings.width, 2) + Math.pow(settings.height, 2))
const flagHeight = size / settings.flags.filter((flag) => flag.id !== '').length
const tempCanvas = document.createElement('canvas')
tempCanvas.height = size
tempCanvas.width = size
const tempContext = tempCanvas.getContext('2d')
settings.flags.forEach((flag, flagIndex) => {
if (flag.id === 'bisexual') {
const barHeight = flagHeight / 5
tempContext.fillStyle = flag.bars[0]
tempContext.fillRect(0, flagHeight * flagIndex, size, barHeight * 2)
tempContext.fillStyle = flag.bars[1]
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * 2), size, barHeight)
tempContext.fillStyle = flag.bars[2]
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * 3), size, barHeight * 2)
} else if (flag.id === 'demisexual') {
const barHeight = flagHeight / 6
tempContext.fillStyle = flag.bars[1]
tempContext.fillRect(0, flagHeight * flagIndex, size, barHeight * 2.5)
tempContext.fillStyle = flag.bars[2]
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * 2.5), size, barHeight)
tempContext.fillStyle = flag.bars[3]
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * 3.5), size, barHeight * 2.5)
tempContext.fillStyle = flag.bars[0]
tempContext.beginPath()
tempContext.moveTo(0, flagHeight * flagIndex)
tempContext.lineTo(flagHeight * 0.5, (flagHeight * flagIndex) + (barHeight * 3))
tempContext.lineTo(0, (flagHeight * flagIndex) + flagHeight)
tempContext.fill()
} else if (flag.id === 'intersex') {
tempContext.fillStyle = flag.bars[0]
tempContext.fillRect(0, flagHeight * flagIndex, size, flagHeight)
tempContext.save()
tempContext.strokeStyle = flag.bars[1]
tempContext.fillStyle = flag.bars[2]
tempContext.lineWidth = flagHeight * 0.1
tempContext.arc(size / 2, (flagHeight * flagIndex) + (flagHeight / 2), flagHeight * 0.1875, 0, 2 * Math.PI)
tempContext.fill()
tempContext.stroke()
tempContext.restore()
} else {
const barHeight = flagHeight / flag.bars.length
flag.bars.forEach((bar, barIndex) => {
tempContext.fillStyle = bar
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * barIndex), size, barHeight)
})
}
})
context.value.clearRect(0, 0, settings.width, settings.height)
context.value.save()
context.value.translate(settings.width / 2, settings.height / 2)
context.value.rotate(-Math.PI / 4)
context.value.translate(-size / 2, -size / 2)
context.value.drawImage(tempCanvas, 0, 0)
context.value.restore()
}
const renderPreview = useRendering(context)
// Render on canvas resize.
const canvasResizeObserver = reactive(new ResizeObserver(() => {
@ -133,17 +60,19 @@ const canvasResizeObserver = reactive(new ResizeObserver(() => {
renderPreview(props.settings)
}))
// Get the context, register observer, and emit canvas to parent.
watch(canvas, (newCanvas) => {
context.value = newCanvas.getContext('2d')
canvasResizeObserver.observe(newCanvas)
emit('ready', newCanvas)
})
// Render on setting changed.
watch(props.settings, (newSettings) => {
renderPreview(newSettings)
})
onMounted(() => {
resizeObserver.observe(container.value)
// Register observer, Get the context, and emit canvas to parent.
canvasResizeObserver.observe(canvas.value)
context.value = canvas.value.getContext('2d')
emit('ready', canvas.value)
})
</script>
<style scoped>

74
src/image-preview/composables/useRendering.js

@ -0,0 +1,74 @@
export default function useRendering(context) {
return (settings) => {
if (!context.value) return
const size = Math.sqrt(Math.pow(settings.width, 2) + Math.pow(settings.height, 2))
const flagHeight = size / settings.flags.filter((flag) => flag.id !== '').length
const tempCanvas = document.createElement('canvas')
tempCanvas.height = size
tempCanvas.width = size
const tempContext = tempCanvas.getContext('2d')
settings.flags.forEach((flag, flagIndex) => {
if (flag.id === 'bisexual') {
const barHeight = flagHeight / 5
tempContext.fillStyle = flag.bars[0]
tempContext.fillRect(0, flagHeight * flagIndex, size, barHeight * 2)
tempContext.fillStyle = flag.bars[1]
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * 2), size, barHeight)
tempContext.fillStyle = flag.bars[2]
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * 3), size, barHeight * 2)
} else if (flag.id === 'demisexual') {
const barHeight = flagHeight / 6
tempContext.fillStyle = flag.bars[1]
tempContext.fillRect(0, flagHeight * flagIndex, size, barHeight * 2.5)
tempContext.fillStyle = flag.bars[2]
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * 2.5), size, barHeight)
tempContext.fillStyle = flag.bars[3]
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * 3.5), size, barHeight * 2.5)
tempContext.fillStyle = flag.bars[0]
tempContext.beginPath()
tempContext.moveTo(0, flagHeight * flagIndex)
tempContext.lineTo(flagHeight * 0.5, (flagHeight * flagIndex) + (barHeight * 3))
tempContext.lineTo(0, (flagHeight * flagIndex) + flagHeight)
tempContext.fill()
} else if (flag.id === 'intersex') {
tempContext.fillStyle = flag.bars[0]
tempContext.fillRect(0, flagHeight * flagIndex, size, flagHeight)
tempContext.save()
tempContext.strokeStyle = flag.bars[1]
tempContext.fillStyle = flag.bars[2]
tempContext.lineWidth = flagHeight * 0.1
tempContext.arc(size / 2, (flagHeight * flagIndex) + (flagHeight / 2), flagHeight * 0.1875, 0, 2 * Math.PI)
tempContext.fill()
tempContext.stroke()
tempContext.restore()
} else {
const barHeight = flagHeight / flag.bars.length
flag.bars.forEach((bar, barIndex) => {
tempContext.fillStyle = bar
tempContext.fillRect(0, (flagHeight * flagIndex) + (barHeight * barIndex), size, barHeight)
})
}
})
context.value.clearRect(0, 0, settings.width, settings.height)
context.value.save()
context.value.translate(settings.width / 2, settings.height / 2)
context.value.rotate(-Math.PI / 4)
context.value.translate(-size / 2, -size / 2)
context.value.drawImage(tempCanvas, 0, 0)
context.value.restore()
}
}

16
src/side-bar/SideBar.vue

@ -3,12 +3,14 @@
<h1>
<span>Settings</span>
<icon-button
label="View source code"
type="secondary"
@click="viewCode">
<code-icon
color="#FFF"
height="16px"
label="View source code"
width="16px" />
</icon-button>
@ -20,12 +22,14 @@
<h2>
<span>Flags</span>
<icon-button
label="Add flag"
type="secondary"
@click="addFlag">
<add-icon
color="#FFF"
height="16px"
label="Add flag"
width="16px" />
</icon-button>
@ -44,12 +48,14 @@
<div class="footer">
<icon-button
label="Save background"
type="primary"
@click="$emit('save')">
<download-icon
color="#FFF"
height="16px"
label="Save background"
width="16px" />
</icon-button>
@ -67,6 +73,8 @@ import IconButton from '../components/IconButton.vue'
import FlagSettings from './components/FlagSettings.vue'
import ImageSettings from './components/ImageSettings.vue'
const emit = defineEmits(['change', 'save'])
function viewCode() {
window.open('https://git.nicholemattera.com/NicholeMattera/Pride-Background-Generator', '_blank')
}
@ -74,10 +82,10 @@ function viewCode() {
const settings = reactive({
width: 0,
height: 0,
flags: []
flags: [],
})
emit('change', settings)
const emit = defineEmits(['change', 'save'])
function onFieldChanged({ field, value }) {
settings[field] = value
emit('change', settings)
@ -87,7 +95,7 @@ function addFlag() {
settings.flags.push({
id: '',
label: '',
bars: []
bars: [],
})
emit('change', settings)
}
@ -101,8 +109,6 @@ function removeFlag(index) {
settings.flags = settings.flags.filter((e, i) => i != index)
emit('change', settings)
}
emit('change', settings)
</script>
<style scoped>

390
src/side-bar/components/FlagSettings.vue

@ -5,11 +5,13 @@
Flag #{{ index + 1 }}
</span>
<icon-button
label="Remove Flag"
type="secondary"
@click="$emit('remove')">
<remove-icon
color="#FFF"
height="16px"
label="Remove Flag"
width="16px" />
</icon-button>
</h3>
@ -20,10 +22,10 @@
label="Flag Type">
<select
:id="`flag-type-${index}`"
v-model="selectedFlagTypeId"
@change="flagSelected">
<option
disabled
selected
value="">
Select a flag type
</option>
@ -40,396 +42,24 @@
</template>
<script setup>
import { defineEmits, defineProps, ref } from 'vue'
import { defineEmits, defineProps } from 'vue'
import FormField from '../../components/FormField.vue'
import IconButton from '../../components/IconButton.vue'
import RemoveIcon from '../../components/RemoveIcon.vue'
import useFlagTypes from '../composables/useFlagTypes'
const props = defineProps({
index: Number
index: Number,
})
const selectedFlagTypeId = ref('')
const flagTypes = ref([
{
id: 'abrosexual',
label: 'Abrosexual',
bars: [
'#77CC94',
'#B5E5CC',
'#FCFEFF',
'#E997B5',
'#DC406C',
],
},
{
id: 'aceflux',
label: 'Aceflux',
bars: [
'#C82067',
'#BCC5C6',
'#EC6D87',
'#91479B',
'#800080',
],
},
{
id: 'agender',
label: 'Agender',
bars: [
'#000',
'#BCC5C6',
'#FFF',
'#B5F582',
'#FFF',
'#BCC5C6',
'#000',
],
},
{
id: 'androgyne',
label: 'Androgyne',
bars: [
'#FE007F',
'#9832FF',
'#00B8E7',
],
},
{
id: 'aromantic',
label: 'Aromantic',
bars: [
'#3AA740',
'#A8D47A',
'#FFF',
'#ABABAB',
'#000',
],
},
{
id: 'asexual',
label: 'Asexual',
bars: [
'#000',
'#A6A7A6',
'#FFF',
'#820082',
],
},
{
id: 'bigender',
label: 'Bigender',
bars: [
'#ED78AB',
'#FEF54D',
'#FFF',
'#AE6DBE',
'#719EE3',
],
},
{
id: 'bisexual',
label: 'Bisexual',
bars: [
'#D80071',
'#744E96',
'#0035A9',
],
},
{
id: 'boyflux',
label: 'Boyflux',
bars: [
'#D7E9F8',
'#6FACF5',
'#023670',
'#9EEDAC',
'#023670',
'#6FACF5',
'#D7E9F8',
],
},
{
id: 'ceterosexual',
label: 'Ceterosexual',
bars: [
'#FCF980',
'#169C47',
'#FFF',
'#000',
],
},
{
id: 'demiboy',
label: 'Demiboy',
bars: [
'#7F7F7F',
'#C4C4C4',
'#9AD9EB',
'#FFF',
'#9AD9EB',
'#C4C4C4',
'#7F7F7F',
],
},
{
id: 'demiflux',
label: 'Demiflux',
bars: [
'#7F7F7F',
'#DADADA',
'#FFB6B8',
'#F4F691',
'#9AD9EB',
'#DADADA',
'#7F7F7F',
],
},
{
id: 'demigender',
label: 'Demigender',
bars: [
'#7F7F7F',
'#C4C4C4',
'#FAFF72',
'#FFF',
'#FAFF72',
'#C4C4C4',
'#7F7F7F',
],
},
{
id: 'demigirl',
label: 'Demigirl',
bars: [
'#7F7F7F',
'#C4C4C4',
'#FFAEC9',
'#FFF',
'#FFAEC9',
'#C4C4C4',
'#7F7F7F',
],
},
{
id: 'demigirlflux',
label: 'Demigirlflux',
bars: [
'#7F7F7F',
'#C4C4C4',
'#A24AA3',
'#FEAFC9',
'#FFF',
'#FEAFC9',
'#A24AA3',
'#C4C4C4',
'#7F7F7F',
],
},
{
id: 'demisexual',
label: 'Demisexual',
bars: [
'#000',
'#FFF',
'#6f0071',
'#d3d3d3',
],
},
{
id: 'fraysexual',
label: 'Fraysexual',
bars: [
'#226CB5',
'#93E7DD',
'#FFF',
'#636363',
],
},
{
id: 'mlm',
label: 'MLM',
bars: [
'#008F72',
'#1BD0AD',
'#9BEAC4',
'#FFF',
'#7DB1E5',
'#4E45CD',
'#390B7A',
],
},
{
id: 'genderfluid',
label: 'Genderfluid',
bars: [
'#FF77A5',
'#F5F5F5',
'#C009D8',
'#232323',
'#2C39BF',
],
},
{
id: 'genderqueer',
label: 'Genderqueer',
bars: [
'#B880DE',
'#FFF',
'#478318',
],
},
{
id: 'girlflux',
label: 'Girlflux',
bars: [
'#F8E6D8',
'#F1526D',
'#BF0310',
'#E8C586',
'#BF0310',
'#F1526D',
'#F8E6D8',
],
},
{
id: 'greysexual',
label: 'Greysexual',
bars: [
'#740195',
'#AEB2AA',
'#FFF',
'#AEB2AA',
'#740195',
],
},
{
id: 'intersex',
label: 'Intersex',
bars: [
'#FFD900',
'#7A00AC',
'#FFD900',
],
},
{
id: 'lesbian',
label: 'Lesbian',
bars: [
'#D52800',
'#FD9954',
'#FFF',
'#D261A4',
'#A40061',
],
},
{
id: 'nonbinary',
label: 'NonBinary',
bars: [
'#FEF32A',
'#FEFEFE',
'#9D57D2',
'#000',
],
},
{
id: 'omnisexual',
label: 'Omnisexual',
bars: [
'#FF9DCF',
'#FF51C0',
'#1A0042',
'#675FFF',
'#8EA9FF',
],
},
{
id: 'pangender',
label: 'Pangender',
bars: [
'#FFF798',
'#FFDDCD',
'#FFEBFB',
'#FFF',
'#FFEBFB',
'#FFDDCD',
'#FFF798',
],
},
{
id: 'pansexual',
label: 'Pansexual',
bars: [
'#FF148E',
'#FFDA00',
'#14B5FF',
],
},
{
id: 'polysexual',
label: 'Polysexual',
bars: [
'#F614BA',
'#00D769',
'#1593F5',
],
},
{
id: 'philadelphia-pride',
label: 'Philadelphia Pride',
bars: [
'#000',
'#794E10',
'#E60000',
'#FF8E00',
'#FFEF00',
'#00821B',
'#004BFF',
'#770089',
],
},
{
id: 'pride',
label: 'Pride',
bars: [
'#E60000',
'#FF8E00',
'#FFEF00',
'#00821B',
'#004BFF',
'#770089',
],
},
{
id: 'transgender',
label: 'Transgender',
bars: [
'#5CCFFA',
'#F4ABB8',
'#FFF',
'#F4ABB8',
'#5CCFFA',
],
},
{
id: 'trigender',
label: 'Trigender',
bars: [
'#FF95C4',
'#9580FF',
'#6AD969',
'#9580FF',
'#FF95C4',
],
},
])
const emit = defineEmits(['change', 'remove'])
const flagTypes = useFlagTypes()
function flagSelected(event) {
emit('change', {
index: props.index,
value: flagTypes.value.find((flagType) => flagType.id === event.target.value)
value: flagTypes.value.find((flagType) => flagType.id === event.target.value),
})
}
</script>

2
src/side-bar/components/ImageSettings.vue

@ -30,7 +30,7 @@ const emit = defineEmits(['change'])
function onFieldChanged(field, value) {
emit('change', {
field,
value: typeof value === 'number' ? value : parseInt(value)
value: typeof value === 'number' ? value : parseInt(value),
})
}

378
src/side-bar/composables/useFlagTypes.js

@ -0,0 +1,378 @@
import { ref } from 'vue'
export default function useFlagTypes() {
return ref([
{
id: 'abrosexual',
label: 'Abrosexual',
bars: [
'#77CC94',
'#B5E5CC',
'#FCFEFF',
'#E997B5',
'#DC406C',
],
},
{
id: 'aceflux',
label: 'Aceflux',
bars: [
'#C82067',
'#BCC5C6',
'#EC6D87',
'#91479B',
'#800080',
],
},
{
id: 'agender',
label: 'Agender',
bars: [
'#000',
'#BCC5C6',
'#FFF',
'#B5F582',
'#FFF',
'#BCC5C6',
'#000',
],
},
{
id: 'androgyne',
label: 'Androgyne',
bars: [
'#FE007F',
'#9832FF',
'#00B8E7',
],
},
{
id: 'aromantic',
label: 'Aromantic',
bars: [
'#3AA740',
'#A8D47A',
'#FFF',
'#ABABAB',
'#000',
],
},
{
id: 'asexual',
label: 'Asexual',
bars: [
'#000',
'#A6A7A6',
'#FFF',
'#820082',
],
},
{
id: 'bigender',
label: 'Bigender',
bars: [
'#ED78AB',
'#FEF54D',
'#FFF',
'#AE6DBE',
'#719EE3',
],
},
{
id: 'bisexual',
label: 'Bisexual',
bars: [
'#D80071',
'#744E96',
'#0035A9',
],
},
{
id: 'boyflux',
label: 'Boyflux',
bars: [
'#D7E9F8',
'#6FACF5',
'#023670',
'#9EEDAC',
'#023670',
'#6FACF5',
'#D7E9F8',
],
},
{
id: 'ceterosexual',
label: 'Ceterosexual',
bars: [
'#FCF980',
'#169C47',
'#FFF',
'#000',
],
},
{
id: 'demiboy',
label: 'Demiboy',
bars: [
'#7F7F7F',
'#C4C4C4',
'#9AD9EB',
'#FFF',
'#9AD9EB',
'#C4C4C4',
'#7F7F7F',
],
},
{
id: 'demiflux',
label: 'Demiflux',
bars: [
'#7F7F7F',
'#DADADA',
'#FFB6B8',
'#F4F691',
'#9AD9EB',
'#DADADA',
'#7F7F7F',
],
},
{
id: 'demigender',
label: 'Demigender',
bars: [
'#7F7F7F',
'#C4C4C4',
'#FAFF72',
'#FFF',
'#FAFF72',
'#C4C4C4',
'#7F7F7F',
],
},
{
id: 'demigirl',
label: 'Demigirl',
bars: [
'#7F7F7F',
'#C4C4C4',
'#FFAEC9',
'#FFF',
'#FFAEC9',
'#C4C4C4',
'#7F7F7F',
],
},
{
id: 'demigirlflux',
label: 'Demigirlflux',
bars: [
'#7F7F7F',
'#C4C4C4',
'#A24AA3',
'#FEAFC9',
'#FFF',
'#FEAFC9',
'#A24AA3',
'#C4C4C4',
'#7F7F7F',
],
},
{
id: 'demisexual',
label: 'Demisexual',
bars: [
'#000',
'#FFF',
'#6f0071',
'#d3d3d3',
],
},
{
id: 'fraysexual',
label: 'Fraysexual',
bars: [
'#226CB5',
'#93E7DD',
'#FFF',
'#636363',
],
},
{
id: 'mlm',
label: 'MLM',
bars: [
'#008F72',
'#1BD0AD',
'#9BEAC4',
'#FFF',
'#7DB1E5',
'#4E45CD',
'#390B7A',
],
},
{
id: 'genderfluid',
label: 'Genderfluid',
bars: [
'#FF77A5',
'#F5F5F5',
'#C009D8',
'#232323',
'#2C39BF',
],
},
{
id: 'genderqueer',
label: 'Genderqueer',
bars: [
'#B880DE',
'#FFF',
'#478318',
],
},
{
id: 'girlflux',
label: 'Girlflux',
bars: [
'#F8E6D8',
'#F1526D',
'#BF0310',
'#E8C586',
'#BF0310',
'#F1526D',
'#F8E6D8',
],
},
{
id: 'greysexual',
label: 'Greysexual',
bars: [
'#740195',
'#AEB2AA',
'#FFF',
'#AEB2AA',
'#740195',
],
},
{
id: 'intersex',
label: 'Intersex',
bars: [
'#FFD900',
'#7A00AC',
'#FFD900',
],
},
{
id: 'lesbian',
label: 'Lesbian',
bars: [
'#D52800',
'#FD9954',
'#FFF',
'#D261A4',
'#A40061',
],
},
{
id: 'nonbinary',
label: 'NonBinary',
bars: [
'#FEF32A',
'#FEFEFE',
'#9D57D2',
'#000',
],
},
{
id: 'omnisexual',
label: 'Omnisexual',
bars: [
'#FF9DCF',
'#FF51C0',
'#1A0042',
'#675FFF',
'#8EA9FF',
],
},
{
id: 'pangender',
label: 'Pangender',
bars: [
'#FFF798',
'#FFDDCD',
'#FFEBFB',
'#FFF',
'#FFEBFB',
'#FFDDCD',
'#FFF798',
],
},
{
id: 'pansexual',
label: 'Pansexual',
bars: [
'#FF148E',
'#FFDA00',
'#14B5FF',
],
},
{
id: 'polysexual',
label: 'Polysexual',
bars: [
'#F614BA',
'#00D769',
'#1593F5',
],
},
{
id: 'philadelphia-pride',
label: 'Philadelphia Pride',
bars: [
'#000',
'#794E10',
'#E60000',
'#FF8E00',
'#FFEF00',
'#00821B',
'#004BFF',
'#770089',
],
},
{
id: 'pride',
label: 'Pride',
bars: [
'#E60000',
'#FF8E00',
'#FFEF00',
'#00821B',
'#004BFF',
'#770089',
],
},
{
id: 'transgender',
label: 'Transgender',
bars: [
'#5CCFFA',
'#F4ABB8',
'#FFF',
'#F4ABB8',
'#5CCFFA',
],
},
{
id: 'trigender',
label: 'Trigender',
bars: [
'#FF95C4',
'#9580FF',
'#6AD969',
'#9580FF',
'#FF95C4',
],
},
])
}

2
vue.config.js

@ -1,4 +1,4 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
transpileDependencies: true,
})

Loading…
Cancel
Save