vue3实现svg文本特效样式编辑风格选择生成svg和css代码
代码语言:html
所属分类:布局界面
代码描述:vue3实现svg文本特效样式编辑风格选择生成svg和css代码,输入文本,选择文本特效样式,就能预览效果,还能复制效果的css及svg代码,直接粘贴到html中就能用。
代码标签: vue svg 文本 特效 样式 编辑 风格 选择 生成 svg css 代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SVG 文字特效编辑器</title>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/vue3.2.22.js"></script>
<style>
:root {
--bg-color: #1a1a1a;
--panel-bg: #242424;
--text-color: #f0f0f0;
--primary-color: #42b883;
--border-color: #333;
--input-bg: #333;
--shadow-color: rgba(0, 0, 0, 0.5);
}
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
overflow: hidden;
}
body {
font-family: 'Poppins', sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
}
#app {
display: grid;
grid-template-columns: 320px 1fr;
width: 100vw;
height: 100vh;
gap: 1px;
background-color: var(--border-color);
}
.control-panel {
background-color: var(--panel-bg);
padding: 24px;
display: flex;
flex-direction: column;
gap: 20px;
}
.control-panel h1 {
font-size: 24px;
color: var(--primary-color);
text-align: center;
margin-bottom: 10px;
font-weight: 700;
}
.input-group label {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
color: #aaa;
}
.input-group input {
width: 100%;
padding: 10px;
background-color: var(--input-bg);
border: 1px solid var(--border-color);
border-radius: 6px;
color: var(--text-color);
font-size: 16px;
}
.input-group input:focus {
outline: none;
border-color: var(--primary-color);
}
.effects-list {
flex-grow: 1;
overflow-y: auto;
padding-right: 10px;
height: 100vh;
}
.effects-list::-webkit-scrollbar {
width: 6px;
}
.effects-list::-webkit-scrollbar-thumb {
background: var(--primary-color);
border-radius: 3px;
}
.effect-item {
padding: 12px;
margin-bottom: 6px;
border-radius: 6px;
cursor: pointer;
font-weight: 600;
}
.effect-item:hover {
background-color: var(--input-bg);
}
.effect-item.active {
background-color: var(--primary-color);
color: var(--bg-color);
font-weight: 700;
}
.preview-area {
background-color: var(--bg-color);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 40px;
position: relative;
overflow: hidden;
}
.preview-content {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.preview-content svg {
width: 90%;
max-height: 90%;
overflow: visible;
}
.copy-button {
position: absolute;
bottom: 30px;
right: 30px;
padding: 12px 24px;
background-color: var(--primary-color);
color: var(--bg-color);
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 700;
cursor: pointer;
box-shadow: 0 4px 15px var(--shadow-color);
}
.copy-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px var(--shadow-color);
}
.copy-button.copied {
background-color: #28a745;
}
</style>
</head>
<body>
<div id="app">
<div class="control-panel">
<h1>SVG 文字特效编辑器</h1>
<div class="input-group">
<label for="text-input">编辑文本</label>
<input id="text-input" type="text" v-model="text" />
</div>
<div class="input-group">
<label>选择特效</label>
</div>
<div class="effects-list">
<div
v-for="effect in effects"
:key="effect.id"
class="effect-item"
:class="{ active: selectedEffect && selectedEffect.id === effect.id }"
@click="selectEffect(effect)"
>
{{ effect.name }}
</div>
</div>
</div>
<div class="preview-area">
<div class="preview-content">
<div v-if="selectedEffect" v-html="previewHtml"></div>
</div>
<button class="copy-button" :class="{ copied }" @click="copyCode">
{{ copyButtonText }}
</button>
</div>
</div>
<script>
const { createApp, ref, computed, onMounted, watchEffect } = Vue;
createApp({
setup() {
const text = ref("Hello SVG");
const effects = ref([]);
const selectedEffect = ref(null);
const copied = ref(false);
const previewHtml = computed(() => {
if (!selectedEffect.value) return "";
return selectedEffect.value.svg(text.value);
});
const copyButtonText = computed(() =>
copied.value ? "已复制!" : "复制代码"
);
const codeToCopy = computed(() => {
if (!selectedEffect.value) return "";
const { name, svg, css } = selectedEffect.value;
const svgContent = svg(text.value);
const cssContent = typeof css === "function" ? css(text.value) : css;
return `<!-- ${name} 特效代码 -->\n${svgContent.trim()}\n<style>\n${cssContent.trim()}\n</style>`;
});
const selectEffect = (effect) => {
selectedEffect.value = effect;
};
const copyCode = async () => {
if (!navigator.clipboard) {
alert("浏览器不支持 Clipboard API");
return;
}
try {
await navigator.clipboard.writeText(codeToCopy.value);
copied.value = true;
setTimeout(() => (copied.value = false), 2000);
} catch (err) {
alert("复制失败!");
}
};
onMounted(() => {
// 示例:只放一个特效,更多可继续加
effects.value = [
{
id: 'gradient-fill',
name: '多彩渐变填充',
svg: (txt) => `<svg viewBox="0 0 800 200"><defs><linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" /><stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" /></linearGradient></defs><text class="effect-text" x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">${txt}</text></svg>`,
css: `.effect-text { font-size: 100px; font-weight: bold; fill: url(#grad1); }`
},
{
id: 'neon-glow',
name: '霓虹灯光',
svg: (txt) => `<svg viewBox="0 0 800 200"><text class="effect-text" x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">${txt}</text></svg>`,
css: `.effect-text { font-size: 100px; font-weight: bold; fill: #fff; stroke: #f0f; stroke-width: 2px; text-shadow: 0 0 10px #f0f, 0 0 20px #f0f, 0 0 30px #f0f, 0 0 40px #f0f; }`
},
{
id: 'simple-stroke',
name: '简约描边',
svg: (txt) => `<svg viewBox="0 0 800 200"><text class="effect-text" x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">${txt}</text></svg>`,
css: `.effect-text { font-size: 120px; font-weight: 900; fill: none; stroke: #42b883; stroke-width: 2; }`
},
{
id: 'double-stroke',
name: '双层描边',
svg: (txt) => `<svg viewBox="0 0 800 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><symbol id="s-text"><text text-anchor="middle" x="50%" y=".........完整代码请登录后点击上方下载按钮下载查看
















网友评论0