<!-- 艺术字组件,实现描边和阴影 -->
<script setup lang="ts">
import { computed } from 'vue'
interface IProps {
strokeColor?: string
strokeGradient?: string
strokeWidth?: number | string
showStroke?: boolean
color?: string
gradient?: string
shadowColor?: string
shadowGradient?: string
shadowX?: number | string
shadowY?: number | string
}
const props = withDefaults(defineProps<IProps>(), {
showStroke: true,
shadowX: 0,
shadowY: 0,
})
const formatPxToVw = px => {
return typeof px === 'number' ? `${px / 7.5}vw` : px
}
const computedStrokeWidth = computed(() => formatPxToVw(props.strokeWidth))
const computedShadowX = computed(() => formatPxToVw(props.shadowX))
const computedShadowY = computed(() => formatPxToVw(props.shadowY))
const strokeColorStyle = computed(() => {
if (props.strokeGradient) {
return {
'background-image': props.strokeGradient,
'-webkit-text-fill-color': 'transparent',
'-webkit-text-stroke': `transparent ${computedStrokeWidth.value}`,
}
}
return {
color: props.strokeColor,
'-webkit-text-stroke': `${props.strokeColor} ${computedStrokeWidth.value}`,
}
})
const colorStyle = computed(() => {
if (props.gradient) {
return {
'background-image': props.gradient,
'-webkit-text-fill-color': 'transparent',
}
}
if (props.color) {
return {
color: props.color,
}
}
return {}
})
const shadowColorStyle = computed(() => {
if (props.shadowGradient) {
return {
'background-image': props.shadowGradient,
'-webkit-text-fill-color': 'transparent',
'-webkit-text-stroke': `transparent ${computedStrokeWidth.value}`,
}
}
return {
color: props.shadowColor,
'-webkit-text-stroke': `${props.shadowColor} ${computedStrokeWidth.value}`,
}
})
</script>
<template>
<div class="word-art">
<div
v-if="showStroke"
class="text-shadow"
:style="{
...shadowColorStyle,
top: computedShadowY,
left: computedShadowX,
}"
>
<slot></slot>
</div>
<div
v-if="showStroke"
class="text-stroke"
:style="{
...strokeColorStyle,
}"
>
<slot></slot>
</div>
<div class="text-draw" :style="{ ...colorStyle }">
<slot></slot>
</div>
</div>
</template>
<style lang="less" scoped>
.word-art {
position: relative;
}
.text-shadow {
stroke-linecap: butt;
stroke-linejoin: round;
position: absolute;
left: 0;
right: 0;
background-clip: text;
-webkit-background-clip: text;
background-size: 100% 100%;
}
.text-stroke {
stroke-linecap: butt;
stroke-linejoin: round;
position: absolute;
left: 0;
right: 0;
background-clip: text;
-webkit-background-clip: text;
background-size: 100% 100%;
}
.text-draw {
position: relative;
background-clip: text;
-webkit-background-clip: text;
background-size: 100% 100%;
}
</style>
11-10
3290
05-08
228
09-12
1052