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