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