262 lines
11 KiB
Vue
262 lines
11 KiB
Vue
<template>
|
|
<div class="grid-container h-screen">
|
|
<div class="wrapper">
|
|
<div class="grid-header">
|
|
<h1 class="text-center text-4xl font-bold">Batch Color Converter</h1>
|
|
<button @click="batchConvert" type="button">Convert</button>
|
|
</div>
|
|
<div class="grid-main">
|
|
<div class="input-container">
|
|
<textarea v-model="inputBox" class="resize-y w-full h-96 border border-gray-200 shadow rounded py-2 px-4" placeholder="#fff"></textarea>
|
|
</div>
|
|
<div class="output-wrapper">
|
|
<table class="font-ubuntu w-full">
|
|
<thead>
|
|
<tr>
|
|
<th class="p-4">Preview</th>
|
|
<th class="p-4">Hex(a)</th>
|
|
<th class="p-4">RGB(a)</th>
|
|
<th class="p-4">HSL(a)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="(color, idx) in convertedColors" :key="idx" class="border-t border-gray-300">
|
|
<td v-show="color.error" class="text-center px-2 py-4 bg-red-200 text-red-700 font-bold" colspan="4">Error with {{ color.raw }}</td>
|
|
<td v-show="!color.error">
|
|
<div class="block mx-2 my-4" style="height: 25px" :style="{ background: color.hex }"></div>
|
|
</td>
|
|
<td v-show="!color.error" class="color-cell cursor-pointer"><div class="text-center px-2 py-4 border border-transparent hover:border-gray-500" v-on:click="updateClipboard(color.hex)">{{ color.hex }}</div></td>
|
|
<td v-show="!color.error" class="color-cell cursor-pointer"><div class="text-center px-2 py-4 border border-transparent hover:border-gray-500" v-on:click="updateClipboard(color.rgb)">{{ color.rgb }}</div></td>
|
|
<td v-show="!color.error" class="color-cell cursor-pointer"><div class="text-center px-2 py-4 border border-transparent hover:border-gray-500" v-on:click="updateClipboard(color.hsl)">{{ color.hsl }}</div></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="grid-footer">
|
|
<p>You can take a look at <a href="https://git.ditoforge.com/brian/batch-color-converter" title="Source code for this page" class="text-blue-400 font-bold hover:text-blue-700 transition">this terrible code over on my git server</a>.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { defineComponent, reactive, ref, computed, watch, onBeforeMount, onMounted } from 'vue'
|
|
import { Color } from './converters/index.js'
|
|
|
|
export default defineComponent({
|
|
emits: [],
|
|
|
|
props: {},
|
|
|
|
components: {},
|
|
|
|
setup(props, { attrs, slots, emit, expose }) {
|
|
let defaultInputs = [
|
|
"ccc",
|
|
"#db2777aa",
|
|
"rgb(64, 240, 18)",
|
|
"hsla(240, 86.9%, 50.7%, 0.8)",
|
|
]
|
|
let inputBox = ref("ccc\n#4f46e5\n#db2777aa\n")
|
|
|
|
let convertedColors = ref([])
|
|
|
|
let showStatusMessage = ref(false)
|
|
let showErrorMessage = ref(false)
|
|
|
|
//const hexRegex = /^\#?[a-fA-F0-9]{3,6}$/i
|
|
//const hexRegex = /^(?=(\#?)[a-fA-F0-9]$)(?:.{3}|.{6})$/i
|
|
const hexRegex = /^(\#?[a-fA-F0-9]{3}|\#?[a-fA-F0-9]{6})$/i
|
|
//const hexaRegex = /^(\#?)[a-fA-F0-9]{4,8}$/i
|
|
//const hexaRegex = /^(?=\#?[a-fA-F0-9]$)(?:.{4}|.{8})$/i
|
|
const hexaRegex = /^(\#?[a-fA-F0-9]{4}|\#?[a-fA-F0-9]{8})$/i
|
|
const rgbRegex = /^rgb\(\s*\d{1,3}\s*,?\s*\d{1,3}\s*,?\s*\d{1,3}\s*\)$/i
|
|
//const rgbaRegex = /^rgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*(0(\.[0-9])?|1(\.0)?)\s*\)/i
|
|
const rgbaRegex = /^rgb(a?)\(\s*\d{1,3}\s*,?\s*\d{1,3}\s*,?\s*\d{1,3}\s*(,|\/)*\s*((0(\.[0-9]{1,3}))?|(1(\.0{1,3}))?|([1-9][0-9]?|100))\s*\)$/i
|
|
const hslRegex = /^hsl\(\s*\d{1,3}\s*,?\s*\d{1,3}(\.[0-9])?%\s*,?\s*\d{1,3}(\.[0-9])?%\s*\)\s*$/i
|
|
//const hslaRegex = /^hsla\(\s*\d{1,3}\s*,*\s*\d{1,3}(\.[0-9])?%\s*,*\s*\d{1,3}(\.[0-9])?%\s*(,|\/)*\s*((0(\.[0-9]{1,3}))?|(1(\.0{1,3}))?)\s*\)/i
|
|
const hslaRegex = /^hsl(a?)\(\s*\d{1,3}\s*,?\s*\d{1,3}(\.[0-9])?%\s*,?\s*\d{1,3}(\.[0-9])?%\s*(,|\/)*\s*((0(\.[0-9]{1,3}))?|(1(\.0{1,3}))?|([1-9][0-9]?|100))\s*\)\s*$/i
|
|
|
|
// computed properties
|
|
/*let compVariable = computed(() => {
|
|
//return 'foo'
|
|
})*/
|
|
|
|
// watchers
|
|
/*watch(inputBox, (newValue, oldValue) => {
|
|
//
|
|
})*/
|
|
|
|
// lifecycle hooks
|
|
onBeforeMount(() => {
|
|
inputBox.value = defaultInputs.join("\n")
|
|
})
|
|
|
|
onMounted(() => {
|
|
batchConvert()
|
|
})
|
|
|
|
// methods
|
|
function batchConvert() {
|
|
convertedColors.value = []
|
|
|
|
// first attempt to split by new-line characters
|
|
let inputArray = inputBox.value.split('\n')
|
|
let count = inputArray.length
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
// check for empty line, non hex(a)/rgb(a)/hsl(a) string
|
|
let inputLine = inputArray[i].toLowerCase().trim()
|
|
if (inputLine.length === 0) {
|
|
continue
|
|
}
|
|
|
|
let converted = {
|
|
error: false,
|
|
raw: inputLine,
|
|
hex: "",
|
|
rgb: "",
|
|
hsl: "",
|
|
}
|
|
|
|
let rgb = { red: null, green: null, blue: null, alpha: null }
|
|
let hsl = { hue: null, saturation: null, lightness: null, alpha: null }
|
|
|
|
if (hexRegex.test(inputLine)) {
|
|
let hexString = inputLine
|
|
|
|
// doing this just to add pound symbol for the table output
|
|
// if it doesn't already exist and to allow the use of
|
|
// the hex value without leading pound symbol
|
|
// for conversion to other formats.
|
|
hexString = hexString.replace('#', '')
|
|
|
|
rgb = Color.hexToRgb(hexString)
|
|
hsl = Color.rgbToHsl(rgb.red, rgb.green, rgb.blue)
|
|
|
|
converted.hex = "#" + hexString
|
|
converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ")"
|
|
converted.hsl = "hsl(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%)"
|
|
} else if (hexaRegex.test(inputLine)) {
|
|
let hexString = inputLine
|
|
hexString = hexString.replace('#', '')
|
|
|
|
rgb = Color.hexaToRgba(hexString)
|
|
hsl = Color.rgbaToHsla(rgb.red, rgb.green, rgb.blue, rgb.alpha)
|
|
|
|
converted.hex = "#" + hexString
|
|
converted.rgb = "rgba(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ", " + rgb.alpha + ")"
|
|
converted.hsl = "hsla(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%, " + hsl.alpha + ")"
|
|
}
|
|
|
|
if (rgbRegex.test(inputLine)) {
|
|
// extract the values for red, green, blue.
|
|
let rgbStrArray = inputLine.split(',')
|
|
if (rgbStrArray.length !== 3) {
|
|
rgbStrArray = inputLine.split(' ')
|
|
}
|
|
let red = Number.parseInt(rgbStrArray[0].replace('rgb(', '').trim())
|
|
let green = Number.parseInt(rgbStrArray[1].trim())
|
|
let blue = Number.parseInt(rgbStrArray[2].replace(')', '').trim())
|
|
|
|
hsl = Color.rgbToHsl(red, green, blue)
|
|
|
|
converted.hex = "#" + Color.rgbToHex(red, green, blue)
|
|
converted.rgb = "rgb(" + red + ", " + green + ", " + blue + ")"
|
|
converted.hsl = converted.hsl = "hsl(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%)"
|
|
} else if (rgbaRegex.test(inputLine)) {
|
|
// extract the values for red, green, blue, alpha.
|
|
let alphaIndex = 3
|
|
let rgbaStrArray = inputLine.split(',')
|
|
if (rgbaStrArray.length !== 4) {
|
|
alphaIndex = 4
|
|
rgbaStrArray = inputLine.split(' ')
|
|
}
|
|
let red = Number.parseInt(rgbaStrArray[0].replace('rgb(', '').replace('rgba(', '').trim())
|
|
let green = Number.parseInt(rgbaStrArray[1].trim())
|
|
let blue = Number.parseInt(rgbaStrArray[2].trim())
|
|
let alpha = rgbaStrArray[alphaIndex].replace(')', '').trim()
|
|
if (alpha > 1) { alpha /= 100 }
|
|
|
|
hsl = Color.rgbToHsl(red, green, blue)
|
|
|
|
converted.hex = "#" + Color.rgbaToHexa(red, green, blue, alpha)
|
|
converted.rgb = "rgba(" + red + ", " + green + ", " + blue + ", " + alpha + ")"
|
|
converted.hsl = "hsla(" + hsl.hue + ", " + hsl.saturation + "%, " + hsl.lightness + "%, " + alpha + ")"
|
|
}
|
|
|
|
if (hslRegex.test(inputLine)) {
|
|
// extract the values for hue, saturation, lightness.
|
|
let hslStrArray = inputLine.split(',')
|
|
if (hslStrArray.length !== 3) {
|
|
hslStrArray = inputLine.split(' ')
|
|
}
|
|
let hue = hslStrArray[0].replace('hsl(', '').trim()
|
|
let saturation = hslStrArray[1].replace('%', '').trim()
|
|
let lightness = hslStrArray[2].replace('%', '').replace(')', '').trim()
|
|
|
|
rgb = Color.hslToRgb(hue, saturation, lightness)
|
|
|
|
converted.hex = "#" + Color.hslToHex(hue, saturation, lightness)
|
|
converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ")"
|
|
converted.hsl = "hsl(" + hue + ", " + saturation + "%, " + lightness + "%)"
|
|
} else if (hslaRegex.test(inputLine)) {
|
|
// extract the values for hue, saturation, lightness, alpha.
|
|
let alphaIndex = 3
|
|
let hslaStrArray = inputLine.split(',')
|
|
if (hslaStrArray.length !== 4) {
|
|
alphaIndex = 4
|
|
hslaStrArray = inputLine.split(' ')
|
|
}
|
|
let hue = hslaStrArray[0].replace('hsl(', '').replace('hsla(', '').trim()
|
|
let saturation = hslaStrArray[1].replace('%', '').trim()
|
|
let lightness = hslaStrArray[2].replace('%', '').trim()
|
|
let alpha = hslaStrArray[alphaIndex].replace(')', '').trim()
|
|
if (alpha > 1) { alpha /= 100 }
|
|
|
|
rgb = Color.hslaToRgba(hue, saturation, lightness, alpha)
|
|
|
|
converted.hex = "#" + Color.hslaToHexa(hue, saturation, lightness, alpha)
|
|
converted.rgb = "rgb(" + rgb.red + ", " + rgb.green + ", " + rgb.blue + ", " + alpha + ")"
|
|
converted.hsl = "hsla(" + hue + ", " + saturation + "%, " + lightness + "%, " + alpha + ")"
|
|
}
|
|
|
|
convertedColors.value.push(converted)
|
|
}
|
|
}
|
|
|
|
function updateClipboard (text) {
|
|
clipboard.writeText(text).then(() => {
|
|
showErrorMessage = false
|
|
showStatusMessage = true
|
|
setTimeout(() => {
|
|
showStatusMessage = false
|
|
}, 1000)
|
|
})
|
|
.catch(() => {
|
|
showStatusMessage = false
|
|
showErrorMessage = true
|
|
setTimeout(() => {
|
|
showErrorMessage = false
|
|
}, 1000)
|
|
})
|
|
}
|
|
|
|
return {
|
|
inputBox,
|
|
convertedColors,
|
|
showStatusMessage,
|
|
showErrorMessage,
|
|
batchConvert,
|
|
updateClipboard,
|
|
}
|
|
},
|
|
})
|
|
</script>
|
|
|
|
<style>
|
|
@import './assets/base.css'
|
|
|
|
</style>
|