Custom Styles
Custom Colors
To better observe the changes in fill color, the font size has been increased.
Custom Colors
你还可以将下列属性作为文本颜色:
Click to view code
html
<div class="text-center">
<timered-counter-number id="colorful-number-counter" class="!text-8xl font-bold" />
</div>
<hr />
<div class="flex gap-4">
<input class="border border-solid p-1" v-model="number" type="number" />
<button class="border border-solid px-2 py-1" @click="switchNumber">🔄</button>
<span class="flex-auto" />
<input class="border border-solid p-1" v-model="color" type="color" />
</div>
<div class="flex flex-col mt-4">
<div>你还可以将下列属性作为文本颜色:</div>
<ol>
<li>
<label>
<input
type="radio"
name="color"
value="linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet)"
v-model="color"
/>
CSS 渐变属性
</label>
</li>
<li>
<label>
<input
type="radio"
name="color"
value="url('https://picsum.photos/400/300')"
v-model="color"
/>
CSS 图片属性(加载图片时会有一段空白时间)
</label>
</li>
<li>
<label>
<input
type="radio"
name="color"
value="linear-gradient(rgba(255, 0, 0, 0.4), rgba(0, 0, 255, 0.4)), url('https://picsum.photos/400/300')"
v-model="color"
/>
CSS 渐变属性 + 图片属性
</label>
</li>
</ol>
</div>
js
import { onMounted, ref, watch } from "vue";
const number = ref(114514);
function switchNumber() {
number.value = Math.floor(Math.random() * 1000000);
}
const color = ref(
"#" +
Math.floor(Math.random() * 16777215)
.toString(16)
.padStart(6, "0")
);
onMounted(() => watch([number, color], update, { immediate: true }));
function update() {
const _number = number.value;
const _color = color.value;
const counter = document.getElementById('colorful-number-counter');
counter.value = _number;
counter.color = _color;
}
vue
<script setup>
// #region js
import { onMounted, ref, watch } from "vue";
const number = ref(114514);
function switchNumber() {
number.value = Math.floor(Math.random() * 1000000);
}
const color = ref(
"#" +
Math.floor(Math.random() * 16777215)
.toString(16)
.padStart(6, "0")
);
onMounted(() => watch([number, color], update, { immediate: true }));
function update() {
const _number = number.value;
const _color = color.value;
const counter = document.getElementById('colorful-number-counter');
counter.value = _number;
counter.color = _color;
}
// #endregion js
</script>
<template>
<!-- #region html -->
<div class="text-center">
<timered-counter-number id="colorful-number-counter" class="!text-8xl font-bold" />
</div>
<hr />
<div class="flex gap-4">
<input class="border border-solid p-1" v-model="number" type="number" />
<button class="border border-solid px-2 py-1" @click="switchNumber">🔄</button>
<span class="flex-auto" />
<input class="border border-solid p-1" v-model="color" type="color" />
</div>
<div class="flex flex-col mt-4">
<div>你还可以将下列属性作为文本颜色:</div>
<ol>
<li>
<label>
<input
type="radio"
name="color"
value="linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet)"
v-model="color"
/>
CSS 渐变属性
</label>
</li>
<li>
<label>
<input
type="radio"
name="color"
value="url('https://picsum.photos/400/300')"
v-model="color"
/>
CSS 图片属性(加载图片时会有一段空白时间)
</label>
</li>
<li>
<label>
<input
type="radio"
name="color"
value="linear-gradient(rgba(255, 0, 0, 0.4), rgba(0, 0, 255, 0.4)), url('https://picsum.photos/400/300')"
v-model="color"
/>
CSS 渐变属性 + 图片属性
</label>
</li>
</ol>
</div>
<!-- #endregion html -->
</template>
<style scoped></style>
Custom Fonts
You can directly customize various font properties by setting CSS properties.
Custom Fonts
Click to view code
html
<div class="text-center">
<timered-counter-number id="playful-number-counter" style="line-height: 1.2"/>
</div>
<hr />
<div class="flex gap-4">
<input class="border border-solid p-1" v-model="number" type="number" />
<button class="border border-solid px-2 py-1" @click="switchNumber">🔄</button>
<span class="flex-auto" />
<input class="border border-solid p-1" v-model="color" type="color" />
</div>
<div class="flex gap-4 mt-4">
<label class="inline-flex gap-1 border border-solid p-1">
斜体
<input v-model="italic" type="checkbox" />
</label>
<label class="inline-flex gap-1 border border-solid p-1">
字号
<input v-model="fontSize" type="range" min="1" max="128" />
{{ fontSize }}px
</label>
</div>
<div class="flex gap-4 mt-4">
<google-font-picker v-model="fontFamily" />
</div>
js
import { onMounted, ref, watch } from "vue";
import GoogleFontPicker from "./GoogleFontPicker.vue";
const number = ref(114514);
function switchNumber() {
number.value = Math.floor(Math.random() * 1000000);
}
const italic = ref(false);
const fontSize = ref(64);
const color = ref(
"#" +
Math.floor(Math.random() * 16777215)
.toString(16)
.padStart(6, "0")
);
const fontFamily = ref("");
onMounted(() => watch([number, italic, fontSize, fontFamily, color], update, { immediate: true }));
function update() {
const _number = number.value;
const _italic = italic.value;
const _fontSize = fontSize.value;
const _fontFamily = fontFamily.value;
const _color = color.value;
const counter = document.getElementById('playful-number-counter');
counter.value = _number;
counter.color = _color;
counter.style.fontSize = _fontSize + 'px';
counter.style.fontStyle = _italic ? 'italic' : 'normal';
counter.style.fontFamily = _fontFamily;
}
vue
<script setup>
// #region js
import { onMounted, ref, watch } from "vue";
import GoogleFontPicker from "./GoogleFontPicker.vue";
const number = ref(114514);
function switchNumber() {
number.value = Math.floor(Math.random() * 1000000);
}
const italic = ref(false);
const fontSize = ref(64);
const color = ref(
"#" +
Math.floor(Math.random() * 16777215)
.toString(16)
.padStart(6, "0")
);
const fontFamily = ref("");
onMounted(() => watch([number, italic, fontSize, fontFamily, color], update, { immediate: true }));
function update() {
const _number = number.value;
const _italic = italic.value;
const _fontSize = fontSize.value;
const _fontFamily = fontFamily.value;
const _color = color.value;
const counter = document.getElementById('playful-number-counter');
counter.value = _number;
counter.color = _color;
counter.style.fontSize = _fontSize + 'px';
counter.style.fontStyle = _italic ? 'italic' : 'normal';
counter.style.fontFamily = _fontFamily;
}
// #endregion js
</script>
<template>
<!-- #region html -->
<div class="text-center">
<timered-counter-number id="playful-number-counter" style="line-height: 1.2"/>
</div>
<hr />
<div class="flex gap-4">
<input class="border border-solid p-1" v-model="number" type="number" />
<button class="border border-solid px-2 py-1" @click="switchNumber">🔄</button>
<span class="flex-auto" />
<input class="border border-solid p-1" v-model="color" type="color" />
</div>
<div class="flex gap-4 mt-4">
<label class="inline-flex gap-1 border border-solid p-1">
斜体
<input v-model="italic" type="checkbox" />
</label>
<label class="inline-flex gap-1 border border-solid p-1">
字号
<input v-model="fontSize" type="range" min="1" max="128" />
{{ fontSize }}px
</label>
</div>
<div class="flex gap-4 mt-4">
<google-font-picker v-model="fontFamily" />
</div>
<!-- #endregion html -->
</template>
<style scoped></style>
vue
<script setup>
import { ref, onMounted, watch, computed } from "vue";
const fonts = ref([]);
const searchQuery = ref("");
const selectedFont = defineModel("modelValue");
const fetchFonts = async () => {
try {
const response = await fetch(
"https://www.googleapis.com/webfonts/v1/webfonts?" +
new URLSearchParams({
key: "AIzaSyBJPgjEPn1iDes5wLzDF-JMEst6QdR4skU",
capability: "WOFF2",
sort: "popularity",
}).toString()
); // Replace with your Google Fonts API key
const data = await response.json();
fonts.value = data.items;
} catch (error) {
console.error("Error fetching fonts:", error);
}
};
const filteredFonts = computed(() => {
if (!searchQuery.value) {
return fonts.value;
}
return fonts.value.filter((font) =>
font.family.toLowerCase().includes(searchQuery.value.toLowerCase())
);
});
const loadFont = (fontName) => {
const link = document.createElement("link");
link.href = `https://fonts.googleapis.com/css2?family=${fontName.replace(/ /g, "+")}&display=swap`;
link.rel = "stylesheet";
document.head.appendChild(link);
};
watch(selectedFont, (newFont) => {
if (newFont) {
loadFont(newFont);
}
});
onMounted(async () => {
await fetchFonts();
selectedFont.value = "Ingrid Darling";
// await nextTick();
// document
// .querySelector(`#${selectedFont.value.replaceAll(" ", "-")}`)
// ?.scrollIntoView();
});
// 自动加载选择框中可见字体的预览menu字体
watch(
filteredFonts,
(newFonts) => {
newFonts.forEach((font) => {
const previewFamily = joinPreviewFamily(font.family);
const fontFace = new FontFace(previewFamily, `url(${font.menu})`, {
display: "swap",
});
document.fonts.add(fontFace);
});
},
{ immediate: true }
);
function joinPreviewFamily(family) {
return [...family.split(" "), "PREVIEW"].join("-");
}
</script>
<template>
<div class="flex-none flex flex-col">
<input
type="text"
v-model="searchQuery"
placeholder="Search for fonts"
class="w-full border border-solid p-1 self-start"
/>
<a
href="https://developers.google.com/fonts"
target="_blank"
class="mt-1 text-xs"
>
Data provided by Google Fonts API
</a>
</div>
<div
class="flex-auto font-list-container border border-solid p-1 overflow-y-scroll h-64"
>
<div
v-for="font in filteredFonts"
:key="font.family"
:id="font.family.replace(' ', '-')"
:style="{ fontFamily: joinPreviewFamily(font.family) }"
class="font-item p-2 cursor-pointer"
:class="{
'bg-gray-200': selectedFont === font.family,
}"
@click="selectedFont = font.family"
>
{{ font.family }}
</div>
</div>
</template>
<style scoped>
.font-list-container {
max-height: 16rem;
}
.font-item:hover {
background-color: #f0f0f0;
}
</style>