htmlcanvas前段时间干好需要做一个流水线实时更新缩略图
实现效果(菜鸟一枚,如果更好的实现方法还请指出,多谢)
首先准备dom截图的插件
使用的是html2canvas插件
// 安装 引入html2canvas
npm install html2canvas
项目文件引入 html2canvas
import html2canvas from 'html2canvas'
html部分
<div
ref="mainDom">
<div
ref="imageDom"
>
<pipeline-stage /> <!-- 流水线通用组件 -->
</div>
</div>
// 浮窗
<div class="absolute thumbnail">
<div
v-if="showThumbnail"
ref="choose"
class="imagedom"
>
<div
ref="content"
class="relative"
@mousemove="handleMove"
>
<img
:src="imgUrl"
>
<div
ref="shadow"
class="shadow absolute"
/>
</div>
</div>
<div
class="absolute"
:title="showThumbnail ? '点击关闭' : '点击展开'"
>
<i
class="fa fs18"
:class="showThumbnail ? 'fa-eye' : 'fa-eye-slash'"
@click="setShowThumbnail"
/>
</div>
</div>
JS部分通过在页面加载完成后异步生成div图片
watch监听流水线数据,发生变化则触发 loadThumbnail()
methods: {
loadThumbnail () {
let timeer = setTimeout(() => {
if (document.readyState === 'complete') { // 判断页面是否加载完成
this.clickGeneratePicture()
}
}, 500) // 清除定时器
this.$once('hook:beforeDestroy', () => {
clearTimeout(timeer)
})
},
/**
* 将页面指定节点内容转为图片
* 1.拿到想要转换为图片的内容节点DOM;
* 2.转换,拿到转换后的canvas
* 3.转换为图片
*/
async clickGeneratePicture () {if (this.timeout) { // 规定时间内只执行一次,防止页面过于卡顿
return
}
this.timeout = true
html2canvas(this.$refs.imageDom, {
allowTaint: true, // 否允许跨源图像污染画布
width: this.$refs.imageDom.clientWidth, // dom 原始宽度
height: this.$refs.imageDom.clientHeight, // dom 原始高度
backgroundColor: '#f1f1f1', // DOM背景色
scrollY: 0, // 解决DOM截图不完整的问题
scrollX: 0, // 解决DOM截图不完整的问题
useCORS: true, // 解决单截图范围内有图片时的跨域问题
dpi: 182 // 导出图片清晰度,太高会导致图片无法加载
}).then(canvas => { // 转成图片,生成图片地址
this.imgUrl = canvas.toDataURL('image/webp', 1) // 显示缩略图
this.showThumbnail = this.isShowThumbnail()
})
// 规定时间内只执行一次,防止页面过于卡顿
let timeer = setTimeout(() => {
this.timeout = false
}, 1000)
this.$once('hook:beforeDestroy', () => { // 清除定时器
clearTimeout(timeer)
})
},
// 获取元素到文档区域的坐标
getPosition (element) {
let dc = document
let rec = element.getBoundingClientRect()
let x = rec.left // 获取元素相对浏览器视窗window的左、上坐标
let y = rec.top // 与html或body元素的滚动距离相加就是元素相对于文档区域document的坐标位置
x += dc.documentElement.scrollLeft || dc.body.scrollLeft
y += dc.documentElement.scrollTop || dc.body.scrollTop
return {
left: x,
top: y
}
},
handleMove (evt) {
let shadow = this.$refs.shadow
let imagedom = this.$refs.imageDom.getBoundingClientRect()
if (this.isShowThumbnail()) { // 判断是否需要展示缩略图
let pos = this.getPosition(this.$refs.choose)
let shadowRect = shadow.getBoundingClientRect()
let contentRect = this.$refs.content.getBoundingClientRect()
let maxY = contentRect.height - shadowRect.height
let Y = evt.pageY - pos.top - shadowRect.height / 2
// 防止遮罩层粘滞,跟随鼠标一起滑出大图位置
if (Y <= 0) {
Y = 0
}
if (Y >= maxY) {
Y = maxY
}
let magnification = accurateDivide(imagedom.height, shadowRect.height)
shadow.style.top = Y + 'px'
this.$refs.mainDom.scrollTo(0, accurateTimes(Y, magnification))
} else {
shadow.style.display = 'none'
}
}
}
5、html2canvas官网地址