vue+three.js三维建模并可下载为图片
环境搭建:
npm install three
需要用的页面引用:
import * as THREE from 'three'
效果图
完整源码:
<template>
<div>
<el-button type="primary" size="mini" style="margin-bottom: 10px;margin-top: 10px;" @click="saveImg()">下载为图片</el-button>
<div class="area">
<!-- Three.js主体展示 -->
<div id="container"></div>
</div>
</div>
</template>
<script>
import * as THREE from 'three'
export default {
name: "parentClass",
data() {
return {
camera: null,
scene: null,
renderer: null,
sphere:null,
cube:null,
data:{
batchId:"375TH",
list: [{
topList:[{"title":"盒子top1","color":"#FFFF3C"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#03C9D7"},{"title":"盒子top1","color":"#3296FA"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
{
topList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
bottomList:[{"title":"盒子top1","color":"#1A851A"},{"title":"盒子top1","color":"#FFFF3C"}],
},
],
}
};
},
methods: {
saveImg() {
let image = new Image();
this.renderer.render(this.scene, this.camera);//此处renderer为three.js里的渲染器,scene为场景 camera为相机
let imgData = this.renderer.domElement.toDataURL("image/jpeg");//这里可以选择png格式jpeg格式
let a = document.createElement("a");
a.href =imgData;
a.download ="imgage";
a.click();
},
init() {
if(this.data!=null){
let container = document.getElementById('container');
this.scene= new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(45, container.clientWidth/container.clientHeight, 0.1, 1000);
this.camera.position.x = 100;
this.camera.position.y = 60;
this.camera.position.z = 45;
this.camera.lookAt(this.scene.position);
this.renderer = new THREE.WebGLRenderer();
this.renderer.setClearColor(0x484848); //背景色
this.renderer.setSize(container.clientWidth, container.clientHeight); //场景大小
this.renderer.shadowMap.enabled = true; //启用阴影
let spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(40, 80, 40);
spotLight.castShadow = true;
this.scene.add(spotLight);
if(this.data.list!=null&&this.data.list.length>0){
let i=0;
this.data.list.forEach(it=>{
let j=0;
let z=0;
it.topList.forEach(ittop=>{
//设置字体
var spriteOrigin = this.makeTextSprite( ittop.title,
{
fontsize: 35,
backgroundColor: {r:72, g:72, b:72, a:0.1}/* 背景颜色 */
} );
spriteOrigin.center = new THREE.Vector2(0, 0);
this.scene.add( spriteOrigin );
spriteOrigin.position.set(-10,7-j, -115+i-j);
//画模型
let cubeGeometry2 = new THREE.BoxGeometry(5, 3, 10);
let cubeMaterial2 = new THREE.MeshLambertMaterial({color:ittop.color});
this.cube2 = new THREE.Mesh(cubeGeometry2, cubeMaterial2);
this.cube2.position.x = -18;
this.cube2.position.y = 10-j;
this.cube2.position.z = -125+i;
j+=4;
this.scene.add(this.cube2);
});
it.bottomList.forEach(itbottom=>{
//设置字体
var spriteOrigin = this.makeTextSprite( itbottom.title,
{
fontsize:30,
backgroundColor: {r:72, g:72, b:72, a:0.1}/* 背景颜色 */
} );
spriteOrigin.center = new THREE.Vector2(0, 0);
this.scene.add( spriteOrigin );
spriteOrigin.position.set(15.2,7-z, -120+i);
//设置模型
let cubeGeometry = new THREE.BoxGeometry(5, 3, 10);
let cubeMaterial = new THREE.MeshLambertMaterial({color: itbottom.color});
this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
this.cube.position.x = 10;
this.cube.position.y = 10-z;
this.cube.position.z = -125+i;
z+=4;
this.scene.add(this.cube);
container.appendChild(this.renderer.domElement);
this.renderer.render(this.scene, this.camera);
})
i+=18;
});
}
}
},
/* 创建字体精灵 */
makeTextSprite(message, parameters) {
if ( parameters === undefined ) parameters = {};
var fontface = parameters.hasOwnProperty("fontface") ?
parameters["fontface"] : "Arial";
/* 字体大小 */
var fontsize = parameters.hasOwnProperty("fontsize") ?
parameters["fontsize"] : 18;
/* 边框厚度 */
var borderThickness = parameters.hasOwnProperty("borderThickness") ?
parameters["borderThickness"] : 4;
/* 边框颜色 */
var borderColor = parameters.hasOwnProperty("borderColor") ?
parameters["borderColor"] : { r:72, g:72, b:72, a:0 };
/* 背景颜色 */
var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?
parameters["backgroundColor"] : { r:72, g:72, b:72, a:0.5};
/* 创建画布 */
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
/* 字体加粗 */
context.font = "Bold " + fontsize + "px " + fontface;
/* 获取文字的大小数据,高度取决于文字的大小 */
var metrics = context.measureText( message );
var textWidth = metrics.width;
console.log(message+":"+textWidth);
/* 背景颜色 */
context.fillStyle = "rgba(" + backgroundColor.r + "," + backgroundColor.g + ","
+ backgroundColor.b + "," + backgroundColor.a + ")";
/* 边框的颜色 */
context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + ","
+ borderColor.b + "," + borderColor.a + ")";
context.lineWidth = borderThickness;
/* 绘制圆角矩形 */
/* this.roundRect(context, borderThickness/2, borderThickness/2, textWidth + borderThickness, fontsize * 1.4 + borderThickness, 6);*/
/* 字体颜色 */
context.fillStyle = "rgba(255,255, 255, 1.0)";
context.fillText( message, borderThickness, fontsize + borderThickness);
/* 画布内容用于纹理贴图 */
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var spriteMaterial = new THREE.SpriteMaterial({ map: texture } );
var sprite = new THREE.Sprite( spriteMaterial );
/* 缩放比例 */
sprite.scale.set(15,7,0);
return sprite;
},
/* 绘制圆角矩形 */
roundRect(ctx, x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x+r, y);
ctx.lineTo(x+w-r, y);
ctx.quadraticCurveTo(x+w, y, x+w, y+r);
ctx.lineTo(x+w, y+h-r);
ctx.quadraticCurveTo(x+w, y+h, x+w-r, y+h);
ctx.lineTo(x+r, y+h);
ctx.quadraticCurveTo(x, y+h, x, y+h-r);
ctx.lineTo(x, y+r);
ctx.quadraticCurveTo(x, y, x+r, y);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
},
mounted() {
this.init();
}
}
</script>
<style scoped>
#container{
width: 1024;
height:900px;
margin: 0 auto;
}
</style>