vue+three.js三維模組化并可下載下傳為圖檔
環境搭建:
npm install 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>