vue.js3:用html2canvas把html转canvas图片(html2canvas@1.4.1 / vue@3.2.37)
一,安装html2canvas
1,官网:
https://html2canvas.hertzen.com/
如图:
代码站:
https://github.com/niklasvh/html2canvas
2,通过npm安装
liuhongdi@lhdpc:/data/vue/touch$ npm install --save html2canvas added 5 packages in 4s
3,查看已安装的html2canvas库的版本
liuhongdi@lhdpc:/data/vue/touch$ npm list html2canvas touch@0.1.0 /data/vue/touch └── html2canvas@1.4.1
说明:刘宏缔的架构森林是一个专注架构的博客,
网站:https://blog.imgtouch.com
原文: https://blog.imgtouch.com/index.php/2023/06/03/vue-js3-yong-html2canvas-ba-html-zhuan-canvas-tu-pian/
对应的源码可以访问这里获取: https://github.com/liuhongdi/
或: https://gitee.com/liuhongdi
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,js代码:
<template> <div> <div style="width:800px;margin: auto;display: flex;flex-direction: column;"> <div>请选择上传图片: <input type="file" id="back" ref="backfile" accept="image/*" @change="handleFile" /></div> <div id="imgContainer" style="position: relative;margin-left:150px;margin-top:10px;width:500px;height:500px;overflow: hidden;background: lightgray;" > <div id="imgDiv"> <img id="img" :src="imgSrc" style="" /> <div id="text" :style="{ width:'600px', height:'200px', position: 'absolute', left:'50px', top:'50px', width: '300px', height: 'auto', fontSize:fontSizeValue+'px', color:colorValue, fontStyle:styleValue, fontWeight:weightValue, opacity:opacityValue, textAlign:alignValue }">这是一个可编辑的信息,测试思源的字体文件</div> </div> </div> <div> 字号: <el-input-number v-model="fontSizeValue" class="mx-4" :min="10" :max="100" controls-position="right" @change="fontSizeChange" /><br/> 颜色:<el-color-picker v-model="colorValue" @active-change="setColor" /><br/> <span>透明度:</span><el-slider v-model="opacityDispValue" :min="0" :max="100" @input="setOpacity" style="width:300px;" /><br/> <button @click="weight">加粗</button> <button @click="style">斜体</button> </div> <div id="dpiBtn" style="display: none;"> <input type="button" value="保存图片" @click="makeCanvas" /> </div> </div> </div> </template> <script> import {ref} from "vue"; import html2canvas from "html2canvas" export default { name: "ImageText", setup() { //图片的原宽高 const imgWidth = ref(0); const imgHeight = ref(0); //图片内容 const imgSrc = ref(""); //选中的图片文件 const imgFile = ref(); //选中图片后的处理 const handleFile = () => { let filePaths = window.event.target.files; //清空原有缩略图 if (filePaths.length === 0) { //未选择,则返回 return } //把新选中的图片加入数组 imgFile.value = filePaths[0]; imgSrc.value = URL.createObjectURL(imgFile.value); let reader = new FileReader(); reader.readAsDataURL(imgFile.value); reader.onload = () =>{ //显示图片 imgSrc.value = reader.result; //得到宽高 let img = new Image(); img.src= reader.result; img.onload = () => { //保存宽高 imgWidth.value = img.width; imgHeight.value = img.height; if (img.width >= img.height) { let rate = 500 / img.width; let left = (500-img.width) / 2; let top = (500 -img.height) / 2; let styleStr = 'display:block;width:100%;height:100%;'; document.getElementById('img').style = styleStr; let styleDivStr = 'position:absolute;width:'+img.width+'px;height:'+img.height+'px;transform:scale('+rate+');left:'+left+'px;display: block;top:'+top+'px;'; document.getElementById('imgDiv').style = styleDivStr; } else { let rate = 500 / img.height; let left = (500-img.width) / 2; let top = (500 -img.height) / 2; let styleStr = 'display: inline-block;width:100%;height:100%;'; document.getElementById('img').style = styleStr; let styleDivStr = 'position:absolute;width:'+img.width+'px;height:'+img.height+'px;transform:scale('+rate+');left:'+left+'px;display: block;top:'+top+'px;'; document.getElementById('imgDiv').style = styleDivStr; } document.getElementById('dpiBtn').style.display=""; } } } //对齐 const alignValue = ref("left"); //倾斜 const styleValue = ref("normal"); const style = () => { if (styleValue.value == 'normal') { styleValue.value ='italic' } else { styleValue.value ='normal' } } //加粗 const weightValue = ref("normal"); const weight = () => { if (weightValue.value == 'normal') { weightValue.value ='bold' } else { weightValue.value ='normal' } } //透明度 const opacityValue = ref(1); const opacityDispValue = ref(100); const setOpacity = (value) => { opacityValue.value = value / 100; } //颜色 const colorValue = ref("#2c3e50"); const setColor = (value) => { colorValue.value = value; } //字号 const fontSizeValue = ref(38); const fontSizeChange = (value) =>{ fontSizeValue.value = value; } //把编辑的文字部分保存成图片 const makeCanvas = () => { html2canvas(document.getElementById('text'),{ onclone: function(documentClone){ documentClone.getElementById('imgDiv').style.transform = 'scale(1)'; } }).then(function(canvas){ downPngByCanvas(canvas); }); } //下载图片 const downPngByCanvas = (canvas) => { var oA = document.createElement("a"); let time = timeFormat(); oA.download = "img_"+time+'.png';// 设置下载的文件名,默认是'下载' oA.href = canvas.toDataURL("image/png").replace('image/png', 'image/octet-stream'); document.body.appendChild(oA); oA.click(); oA.remove(); // 下载之后把创建的元素删除 } //补0 const add0 = (m) => { return m<10?'0'+m:m } //格式化时间 const timeFormat = ()=>{ var time = new Date(); var y = time.getFullYear(); var m = time.getMonth()+1; var d = time.getDate(); var h = time.getHours(); var mm = time.getMinutes(); var s = time.getSeconds(); let res = y+add0(m)+add0(d)+add0(h)+add0(mm)+add0(s); return res; } return { imgSrc, handleFile, alignValue, style, styleValue, weight, weightValue, opacityValue, opacityDispValue, setOpacity, colorValue, setColor, fontSizeValue, fontSizeChange, makeCanvas, } } } </script> <style scoped> </style>
三,测试效果:
转canvas后:
四,查看vue框架的版本:
root@lhdpc:/data/vue/imgtouch# npm list vue imgtouch@0.1.0 /data/vue/imgtouch ├─┬ @vue/cli-plugin-babel@5.0.6 │ └─┬ @vue/babel-preset-app@5.0.6 │ └── vue@3.2.37 deduped └─┬ vue@3.2.37 └─┬ @vue/server-renderer@3.2.37 └── vue@3.2.37 deduped