html转canvas创建Marker
我们经常遇到撒点、建筑顶牌等功能,这个时候,就需要在三维场景中创建一些Marker来实现这个功能。在之前的项目中,需要实现Marker不穿墙的问题,这个可以采用canvas的方式来实现,但是呢,有的一些建筑顶牌不止是单纯的建筑名称,还需要有一些其他的数据展示,甚至有可能是表格,这个时候使用canvas去画出这样的页面,就有一些耗费时间了。那么如果使用一些工具把我们的vue组件转成canvas呢?这样就可以大大的加快速度。那么就需要引入一个新的库: html2canvas
。
html2canvas
:读取网页上的目标DOM节点的信息绘制成canvas,但需要注意的是,它不支持一些CSS3的属性,这个可以参考官方文档。
其实它的用法很简单:
<!-- html -->
<div id="capture" style="padding: 10px; background: #f5da55">
<h4 style="color: #000; ">Hello world!</h4>
</div>
// js
// 通过这个方法就可得到绘制的canvas
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
那么我们在项目中,如何在vue中使用它,来达到我们的目的呢?
-
首先,我们需要安装
html2canvas
,使用npm install --save html2canvas
或yarn add html2canvas
-
其次,我们需要一个vue组件,以下简单举例,接收一个参数
name
<template>
<div class="big_data">
<div class="name org">{{ name }}</div>
<img class="icon" src="/img/monitor/org-m.png" />
</div>
</template>
<script>
export default {
name: 'BigData',
props: {
name: {
type: String,
default: '',
},
},
};
</script>
<style lang="scss" scoped>
.big_data {
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
font-size: 24px;
width: 120px;
> img {
width: 100%;
height: 100%;
}
.icon {
width: 26px;
height: 16px;
margin-top: 12px;
}
.name {
min-width: 100%;
background-color: rgba(31, 33, 41, 0.4);
border-radius: 8px;
height: 50px;
line-height: 50px;
text-align: center;
&.org {
border: 1px solid rgba(244, 215, 104, 0.7);
}
&.red {
border: 1px solid rgba(217, 26, 26, 1);
}
}
}
</style>
- 接下来就是主要代码实现,需要引入
html2canvas
,import html2canvas from 'html2canvas'
,以下只写创建方法,具体逻辑根据需求变更。
/**
* @description: 绘制canvas
* @param {Object} container 目标DOM节点
* @param {Object} options html2canvas配置项
* @returns {Object} 绘制的canvas
*/
convertToCanvas(container, options = {}) {
// 传入节点原始宽高
const initWidth = container.offsetWidth;
const initHeight = container.offsetHeight;
const { width = initWidth, height = initHeight } = options;
// html2canvas配置项
const ops = {
// 背景色,不设置默认白色,设置null即透明色
backgroundColor: null,
width,
height,
useCORS: true,
allowTaint: false,
...options,
};
// 返回通过DOM绘制的canvas
return html2canvas(container, ops).then((canvas) => canvas);
}
/**
* @description: 创建marker
* @param {Object} parent 创建marker的父元素
*/
async creatMarkers(parent) {
// 需要传入组件的参数
const { SheBeiMingChen } = parent.userData;
// 创建div并append到body
const div = document.createElement('div');
document.body.append(div);
// BigData即为之前创建的vue组件
const Profile = Vue.extend(BigData);
const profile = new Profile({ propsData: { name: SheBeiMingChen } });
profile.$mount(div);
// 得到通过DOM绘制的canvas画布
const canvasData = await this.convertToCanvas(profile.$el);
// 创建marker
window.uino.app.create({
type: 'Marker',
name: 'bigData',
parent,
localPosition: [0, 5, 0],
size: 3,
canvas: canvasData,
position: parent.position,
pivot: [0.5, 1],
complete: () => {
// 删除DOM
profile.$el.remove();
},
});
}