Updated Public Page Artwork (#20309)

* from rainbow to lava lamp

* svg paths to divs for performance

* Clean up styles

* Public view themable options

* Make speed themable

* Add changeset

---------

Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
This commit is contained in:
Ben Haynes
2023-11-03 13:17:38 -06:00
committed by GitHub
parent bbefc62ef4
commit 3faab8d8ae
5 changed files with 187 additions and 69 deletions

View File

@@ -0,0 +1,6 @@
---
'@directus/themes': minor
'@directus/app': minor
---
Added a new login page default art

View File

@@ -1,9 +1,6 @@
<script setup lang="ts">
import { useServerStore } from '@/stores/server';
import { getAppearance } from '@/utils/get-appearance';
import { getRootPath } from '@/utils/get-root-path';
import { cssVar } from '@directus/utils/browser';
import Color from 'color';
import { storeToRefs } from 'pinia';
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
@@ -21,47 +18,6 @@ const serverStore = useServerStore();
const { info } = storeToRefs(serverStore);
const colors = computed(() => {
const primary = info.value?.project?.project_color || 'var(--theme--primary)';
const primaryHex = primary.startsWith('var(--') ? cssVar(primary.substring(4, primary.length - 1)) : primary;
const isDark = getAppearance() === 'dark';
const primaryColor = Color(primaryHex);
const primaryColorHSL = primaryColor.hsl() as unknown as {
model: 'hsl';
color: [number, number, number];
valpha: number;
};
/**
* The default light mode secondary color is based on the standard difference between Directus purple and pink, which is:
* primary = 250.9, 100, 63.3
* secondary = 320, 100, 80
* diff = +69.1, 0, +16.7
*
* For dark mode, we greatly reduce the lightness value to -50
*/
const secondaryColor = Color({
h: primaryColorHSL.color[0] + (isDark ? -69.1 : 69.1),
s: primaryColorHSL.color[1] + 0,
l: primaryColorHSL.color[2] + (isDark ? -50 : 16.7),
});
const shades = [];
for (let i = 1; i < 6; i++) {
const color = Color(primaryColor).mix(secondaryColor, i / 10);
shades.push(color.hex().toString());
}
return {
primary: primaryColor.hex().toString(),
secondary: secondaryColor.hex().toString(),
shades: shades,
};
});
const hasCustomBackground = computed(() => {
return !!info.value?.project?.public_background;
});
@@ -121,29 +77,11 @@ const logoURL = computed<string | null>(() => {
</div>
</div>
<div class="art" :style="artStyles">
<svg v-if="!hasCustomBackground" viewBox="0 0 1152 1152" preserveAspectRatio="none" fill="none" class="fallback">
<rect width="1152" height="1152" :fill="colors.primary" />
<path
d="M1152 409.138C1148.61 406.92 1146.7 405.765 1146.7 405.765L6.87761e-07 958.424L-7.3277e-07 1152L506.681 1152C558.985 1126.93 614.88 1101.25 672.113 1074.95C839.401 998.085 1018.12 915.967 1152 828.591L1152 409.138Z"
:fill="colors.shades[0]"
/>
<path
d="M1152 159.866C1130.19 146.319 1114.45 138.98 1114.45 138.98L-6.09246e-07 759.421L-3.66364e-07 1152L88.7501 1152C131.867 1108.8 194.289 1054.33 281.936 993.927C371.847 931.97 507.23 864.306 651.138 792.382C828.097 703.939 1017.95 609.052 1152 510.407L1152 159.866Z"
:fill="colors.shades[1]"
/>
<path
d="M772.894 -0.000472457L-4.49523e-07 457.782L-5.22658e-07 953.071C22.142 919.082 94.6279 821.1 262.854 696.786C351.427 631.334 485.624 558.338 628.272 480.744C816.642 378.28 1019.75 267.8 1152 156.087L1152 -0.000477328L772.894 -0.000472457Z"
:fill="colors.shades[2]"
/>
<path
d="M286.365 -0.000483108L-1.73191e-07 176.373L2.43255e-06 662.21C33.488 615.87 106.028 529.959 243.326 424.909C331.205 357.671 464.771 281.956 606.749 201.473C720.914 136.756 840.519 68.9554 946.182 -0.000479285L286.365 -0.000483108Z"
:fill="colors.shades[3]"
/>
<path
d="M0.00195277 363.139C37.1564 313.499 107.096 233.66 228.181 137.623C281.94 94.9838 353.09 48.7594 432.872 9.43526e-06L0.00195595 0L0.00195277 363.139Z"
:fill="colors.shades[4]"
/>
</svg>
<div v-if="!hasCustomBackground" class="fallback">
<div><div></div></div>
<div><div></div></div>
<div><div></div></div>
</div>
<transition name="scale">
<v-image v-if="foregroundURL" class="foreground" :src="foregroundURL" :alt="info?.project?.project_name" />
@@ -225,12 +163,157 @@ const logoURL = computed<string | null>(() => {
background-size: cover;
.fallback {
position: absolute;
background-color: var(--theme--public--art--background);
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: -1;
overflow: hidden;
> div {
position: absolute;
> div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
transform-origin: center center;
}
}
> div:nth-child(1) {
bottom: -25%;
left: -25%;
height: 50%;
width: 50%;
filter: blur(100px);
z-index: 3;
> div {
background-color: var(--theme--public--art--primary);
opacity: 0.5;
animation-name: floating1;
animation-duration: calc(33s / var(--theme--public--art--speed));
}
}
> div:nth-child(2) {
bottom: -25%;
left: 15%;
height: 40%;
width: 60%;
filter: blur(150px);
z-index: 2;
> div {
background: linear-gradient(
107.7deg,
var(--theme--public--art--primary) 0%,
var(--theme--public--art--secondary) 50%
);
opacity: 0.7;
animation-name: floating2;
animation-duration: calc(19s / var(--theme--public--art--speed));
}
}
> div:nth-child(3) {
bottom: -20%;
left: 75%;
height: 20%;
width: 40%;
filter: blur(50px);
z-index: 1;
> div {
background-color: var(--theme--public--art--primary);
opacity: 0.6;
animation-name: floating3;
animation-duration: calc(27s / var(--theme--public--art--speed));
}
}
@keyframes floating1 {
0% {
transform: translate(00%, 00%) scale(1, 1) rotate(0deg);
}
10% {
transform: translate(25%, -20%) scale(1.5, 1) rotate(0deg);
}
20% {
transform: translate(10%, -25%) scale(1, 1.5) rotate(0deg);
}
30% {
transform: translate(00%, -20%) scale(1, 1.5) rotate(-45deg);
}
40% {
transform: translate(10%, -30%) scale(1, 2) rotate(0deg);
}
50% {
transform: translate(15%, -35%) scale(2, 0.5) rotate(45deg);
}
60% {
transform: translate(10%, -30%) scale(1, 2) rotate(90deg);
}
70% {
transform: translate(25%, -10%) scale(1, 1.5) rotate(45deg);
}
80% {
transform: translate(40%, 20%) scale(1.5, 0.5) rotate(-45deg);
}
90% {
transform: translate(15%, -20%) scale(2, 1.5) rotate(0deg);
}
100% {
transform: translate(00%, 00%) scale(1, 1) rotate(0deg);
}
}
@keyframes floating2 {
0% {
transform: translate(00%, 00%) scale(1, 1) rotate(0deg);
}
20% {
transform: translate(-10%, -05%) scale(1.5, 1.5) rotate(15deg);
}
40% {
transform: translate(00%, -15%) scale(2, 0.5) rotate(-45deg);
}
60% {
transform: translate(-15%, -10%) scale(1.5, 1) rotate(45deg);
}
80% {
transform: translate(-25%, -05%) scale(2.5, 0.5) rotate(180deg);
}
100% {
transform: translate(00%, 00%) scale(1, 1) rotate(0deg);
}
}
@keyframes floating3 {
0% {
transform: translate(00%, 00%) scale(1, 1) rotate(0deg);
}
25% {
transform: translate(-10%, -10%) scale(2, 1) rotate(-15deg);
}
50% {
transform: translate(-20%, -05%) scale(1, 0.5) rotate(45deg);
}
75% {
transform: translate(-15%, -15%) scale(2, 1.5) rotate(180deg);
}
100% {
transform: translate(00%, 00%) scale(1, 1) rotate(0deg);
}
}
}
.foreground {

View File

@@ -6,6 +6,7 @@ const FamilyName = Type.String({ $id: 'FamilyName' });
const Length = Type.String({ $id: 'Length' });
const Percentage = Type.String({ $id: 'Percentage' });
const BoxShadow = Type.String({ $id: 'BoxShadow' });
const Number = Type.String({ $id: 'Number' });
const LineWidth = Type.Union([Type.String(), Type.Literal('thin'), Type.Literal('medium'), Type.Literal('thick')], {
$id: 'LineWidth',
@@ -189,6 +190,15 @@ const Rules = Type.Object({
}),
}),
}),
public: Type.Object({
art: Type.Object({
background: Type.Ref(Color),
primary: Type.Ref(Color),
secondary: Type.Ref(Color),
speed: Type.Ref(Number),
}),
}),
});
export const ThemeSchema = Type.Object({
@@ -205,6 +215,7 @@ export const Definitions = {
Percentage,
LineWidth,
BoxShadow,
Number,
},
};

View File

@@ -173,5 +173,14 @@ export const theme: Theme = {
},
},
},
public: {
art: {
background: '#0e1c2f',
primary: 'var(--theme--primary)',
secondary: 'var(--theme--secondary)',
speed: '1',
},
},
},
};

View File

@@ -67,7 +67,7 @@ export const theme: Theme = {
},
modules: {
background: '#18222f',
background: '#0e1c2f',
borderColor: 'transparent',
borderWidth: '0px',
@@ -173,5 +173,14 @@ export const theme: Theme = {
},
},
},
public: {
art: {
background: '#0e1c2f',
primary: 'var(--theme--primary)',
secondary: 'var(--theme--secondary)',
speed: '1',
},
},
},
};