Appearance
字体颜色随背景色变化
filter 滤镜
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
vue
<template>
<div v-for="color of colors" :style="{ backgroundColor: color, color }" class="box">
<span class="filter">文字文字</span>
</div>
</template>
<script setup>
const colors = [
'#775039',
'#8b7042',
'#fff799',
'#b1d5c8',
'#007175',
'#3271ae',
'#a6559d',
'#d5ebe1',
'#80a492',
'#422517'
]
</script>
<style lang="scss" scoped>
.box {
display: inline-block;
width: 50%;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 30px;
}
.filter {
filter: grayscale(1) contrast(999) invert(1);
}
</style>
mix-blend-mode 混合模式
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
文字文字
vue
<template>
<div v-for="color of colors" :style="{ backgroundColor: color }" class="box">
<span class="mix">文字文字</span>
</div>
<div class="box" style="background-image: linear-gradient(45deg, black 50%, transparent 0)">
<span class="mix">文字文字</span>
</div>
<div class="box" style="background-image: linear-gradient(45deg, red 50%, yellow 0)">
<span class="mix">文字文字</span>
</div>
</template>
<script setup>
const colors = [
'#775039',
'#8b7042',
'#fff799',
'#b1d5c8',
'#007175',
'#3271ae',
'#a6559d',
'#d5ebe1',
'#80a492',
'#422517'
]
</script>
<style lang="scss" scoped>
.box {
display: inline-block;
width: 50%;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 30px;
}
.mix {
color: #fff;
mix-blend-mode: difference;
}
</style>
canvas
文字文字
文字文字
文字文字
vue
<template>
<div v-for="img of images" :style="{ backgroundImage: `url(${img.src})`, color: img.color }" class="box">
<span class="filter">文字文字</span>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
const images = reactive([
{ src: 'https://tse3-mm.cn.bing.net/th/id/OIP-C.7KW5GT7NQ8yUGlBbCHEm0gHaNK?pid=ImgDet&rs=1', color: '#fff' },
{
src: 'https://s.cn.bing.net/th?id=OHR.Mohair_ZH-CN9435762268_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&qlt=50',
color: '#fff'
},
{
src: 'https://img.youpin.mi-img.com/ferriswheel/e4d49589_16c6_434b_992c_93e232edff2b.jpeg@base@tag=imgScale&F=webp&h=1320&q=90&w=1080',
color: '#fff'
}
])
onMounted(() => {
for (const img of images) {
getThemeColor(img)
}
})
function readBlob(blob) {
return new Promise((res, rej) => {
const reader = new FileReader()
reader.addEventListener('load', () => res(reader.result))
reader.addEventListener('error', () => rej(reader.result))
reader.readAsDataURL(blob)
})
}
function loadImg(src) {
return new Promise((res, rej) => {
const img = document.createElement('img')
img.addEventListener('load', () => res(img))
img.addEventListener('error', () => rej(img))
img.src = src
})
}
function getColor(img) {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = 10
canvas.height = 10
ctx.drawImage(img, 0, 0, 10, 10)
const { data } = ctx.getImageData(0, 0, 10, 10)
let r = 0,
g = 0,
b = 0
for (let i = 0; i < 400; i += 4) {
r += data[i]
g += data[i + 1]
b += data[i + 2]
}
return `rgb(${r / 100}, ${g / 100}, ${b / 100})`
}
function getThemeColor(row) {
fetch(row.src)
.then(res => res.blob())
.then(readBlob)
.then(loadImg)
.then(getColor)
.then(res => {
row.color = res
})
}
</script>
<style lang="scss" scoped>
.box {
padding: 8px;
font-size: 30px;
height: 200px;
background-clip: content-box;
background-size: cover;
background-position: center;
}
.filter {
filter: grayscale(1) contrast(999) invert(1);
}
</style>