前言:家人们,大家好!今天分享一篇文章给大家!要是文章对你有帮助,激发了你的灵感,
求个收藏 + 关注啦~后续还有超多惊喜,别错过!
引言
在前端开发过程中,我们常常会遇到需要将网页内容导出为图片的需求,比如生成海报、保存页面快照等。今天,我们就来探讨如何借助 html2canvas
和 file-saver
这两个强大的工具,在 Vue 项目里实现图片文案的快速导出功能。
项目需求与目标
我们的目标是创建一个简单的工具,它允许用户选择颜色来定制文案的背景色,同时提供一个按钮,点击后能将特定区域的文案内容导出为带有水印的图片。
项目实现步骤
1. 项目准备
首先,我们需要创建一个 Vue 项目,并安装所需的依赖:
npm install html2canvas file-saver element-ui
这里我们使用了 html2canvas
来将 HTML 元素转换为 Canvas,file-saver
用于保存生成的图片,element-ui
则提供了一些美观的 UI 组件,如按钮和颜色选择器。
2. 编写组件代码
以下是完整的组件代码:
<template>
<div style="padding: 20px">
<div class="flex">
<el-button type="primary" @click="exportImage">保存图片</el-button>
<div class="flex_item">
<span class="demonstration">选择颜色</span>
<el-color-picker v-model="color" @change="activeChange" />
</div>
</div>
<div id="export-container">
<div class="image-content">
<div class="title_bg" :style="{ backgroundColor: color }">
<div>{{ title }}场景提示词</div>
</div>
<ul>
<li v-for="(item, index) in textList" :key="index" class="list_item" :style="{ backgroundColor: hexToRgba(color, 0.1) }">
<div class="name_item">
{{ index + 1 + ' . ' + item.name }}
</div>
<div class="content_item">
{{ item.content }}
</div>
<div class="case_item">
{{ item.case }}
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
import html2canvas from 'html2canvas';
import { saveAs } from 'file-saver';
export default {
data() {
return {
title: '进阶技巧',
textList: [
{
name: '角色扮演指令',
content: '你是一名有20年经验的刑侦法医,用专业术语分析以下现场描述,指出3处异常痕迹:[案件描述]',
case: '(适用:专业场景模拟)',
},
{
name: '多步推理指令',
content: '已知:A>B, B>C, C≠D, D<E。请逐步推导A与E的关系,并用韦恩图解释推导过程',
case: '(适用:逻辑训练)',
},
{
name: '创意生成限制',
content: '列举10种从未被发明过的厨房小工具,每个创意需满足:成本低于$5、无需用电、解决实际痛点',
case: '(适用:产品设计)',
},
{
name: '跨学科联想',
content: '将唐诗《春晓》的意境转化为现代电子音乐创作元素,描述旋律特征、音色选择和节奏设计思路',
case: '(适用:艺术创作)',
},
],
color: '#409eff',
exportContainer: null,
};
},
created() {
this.color = localStorage.getItem('color');
this.exportContainer = document.querySelector('#export - container');
},
methods: {
activeChange(e) {
console.log(e, 'dsdad');
localStorage.setItem('color', e);
this.color = e;
},
async exportImage() {
try {
const canvas = await html2canvas(this.exportContainer, {
width: 520,
height: 700,
scale: 15,
});
this.addWatermark(canvas);
canvas.toBlob((blob) => {
saveAs(blob, 'AI文案.png');
}, 'image/png');
} catch (error) {
console.error('导出图片失败', error);
alert('导出图片失败,请稍后重试。');
}
},
addWatermark(canvas) {
const ctx = canvas.getContext('2d');
const watermarkText = '码上前端';
const font = '30px';
const color1 = 'rgba(255, 255, 255, 0.5)';
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
const x = canvasWidth - ctx.measureText(watermarkText).width - 10;
const y = canvasHeight - 30;
ctx.save();
ctx.rotate((-45 * Math.PI) / 180);
ctx.font = font;
ctx.fillStyle = color1;
ctx.fillText(watermarkText, x, y);
ctx.restore();
},
hexToRgba(hex, alpha) {
if (!hex || typeof hex!== 'string') {
return 'rgba(0, 0, 0, 0)';
}
hex = hex.replace(/^#/, '');
if (hex.length === 3) {
hex = hex
.split('')
.map((char) => char + char)
.join('');
}
const bigint = parseInt(hex, 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
},
},
};
</script>
<style scoped lang="scss">
.flex {
display: flex;
align-items: center;
margin-bottom: 20px;
.flex_item {
margin-left: 20px;
color: blue;
display: flex;
gap: 10px;
align-items: center;
}
}
#export - container {
width: 520px;
height: 700px;
box-sizing: border-box;
padding: 25px 2px 0 2px;
// background - color: rgb(244, 211, 162);
}
.image - content {
width: 100%;
.title_bg {
border - radius: 25px;
text - align: center;
padding: 30px;
font - size: 35px;
font - weight: 400;
color: #fff;
background - color: #409eff;
}
}
ul {
list - style - type: none;
padding: 10px;
.list_item {
margin - bottom: 10px;
border - radius: 25px;
line - height: 25px;
padding: 15px 5px 10px 5px;
background - color: #becede;
.name_item {
font - size: 18px;
font - weight: 600;
}
.content_item {
font - size: 14px;
}
}
}
</style>
3. 代码详细解释
模板部分
- 我们使用了
element - ui
的按钮和颜色选择器。按钮点击触发exportImage
方法,颜色选择器绑定color
变量,颜色改变时触发activeChange
方法。 #export-container
是要导出为图片的区域,包含标题和文案列表。
脚本部分
- 数据部分:定义了文案标题、文案列表、颜色变量和要导出的容器元素。
created
钩子:从localStorage
中获取之前保存的颜色,并缓存要导出的容器元素,避免后续重复查询 DOM。activeChange
方法:当用户选择颜色时,将新颜色保存到localStorage
并更新color
变量。exportImage
方法:- 使用
html2canvas
将#export-container
转换为 Canvas。 - 调用
addWatermark
方法添加水印。 - 将带有水印的 Canvas 转换为 Blob 对象,并使用
file-saver
保存为AI文案.png
。 - 若导出过程中出现错误,会在控制台打印错误信息并弹出提示框告知用户。
- 使用
addWatermark
方法:在 Canvas 上添加旋转 45 度的半透明水印文字。hexToRgba
方法:将十六进制颜色代码转换为 RGBA 格式,方便设置透明度。
样式部分
使用 SCSS 编写样式,设置了布局、背景色、字体大小等样式,使界面更加美观。
结语
通过 html2canvas
和 file-saver
,我们可以在 Vue 项目中轻松实现图片文案的快速导出功能。结合 element-ui
提供的组件,还能打造出美观易用的界面。在实际开发中,我们要注意性能优化、代码结构优化和兼容性处理,以提供更好的用户体验。希望本文能帮助你在 Vue 项目中实现类似的功能。如果你在实践过程中遇到问题或有更好的建议,欢迎在评论区留言分享!
到这里,这篇文章就和大家说再见啦!我的过往文章里还藏着许多干货,感兴趣的话也可以点击我的主页看看,下面的文章也很精彩,可别错过。创作这篇内容花费了不少心血,要是它帮你解决了问题,或者带来了启发,就多多支持下 “码上前端” 吧~要是想转载,麻烦一定注明本文链接,感谢大家! 💕