479 lines
31 KiB
HTML
479 lines
31 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="initial-scale=1.0">
|
|
<meta name="color-scheme" content="dark">
|
|
<link rel="shortcut icon" href="https://gleam.run/images/lucy/lucy.svg">
|
|
<title>BGleam</title>
|
|
<style>
|
|
html, body {
|
|
margin: 0;
|
|
padding: 0;
|
|
height: 100%;
|
|
font-family: sans-serif;
|
|
background-color: #1c1b22;
|
|
}
|
|
body {
|
|
display: flex;
|
|
}
|
|
#sidebar {
|
|
width: 28rem;
|
|
min-width: 28rem;
|
|
height: 100%;
|
|
user-select: none;
|
|
border-right: 2px solid white;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
#sidebar header {
|
|
padding: 1rem;
|
|
border-bottom: 2px solid white;
|
|
}
|
|
#sidebar h2, #sidebar p {
|
|
margin: 0;
|
|
text-align: center;
|
|
}
|
|
#sidebar p {
|
|
font-size: 0.8rem;
|
|
margin-top: 0.5rem;
|
|
}
|
|
#settings {
|
|
flex-grow: 1;
|
|
padding: 1rem;
|
|
display: grid;
|
|
grid-gap: 1rem;
|
|
grid-template-columns: [label] min-content [maininput] 1fr [subinput] 4.2rem [end];
|
|
grid-template-rows: auto;
|
|
align-items: center;
|
|
align-content: start;
|
|
overflow-y: auto;
|
|
}
|
|
#settings label {
|
|
grid-column: label;
|
|
white-space: nowrap;
|
|
}
|
|
#settings input, #settings select {
|
|
font-size: 0.9rem;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
#settings select {
|
|
grid-column-start: maininput;
|
|
grid-column-end: end;
|
|
padding: 0.4rem 0.6rem;
|
|
}
|
|
#settings input[type="range"] {
|
|
grid-column: maininput;
|
|
}
|
|
#settings input[type="number"] {
|
|
grid-column: subinput;
|
|
padding: 0.4rem 0.6rem;
|
|
padding-right: 0;
|
|
}
|
|
#settings input[type="text"] {
|
|
grid-column: maininput;
|
|
padding: 0.4rem 0.6rem;
|
|
}
|
|
#settings input[type="checkbox"] {
|
|
grid-column: maininput;
|
|
width: 1.2rem;
|
|
height: 1.2rem;
|
|
}
|
|
#settings input[type="color"] {
|
|
grid-column: subinput;
|
|
height: 100%;
|
|
padding: 0.2rem;
|
|
}
|
|
#settings .checkboxGroup {
|
|
grid-column-start: maininput;
|
|
grid-column-end: end;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
#settings .checkboxGroup input[type="checkbox"] {
|
|
margin-left: 0.5rem;
|
|
margin-right: 1rem;
|
|
}
|
|
#settings .checkboxGroup input[type="checkbox"]:last-child {
|
|
margin-right: 0;
|
|
}
|
|
#saveButtonContainer {
|
|
width: 100%;
|
|
grid-column-start: label;
|
|
grid-column-end: end;
|
|
display: flex;
|
|
}
|
|
#saveSVGButton, #savePNGButton {
|
|
font-size: 1.2rem;
|
|
font-weight: bold;
|
|
width: 100%;
|
|
padding: 1rem;
|
|
cursor: pointer;
|
|
text-align: center;
|
|
text-decoration: none;
|
|
box-sizing: border-box;
|
|
background-color: #2b2a33;
|
|
color: white;
|
|
}
|
|
#saveSVGButton:hover, #savePNGButton:hover {
|
|
background-color: #52525e;
|
|
}
|
|
#colorSchemeInputs, #vignetteInputs {
|
|
display: contents;
|
|
}
|
|
#colorSchemeInputs.hidden, #vignetteInputs.hidden {
|
|
display: none;
|
|
}
|
|
#preview {
|
|
flex-grow: 1;
|
|
overflow: hidden;
|
|
}
|
|
#preview svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="sidebar">
|
|
<header>
|
|
<h2>Gleam Background Settings</h2>
|
|
<p>Credit to <a href="https://github.com/giacomocavalieri">Jak</a> for the original design idea.</p>
|
|
</header>
|
|
<form id="settings" oninput="updatePreview()" onchange="updateSaveHrefs()">
|
|
<label for="width">Width</label>
|
|
<input name="widthSlider" type="range" min="200" max="8192" value="1920" oninput="this.form.width.value = this.value">
|
|
<input id="width" name="width" type="number" min="200" max="8192" value="1920" oninput="this.form.widthSlider.value = this.value">
|
|
|
|
<label for="height">Height</label>
|
|
<input name="heightSlider" type="range" min="200" max="8192" value="1080" oninput="this.form.height.value = this.value">
|
|
<input id="height" name="height" type="number" min="200" max="8192" value="1080" oninput="this.form.heightSlider.value = this.value">
|
|
|
|
<label for="logoScale">Logo Scale</label>
|
|
<input name="logoScaleSlider" type="range" min="0.1" max="8" step=".01" value="0.7" oninput="this.form.logoScale.value = this.value">
|
|
<input id="logoScale" name="logoScale" type="number" min="0.1" max="8" step=".01" value="0.7" oninput="this.form.logoScaleSlider.value = this.value">
|
|
|
|
<label for="logoRotation">Logo Rotation</label>
|
|
<input name="logoRotationSlider" type="range" min="0" max="360" step=".5" value="348" oninput="this.form.logoRotation.value = this.value">
|
|
<input id="logoRotation" name="logoRotation" type="number" min="0" max="360" step=".5" value="348" oninput="this.form.logoRotationSlider.value = this.value">
|
|
|
|
<label for="patternScale">Pattern Scale</label>
|
|
<input name="patternScaleSlider" type="range" min="0.1" max="8" step=".01" value="1" oninput="this.form.patternScale.value = this.value">
|
|
<input id="patternScale" name="patternScale" type="number" min="0.1" max="8" step=".01" value="1" oninput="this.form.patternScaleSlider.value = this.value">
|
|
|
|
<label for="patternSpacing">Pattern Spacing</label>
|
|
<input name="patternSpacingSlider" type="range" min="1" max="4" step=".01" value="1.1" oninput="this.form.patternSpacing.value = this.value">
|
|
<input id="patternSpacing" name="patternSpacing" type="number" min="1" max="4" step=".01" value="1.1" oninput="this.form.patternSpacingSlider.value = this.value">
|
|
|
|
<label for="patternRotation">Pattern Rotation</label>
|
|
<input name="patternRotationSlider" type="range" min="0" max="360" step=".5" value="325" oninput="this.form.patternRotation.value = this.value">
|
|
<input id="patternRotation" name="patternRotation" type="number" min="0" max="360" step=".5" value="325" oninput="this.form.patternRotationSlider.value = this.value">
|
|
|
|
<label for="patternLucyRotation">Pattern Lucy Rotation</label>
|
|
<input name="patternLucyRotationSlider" type="range" min="0" max="360" step=".5" value="17.5" oninput="this.form.patternLucyRotation.value = this.value">
|
|
<input id="patternLucyRotation" name="patternLucyRotation" type="number" min="0" max="360" step=".5" value="17.5" oninput="this.form.patternLucyRotationSlider.value = this.value">
|
|
|
|
<label>Winking Lucy</label>
|
|
<div class="checkboxGroup">
|
|
<label for="winkingLucyLEnabled">Left Eye</label>
|
|
<input id="winkingLucyLEnabled" name="winkingLucyLEnabled" type="checkbox">
|
|
|
|
<label for="winkingLucyREnabled">Right Eye</label>
|
|
<input id="winkingLucyREnabled" name="winkingLucyREnabled" type="checkbox">
|
|
</div>
|
|
|
|
<label for="sleepyLucyEnabled">Sleepy Lucy</label>
|
|
<input id="sleepyLucyEnabled" name="sleepyLucyEnabled" type="checkbox">
|
|
|
|
<label for="colorScheme">Color Scheme</label>
|
|
<select id="colorScheme" name="colorScheme">
|
|
<option value="light" selected>Light</option>
|
|
<option value="dark">Dark</option>
|
|
<option value="blurple">Blurple</option>
|
|
<option value="custom">Custom</option>
|
|
</select>
|
|
|
|
<div id="colorSchemeInputs" class="hidden">
|
|
<label for="textPrimaryColor">Text Primary Color</label>
|
|
<input id="textPrimaryColor" name="textPrimaryColor" type="text" value="#ffaff3" oninput="this.form.textPrimaryColorPicker.value = normalizeColor(this.value)">
|
|
<input name="textPrimaryColorPicker" type="color" value="#ffaff3" oninput="this.form.textPrimaryColor.value = this.value">
|
|
|
|
<label for="textShadowColor">Text Shadow Color</label>
|
|
<input id="textShadowColor" name="textShadowColor" type="text" value="#a6f0fc" oninput="this.form.textShadowColorPicker.value = normalizeColor(this.value)">
|
|
<input name="textShadowColorPicker" type="color" value="#a6f0fc" oninput="this.form.textShadowColor.value = this.value">
|
|
|
|
<label for="lucyColor">Lucy Color</label>
|
|
<input id="lucyColor" name="lucyColor" type="text" value="#ffaff3" oninput="this.form.lucyColorPicker.value = normalizeColor(this.value)">
|
|
<input name="lucyColorPicker" type="color" value="#ffaff3" oninput="this.form.lucyColor.value = this.value">
|
|
|
|
<label for="lucyFaceColor">Lucy Face Color</label>
|
|
<input id="lucyFaceColor" name="lucyFaceColor" type="text" value="#fefefc" oninput="this.form.lucyFaceColorPicker.value = normalizeColor(this.value)">
|
|
<input name="lucyFaceColorPicker" type="color" value="#fefefc" oninput="this.form.lucyFaceColor.value = this.value">
|
|
|
|
<label for="lambdaColor">Lambda Color</label>
|
|
<input id="lambdaColor" name="lambdaColor" type="text" value="#a6f0fc" oninput="this.form.lambdaColorPicker.value = normalizeColor(this.value)">
|
|
<input name="lambdaColorPicker" type="color" value="#a6f0fc" oninput="this.form.lambdaColor.value = this.value">
|
|
|
|
<label for="outlineColor">Outline Color</label>
|
|
<input id="outlineColor" name="outlineColor" type="text" value="#fefefc" oninput="this.form.outlineColorPicker.value = normalizeColor(this.value)">
|
|
<input name="outlineColorPicker" type="color" value="#fefefc" oninput="this.form.outlineColor.value = this.value">
|
|
|
|
<label for="backgroundColor">BG Color</label>
|
|
<input id="backgroundColor" name="backgroundColor" type="text" value="#fcc3fb" oninput="this.form.backgroundColorPicker.value = normalizeColor(this.value)">
|
|
<input name="backgroundColorPicker" type="color" value="#fcc3fb" oninput="this.form.backgroundColor.value = this.value">
|
|
|
|
<label for="backgroundLucyColor">BG Lucy Color</label>
|
|
<input id="backgroundLucyColor" name="backgroundLucyColor" type="text" value="#fdb7f6" oninput="this.form.backgroundLucyColorPicker.value = normalizeColor(this.value)">
|
|
<input name="backgroundLucyColorPicker" type="color" value="#fdb7f6" oninput="this.form.backgroundLucyColor.value = this.value">
|
|
</div>
|
|
|
|
<label for="vignetteEnabled">Vignette</label>
|
|
<input id="vignetteEnabled" name="vignetteEnabled" type="checkbox">
|
|
|
|
<div id="vignetteInputs" class="hidden">
|
|
<label for="vignetteColor">Vignette Color</label>
|
|
<input id="vignetteColor" name="vignetteColor" type="text" value="#916dab" oninput="this.form.vignetteColorPicker.value = normalizeColor(this.value)">
|
|
<input name="vignetteColorPicker" type="color" value="#916dab" oninput="this.form.vignetteColor.value = this.value">
|
|
|
|
<label for="vignetteStart">Vignette Start</label>
|
|
<input name="vignetteStartSlider" type="range" min="0" max="2" step=".01" value="0.3" oninput="this.form.vignetteStart.value = this.value">
|
|
<input id="vignetteStart" name="vignetteStart" type="number" min="0" max="2" step=".01" value="0.3" oninput="this.form.vignetteStartSlider.value = this.value">
|
|
|
|
<label for="vignetteEnd">Vignette End</label>
|
|
<input name="vignetteEndSlider" type="range" min="0" max="2" step=".01" value="0.7" oninput="this.form.vignetteEnd.value = this.value">
|
|
<input id="vignetteEnd" name="vignetteEnd" type="number" min="0" max="2" step=".01" value="0.7" oninput="this.form.vignetteEndSlider.value = this.value">
|
|
|
|
<label for="vignetteBlendMode">Vignette Blend Mode</label>
|
|
<select id="vignetteBlendMode" name="vignetteBlendMode">
|
|
<option value="normal">Normal</option>
|
|
<option value="multiply" selected>Multiply</option>
|
|
<option value="screen">Screen</option>
|
|
<option value="overlay">Overlay</option>
|
|
<option value="darken">Darken</option>
|
|
<option value="lighten">Lighten</option>
|
|
<option value="color-dodge">Color Dodge</option>
|
|
<option value="color-burn">Color Burn</option>
|
|
<option value="hard-light">Hard Light</option>
|
|
<option value="soft-light">Soft Light</option>
|
|
<option value="difference">Difference</option>
|
|
<option value="exclusion">Exclusion</option>
|
|
<option value="hue">Hue</option>
|
|
<option value="saturation">Saturation</option>
|
|
<option value="color">Color</option>
|
|
<option value="luminosity">Luminosity</option>
|
|
<option value="plus-darker">Plus Darker</option>
|
|
<option value="plus-lighter">Plus Lighter</option>
|
|
</select>
|
|
</div>
|
|
</form>
|
|
<div id="saveButtonContainer">
|
|
<a id="saveSVGButton" href="#" download="gleam-background.svg">Save SVG</a>
|
|
<a id="savePNGButton" href="#" download="gleam-background.png">Save PNG</a>
|
|
</div>
|
|
</div>
|
|
<div id="preview"></div>
|
|
<script>
|
|
const createSVG = ({
|
|
width, height, logoScale, logoRotation, patternScale, patternSpacing, patternRotation,
|
|
patternLucyRotation, winkingLucyLEnabled, winkingLucyREnabled, sleepyLucyEnabled,
|
|
colorScheme, vignetteEnabled, vignetteColor, vignetteStart, vignetteEnd, vignetteBlendMode
|
|
}) =>
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}">
|
|
<defs>
|
|
<path id="lucy" d="M905.5 137.63c41.483-73.507 147.51-73.507 189 0l217.42 385.27c26.9 47.672 73.23 81.278 126.9 92.095l434.05 87.471c82.87 16.699 115.52 117.34 58.4 179.4l-299.67 325.58a188.15 188.15 0 0 0-48.49 149.06l50.83 439.33c9.69 83.71-75.98 146.04-152.89 110.88l-402.64-184.05a188.55 188.55 0 0 0-156.82 0l-402.63 184.05c-76.916 35.15-162.58-27.17-152.9-110.88l50.837-439.33c6.292-54.37-11.413-108.78-48.488-149.06l-299.68-325.58c-57.118-62.055-24.463-162.7 58.403-179.4l434.05-87.471c53.674-10.817 100-44.423 126.9-92.095z"/>
|
|
<pattern id="lucy-pattern" patternUnits="userSpaceOnUse" width="${200 * patternScale * patternSpacing}" height="${200 * patternScale * patternSpacing}" patternTransform="rotate(${patternRotation})">
|
|
<use href="#lucy" fill="${colorScheme.backgroundLucy}" transform="scale(${patternScale / 10}) translate(${1000 * patternSpacing - 1000} ${1000 * patternSpacing - 1000}) rotate(${patternLucyRotation} 1000 1000)"/>
|
|
</pattern>${vignetteEnabled ? `
|
|
<radialGradient id="vignette" fx="50%" fy="50%" r="100%">
|
|
<stop offset="${vignetteStart * 100}%" stop-color="${vignetteColor}" stop-opacity="0.0"/>
|
|
<stop offset="${vignetteEnd * 100}%" stop-color="${vignetteColor}" stop-opacity="1.0"/>
|
|
</radialGradient>` : ""}
|
|
<path id="gleam" d="M98.28 3.78c-27.603 0-95.41 15.403-95.41 86.811 0 54.607 43.005 87.21 87.611 87.21 41.605 0 82.809-28.402 82.809-76.408 0-20.003-5.599-30.004-21.401-30.004-2.4 0-30.604 1.199-52.407 2.399-3.6.2-6.202 3-6.202 6.001v.4l.4 23.804c0 3 1.8 6.2 5.6 6.2h.4c4.801-.2 18.403-1.199 20.803-1.199h.6c2 0 2.801.999 2.801 2.799 0 5.601-9.803 19.604-29.605 19.604-18.802 0-37.005-14.802-37.005-40.406 0-19.802 10.602-42.005 42.806-42.005 8.401 0 16.202 1.799 21.003 4.2.6.4 1.4.6 2 .6 2.4 0 4.401-1.8 4.801-3.6l6.8-33.604v-.801c0-2.4-1.399-4.599-3.2-5.399-9.401-4.401-21.004-6.603-33.205-6.603zm100.413-1.399c-2.2 0-4 1.799-4 4.2v163.421c0 2.2 1.8 4 4 4h40.206c2.2 0 4-1.8 4-4v-163.421c0-2.4-1.8-4.2-4-4.2zm132.616 55.606c-45.606 0-65.807 30.003-65.807 58.607 0 30.404 22.802 61.408 68.208 61.408h2.401c5.801 0 8.401-2.8 10.001-6.001 3-6.801 8.202-20.403 8.202-22.403 0-3.4-3.402-5.2-6.202-5.2h-.4c-1.4.2-2.999.199-4.399.199-25.003 0-35.405-16.001-35.405-30.203 0-12.401 8.001-20.803 17.602-20.803 8.401 0 12.201 6.4 12.201 8.2 0 2.8-1.399 3.202-11.8 5.602-2.6.6-4.202 1.599-4.202 3.799 0 .8 3.802 13.802 6.202 20.403.8 2.4 1.8 3.801 5.001 3.801 10.401-.4 25.203-2.601 34.604-5.802 11.802-4 15.602-11.602 15.602-20.803 0-6.601-2.201-50.805-51.807-50.805zm121.015-.801c-39.605 0-56.607 34.604-56.607 58.607 0 32.204 28.805 57.808 62.209 57.808 10.201 0 21.003-2.401 31.404-7.802 10.001 9.401 24.003 12.603 26.003 12.603 2.6 0 4.599-1.802 6.399-5.202l12.402-24.202c.4-.8.6-1.401.6-1.801 0-2-2.2-3.2-4.2-4.2-6.401-3.4-8.601-12.001-8.601-24.003 0-13.202 2.8-30.605 5.6-48.807v-1c0-2.4-1.4-5.001-6.6-5.401l-34.604-3h-1c-2.4 0-4.201.6-5.401 2-7.801-3.4-17.604-5.6-27.605-5.6zm9.202 36.805c5.801 0 11.201 2.799 13.601 6.8-.4 6.001-.6 11.403-.6 16.604 0 6.201.4 11.802 1 17.002-4.601 2-9.002 2.799-12.802 2.799-13.002 0-20.801-9.6-20.801-20.801 0-10.201 7.001-22.403 19.602-22.403zm196.425-36.604c-11.201 0-23.404 2.2-36.206 7.001-7.801-3-16.201-4.401-25.202-4.401-9.601 0-19.603 1.6-29.805 5.001l-12.001.6c-2 .2-3.6 1.8-3.6 4v.4l5.001 104.013c.2 2.2 1.801 4 3.801 4h.4l37.403-1.801c2.2-.2 3.801-2.001 3.801-4.401l-3.6-72.609c12.602 1 16.801 9.401 17.801 29.603l2 42.206c.2 2.2 1.801 4 3.801 4h.4l37.204-2c2.2-.2 3.801-2.001 3.801-4.401l-3.6-71.409c11.401 1.6 15.602 9.602 16.602 31.205 2.4 39.405 33.804 45.605 36.604 45.605 2 0 3.8-.801 6.001-2.801 0 0 17.002-16.202 17.002-16.602 1.2-1 1.6-2.2 1.6-3.2 0-2.2-2.4-4.202-3.6-5.202-9.401-7.401-11.602-17.201-12.402-30.203-2.2-36.404-28.003-58.607-63.207-58.607z"/>
|
|
<path id="kirakira" d="M250 218c-2.591.392-9.658 1.021-13.74 1.492-1.256.235-1.883 1.256-1.883 2.119 0 .471.706 5.416 1.02 7.929l-12.326-.313c-1.021 0-1.805.706-1.805 1.727l-.158 11.07v.156c0 .864.707 1.57 1.649 1.649l14.84.393 1.176 8.009-19.235 1.1c-.864.079-1.176.705-1.176 1.569v.236l.549 11.07c.079 1.021.863 1.727 1.805 1.727l20.256-1.178 2.827 18.922c.157.864 1.021 1.649 2.041 1.649h.156l13.269-.785c1.021-.079 1.649-.865 1.649-1.807 0-.079-.002-5.181-1.336-19.076l16.096-.944c.942 0 1.649-.784 1.649-1.805l-.551-10.992c-.079-.942-1.256-1.727-2.119-1.727h-.156l-16.567.942-.785-6.439 12.562.315c.942 0 1.807-.707 1.807-1.649l.156-11.07v-.156c0-.942-.785-1.649-1.649-1.649l-14.918-.393c-.707-4.24-1.334-7.774-1.883-10.365-.157-.864-1.022-1.727-2.67-1.727zm60.138.863c-1.021 0-1.884.786-2.041 1.807l-.942 11.54v.156c0 .942.863 1.963 1.883 1.963 8.087.235 21.434 1.1 31.326 1.414h.156c1.021 0 1.963-.786 2.041-1.807l.863-11.933v-.156c0-.942-.784-1.885-1.805-1.963-7.145-.314-22.69-.708-31.326-1.022zm-10.206 20.571c-.785 0-1.492.627-1.571 1.412l-1.178 12.326v.158c0 .785.629 1.412 1.414 1.49l30.775 2.512c.471.079 1.256.157 1.256 1.178 0 1.649-4.867 13.741-10.285 22.612-.235.471-.393.783-.393 1.176 0 .864.785 1.335 1.571 1.649l9.892 3.612c.392.157.707.236 1.1.236 1.177 0 2.198-.707 2.59-1.1 13.425-13.033 17.979-31.326 17.979-35.958 0-4.318-3.376-7.458-8.165-7.851l-44.83-3.453zm107.088-21.434c-2.591.392-9.658 1.021-13.74 1.492-1.256.235-1.883 1.256-1.883 2.119 0 .471.706 5.416 1.02 7.929l-12.326-.313c-1.021 0-1.805.706-1.805 1.727l-.158 11.07v.156c0 .864.707 1.57 1.649 1.649l14.84.393 1.176 8.009-19.235 1.1c-.864.079-1.176.705-1.176 1.569v.236l.549 11.07c.079 1.021.863 1.727 1.805 1.727l20.257-1.178 2.827 18.922c.157.864 1.021 1.649 2.041 1.649h.156l13.269-.785c1.021-.079 1.649-.865 1.649-1.807 0-.079-.002-5.181-1.336-19.076l16.096-.944c.942 0 1.649-.784 1.649-1.805l-.551-10.992c-.079-.942-1.256-1.727-2.119-1.727h-.156l-16.567.942-.785-6.439 12.562.315c.942 0 1.807-.707 1.807-1.649l.156-11.07v-.156c0-.942-.785-1.649-1.649-1.649l-14.918-.393c-.707-4.24-1.334-7.774-1.883-10.365-.157-.864-1.021-1.727-2.67-1.727zm60.138.863c-1.021 0-1.884.786-2.041 1.807l-.942 11.54v.156c0 .942.863 1.963 1.883 1.963 8.087.235 21.434 1.1 31.326 1.414h.157c1.021 0 1.963-.786 2.041-1.807l.863-11.933v-.156c0-.942-.784-1.885-1.805-1.963-7.145-.314-22.69-.708-31.326-1.022zm-10.206 20.571c-.785 0-1.492.627-1.571 1.412l-1.178 12.326v.158c0 .785.629 1.412 1.414 1.49l30.775 2.512c.471.079 1.256.157 1.256 1.178 0 1.649-4.867 13.741-10.285 22.612-.235.471-.393.783-.393 1.176 0 .864.785 1.335 1.571 1.649l9.892 3.612c.392.157.707.236 1.1.236 1.177 0 2.198-.707 2.59-1.1 13.425-13.033 17.979-31.326 17.979-35.958 0-4.318-3.376-7.458-8.165-7.851l-44.83-3.453z"/>
|
|
<path id="lambda" d="M29 2.28c-4.369 0-6.16.448-6.944 2.576l-5.153 14.115c-.112.448-.223.783-.223 1.119 0 1.568 1.792 1.68 3.696 1.68 6.945 0 11.874 1.457 13.33 8.401l3.135 13.666-10.529-4.032c-.112-.112-.335-.113-.447-.113-1.232 0-2.801 1.12-3.137 2.241l-20.163 49.174c-.112.224-.111.448-.111.672 0 1.232.783 2.577 1.791 2.801l19.043 5.376c.112 0 .337.113.561.113 1.12 0 2.688-.898 3.248-2.018 3.92-6.497 9.857-18.706 15.01-31.699l3.471 15.234c4.145 17.81 20.723 19.713 24.98 19.713 1.344 0 2.689-.446 3.809-2.239 0 0 7.504-11.203 7.392-11.539.448-.672.672-1.344.672-1.905 0-1.456-1.231-2.24-2.127-2.576-4.257-1.456-9.186-5.936-10.306-11.201l-11.089-50.407c-3.136-14.338-16.018-19.155-29.908-19.155z"/>
|
|
<g id="logo" transform="scale(${logoScale}) translate(-360 -180) rotate(${logoRotation} 360 180)" stroke-linecap="round" stroke-linejoin="round">
|
|
<g fill="none" stroke="${colorScheme.outline}" stroke-width="67.5">
|
|
<path d="M600 230h80z"/>
|
|
<use href="#lucy" stroke-width="520" transform="translate(518 208) scale(0.13) rotate(31 1000 1000)"/>
|
|
<use href="#lucy" stroke-width="1125" transform="translate(245 -85) scale(0.06) rotate(-20 1000 1000)"/>
|
|
<use href="#gleam"/>
|
|
<use href="#kirakira"/>
|
|
<g transform="translate(-18 13)">
|
|
<use href="#gleam"/>
|
|
<use href="#kirakira"/>
|
|
</g>
|
|
<use href="#lambda" stroke-width="99" transform="translate(702 -12) scale(0.683)"/>
|
|
<use href="#lambda" transform="translate(10 196) rotate(24)"/>
|
|
</g>
|
|
<g transform="translate(518 208) scale(0.13) rotate(31 1000 1000)">
|
|
<use href="#lucy" fill="${colorScheme.lucy}" stroke="none"/>
|
|
<path fill="none" stroke="${colorScheme.lucyFace}" stroke-width="80" d="M937 1194c16 69 110 69 126 0"/>${sleepyLucyEnabled ? `
|
|
<path fill="none" stroke="${colorScheme.lucyFace}" stroke-width="80" d="M607 994c16 69 110 69 126 0"/>
|
|
<path fill="none" stroke="${colorScheme.lucyFace}" stroke-width="80" d="M1267 994c16 69 110 69 126 0"/>` : `${winkingLucyLEnabled ? `
|
|
<path fill="none" stroke="${colorScheme.lucyFace}" stroke-width="80" d="M613 978.5l85 50l-85 50"/>` : `
|
|
<circle fill="${colorScheme.lucyFace}" stroke="none" cx="678.6" cy="1049.6" r="78.571"/>`}${winkingLucyREnabled ? `
|
|
<path fill="none" stroke="${colorScheme.lucyFace}" stroke-width="80" d="M1387 978.5l-85 50l85 50"/>` : `
|
|
<circle fill="${colorScheme.lucyFace}" stroke="none" cx="1321.4" cy="1049.6" r="78.571"/>`}`}
|
|
</g>
|
|
<g fill="${colorScheme.textShadow}" stroke="none" transform="translate(-18 13)">
|
|
<use href="#gleam"/>
|
|
<use href="#kirakira"/>
|
|
</g>
|
|
<g fill="${colorScheme.lambda}" stroke="none">
|
|
<use href="#lambda" transform="translate(702 -12) scale(0.683)"/>
|
|
<use href="#lambda" transform="translate(10 196) rotate(24)"/>
|
|
</g>
|
|
<g fill="${colorScheme.textPrimary}" stroke="${colorScheme.outline}" stroke-width="6.5">
|
|
<use href="#gleam"/>
|
|
<use href="#kirakira"/>
|
|
</g>
|
|
<use href="#lucy" fill="${colorScheme.lucy}" stroke="none" transform="translate(245 -85) scale(0.06) rotate(-20 1000 1000)"/>
|
|
</g>
|
|
</defs>
|
|
<rect fill="${colorScheme.background}" width="100%" height="100%"/>
|
|
<rect fill="url(#lucy-pattern)" width="100%" height="100%"/>${vignetteEnabled ? `
|
|
<rect fill="url(#vignette)" width="100%" height="100%" style="mix-blend-mode:${vignetteBlendMode}"/>` : ""}
|
|
<use href="#logo" x="50%" y="50%"/>
|
|
</svg>`
|
|
|
|
const colors = {
|
|
faffPink: "#ffaff3",
|
|
unnamedBlue: "#a6f0fc",
|
|
white: "#fefefc",
|
|
lightPink: "#fcc3fb",
|
|
lightishPink: "#fdb7f6",
|
|
charcoal: "#2f2f2f",
|
|
blackish: "#202020",
|
|
faafPink: "#faaff3",
|
|
blurple: "#b3bbe2",
|
|
turquoise: "#a2f7e3",
|
|
pureWhite: "#ffffff",
|
|
lightBlue: "#b8d7e2",
|
|
lightBlurple: "#b5c5e2",
|
|
}
|
|
const colorSchemes = new Map(Object.entries({
|
|
light: {
|
|
textPrimary: colors.faffPink,
|
|
textShadow: colors.unnamedBlue,
|
|
lucy: colors.faffPink,
|
|
lucyFace: colors.white,
|
|
lambda: colors.unnamedBlue,
|
|
outline: colors.white,
|
|
background: colors.lightPink,
|
|
backgroundLucy: colors.lightishPink,
|
|
},
|
|
dark: {
|
|
textPrimary: colors.charcoal,
|
|
textShadow: colors.faafPink,
|
|
lucy: colors.faffPink,
|
|
lucyFace: colors.charcoal,
|
|
lambda: colors.charcoal,
|
|
outline: colors.white,
|
|
background: colors.charcoal,
|
|
backgroundLucy: colors.blackish,
|
|
},
|
|
blurple: {
|
|
textPrimary: colors.blurple,
|
|
textShadow: colors.turquoise,
|
|
lucy: colors.blurple,
|
|
lucyFace: colors.pureWhite,
|
|
lambda: colors.turquoise,
|
|
outline: colors.pureWhite,
|
|
background: colors.lightBlue,
|
|
backgroundLucy: colors.lightBlurple,
|
|
}
|
|
}))
|
|
|
|
const form = document.getElementById("settings")
|
|
const colorSchemeInputs = document.getElementById("colorSchemeInputs")
|
|
const vignetteInputs = document.getElementById("vignetteInputs")
|
|
const saveSVGButton = document.getElementById("saveSVGButton")
|
|
const savePNGButton = document.getElementById("savePNGButton")
|
|
const preview = document.getElementById("preview")
|
|
const canvas = document.createElement("canvas")
|
|
const ctx = canvas.getContext("2d")
|
|
const img = document.createElement("img")
|
|
|
|
const normalizeColor = color => {
|
|
ctx.fillStyle = color
|
|
const m = ctx.fillStyle.match(/rgba\((.*?), (.*?), (.*?), .*?\)/)
|
|
if (m) ctx.fillStyle = `rgb(${m[1]}, ${m[2]}, ${m[3]})`
|
|
return ctx.fillStyle
|
|
}
|
|
|
|
const getFormData = () => {
|
|
const formData = new FormData(form)
|
|
const width = +formData.get("width")
|
|
const height = +formData.get("height")
|
|
const logoScale = +formData.get("logoScale")
|
|
const logoRotation = +formData.get("logoRotation")
|
|
const patternScale = +formData.get("patternScale")
|
|
const patternSpacing = +formData.get("patternSpacing")
|
|
const patternRotation = +formData.get("patternRotation")
|
|
const patternLucyRotation = +formData.get("patternLucyRotation")
|
|
const winkingLucyLEnabled = !!formData.get("winkingLucyLEnabled")
|
|
const winkingLucyREnabled = !!formData.get("winkingLucyREnabled")
|
|
const sleepyLucyEnabled = !!formData.get("sleepyLucyEnabled")
|
|
const colorSchemeName = `${formData.get("colorScheme")}`
|
|
const isCustomColorScheme = colorSchemeName === "custom"
|
|
const colorScheme = isCustomColorScheme ? {
|
|
textPrimary: `${formData.get("textPrimaryColor")}`,
|
|
textShadow: `${formData.get("textShadowColor")}`,
|
|
lucy: `${formData.get("lucyColor")}`,
|
|
lucyFace: `${formData.get("lucyFaceColor")}`,
|
|
lambda: `${formData.get("lambdaColor")}`,
|
|
outline: `${formData.get("outlineColor")}`,
|
|
background: `${formData.get("backgroundColor")}`,
|
|
backgroundLucy: `${formData.get("backgroundLucyColor")}`,
|
|
} : colorSchemes.get(colorSchemeName)
|
|
const vignetteEnabled = !!formData.get("vignetteEnabled")
|
|
const vignetteColor = `${formData.get("vignetteColor")}`
|
|
const vignetteStart = +formData.get("vignetteStart")
|
|
const vignetteEnd = +formData.get("vignetteEnd")
|
|
const vignetteBlendMode = `${formData.get("vignetteBlendMode")}`
|
|
const props = {
|
|
width, height, logoScale, logoRotation, patternScale, patternSpacing, patternRotation,
|
|
patternLucyRotation, winkingLucyLEnabled, winkingLucyREnabled, sleepyLucyEnabled,
|
|
colorScheme, vignetteEnabled, vignetteColor, vignetteStart, vignetteEnd, vignetteBlendMode
|
|
}
|
|
const svg = createSVG(props)
|
|
return { ...props, colorSchemeName, isCustomColorScheme, svg }
|
|
}
|
|
|
|
let curData = getFormData()
|
|
|
|
const updatePreview = () => {
|
|
curData = getFormData()
|
|
if (curData.isCustomColorScheme) colorSchemeInputs.classList.remove("hidden")
|
|
else colorSchemeInputs.classList.add("hidden")
|
|
if (curData.vignetteEnabled) vignetteInputs.classList.remove("hidden")
|
|
else vignetteInputs.classList.add("hidden")
|
|
preview.innerHTML = curData.svg
|
|
}
|
|
updatePreview()
|
|
|
|
const updateSaveHrefs = () => {
|
|
savePNGButton.setAttribute("href", "#")
|
|
saveSVGButton.setAttribute("href", "#")
|
|
const svgBlob = new Blob([curData.svg], { type: "image/svg+xml" })
|
|
const svgUrl = window.URL.createObjectURL(svgBlob)
|
|
saveSVGButton.setAttribute("href", svgUrl)
|
|
img.width = curData.width
|
|
img.height = curData.height
|
|
canvas.width = curData.width
|
|
canvas.height = curData.height
|
|
img.onload = () => {
|
|
ctx.drawImage(img, 0, 0, curData.width, curData.height)
|
|
canvas.toBlob(pngBlob => {
|
|
const pngUrl = window.URL.createObjectURL(pngBlob)
|
|
savePNGButton.setAttribute("href", pngUrl)
|
|
}, "image/png")
|
|
}
|
|
img.src = svgUrl
|
|
}
|
|
updateSaveHrefs()
|
|
</script>
|
|
</body>
|
|
</html>
|