Skip to content

Instantly share code, notes, and snippets.

@TheBITLINK
Created August 14, 2023 14:45
Show Gist options
  • Save TheBITLINK/1c84731cc433bef36b414c47ffb58872 to your computer and use it in GitHub Desktop.
Save TheBITLINK/1c84731cc433bef36b414c47ffb58872 to your computer and use it in GitHub Desktop.
Material Design 3 (Material You) Theme Generator for Vuetify
<script setup lang="ts">
import { useTheme } from 'vuetify'
import { vuetifyThemeFromImage } from '@/plugins/vuetifyM3ThemeGenerator'
const theme = useTheme()
async function onImageLoad (e: Event) {
const target = e.target as HTMLImageElement
const darkTheme = await vuetifyThemeFromImage(target, true)
const lightTheme = await vuetifyThemeFromImage(target, false)
theme.themes.value.dark.colors = darkTheme.colors
theme.themes.value.light.colors = lightTheme.colors
}
</script>
<template>
<img src="..." crossorigin="anonymous" @load="onImageLoad">
</template>
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import { md3 } from 'vuetify/blueprints'
import { vuetifyThemeFromColor } from '@/plugins/vuetifyM3ThemeGenerator'
export default createVuetify({
blueprint: md3,
theme: {
defaultTheme: 'dark',
themes: {
dark: vuetifyThemeFromColor(0xff64c798, true),
light: vuetifyThemeFromColor(0xff64c798, false)
}
}
})
import {
Hct,
SchemeTonalSpot,
MaterialDynamicColors,
DynamicScheme,
DynamicColor,
argbFromHex,
hexFromArgb,
sourceColorFromImage
} from '@material/material-color-utilities'
import kebabCase from 'just-kebab-case'
export function getDynamicColors(scheme: DynamicScheme) {
const tokens = Object.keys(MaterialDynamicColors) as (keyof typeof MaterialDynamicColors)[]
return Object.fromEntries(
tokens
.map((token) => {
const key = kebabCase(token)
const value = MaterialDynamicColors[token] as DynamicColor
if (!value.getArgb) return [key, null]
return [key, hexFromArgb(value.getArgb(scheme))]
})
.filter(([, value]) => value !== null)
)
}
export function vuetifyThemeFromColor(
sourceColor: number,
dark: boolean,
contrast = 0.3,
variables: Record<string, string | number> = {}
) {
const source = Hct.fromInt(sourceColor)
const scheme = new SchemeTonalSpot(source, dark, contrast)
const colors = getDynamicColors(scheme)
return {
dark,
colors,
variables: {}
}
}
export function vuetifyThemeFromHex(
hex: string,
dark: boolean,
contrast = 0.3,
variables: Record<string, string | number> = {}
) {
return vuetifyThemeFromColor(argbFromHex(hex), dark, contrast, variables)
}
export async function vuetifyThemeFromImage(
image: HTMLImageElement,
dark: boolean,
contrast = 0.3,
variables: Record<string, string | number> = {}
) {
const color = await sourceColorFromImage(image)
return vuetifyThemeFromColor(color, dark)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment