云生成
This commit is contained in:
@@ -1,5 +1,30 @@
|
||||
<template>
|
||||
<div class="three">
|
||||
<div class="parameter">
|
||||
<label>
|
||||
<span>X:</span>
|
||||
<a-slider class="system_silder"
|
||||
v-model:value="repeat.x"
|
||||
:tooltipVisible="false"
|
||||
@change="changeRepeat"
|
||||
:max="2"
|
||||
:step="0.001"
|
||||
:min="0.002"
|
||||
>
|
||||
</a-slider>
|
||||
</label>
|
||||
<label>
|
||||
<span>Y:</span>
|
||||
<a-slider class="system_silder"
|
||||
v-model:value="repeat.y"
|
||||
:tooltipVisible="false"
|
||||
@change="changeRepeat"
|
||||
:max="2"
|
||||
:step="0.01"
|
||||
>
|
||||
</a-slider>
|
||||
</label>
|
||||
</div>
|
||||
<div class="model" ref="threeDom">
|
||||
|
||||
</div>
|
||||
@@ -13,7 +38,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,computed,shallowRef,provide,nextTick,onMounted,toRefs, reactive} from 'vue'
|
||||
import { defineComponent,computed,shallowRef,provide,nextTick,onMounted,toRefs, reactive, onBeforeUnmount} from 'vue'
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import { Https } from "@/tool/https";
|
||||
import { useStore } from "vuex";
|
||||
@@ -46,14 +71,23 @@ export default defineComponent({
|
||||
renderer:shallowRef() as any,//渲染器
|
||||
pointLight:shallowRef() as any,//光
|
||||
controls:shallowRef() as any,//监听鼠标、键盘事件
|
||||
textureLoader:shallowRef() as any,//材质
|
||||
load:{
|
||||
state:false,
|
||||
progress:0 as any,
|
||||
}
|
||||
},
|
||||
repeat:{
|
||||
x:1,
|
||||
y:1,
|
||||
},
|
||||
animationId:null as any,
|
||||
})
|
||||
const dataDom = reactive({
|
||||
threeDom:null as any,
|
||||
})
|
||||
const dataTime = reactive({
|
||||
updataRepeat:null as any
|
||||
})
|
||||
const init = ()=>{
|
||||
data.scene = new THREE.Scene();
|
||||
data.group = new THREE.Group()
|
||||
@@ -190,8 +224,8 @@ export default defineComponent({
|
||||
|
||||
|
||||
data.controls.enableDamping = true;
|
||||
let animate = function () {
|
||||
requestAnimationFrame(animate);
|
||||
let animate = ()=>{
|
||||
data.animationId = requestAnimationFrame(animate);
|
||||
// data.renderer.render(data.scene, data.camera);
|
||||
// model.rotation.x += 0.01; //旋转物体
|
||||
var vector = data.camera.position.clone()
|
||||
@@ -204,6 +238,7 @@ export default defineComponent({
|
||||
};
|
||||
animate();
|
||||
}
|
||||
|
||||
const setModel = async (url:any)=>{
|
||||
clearModel()
|
||||
await addModel(url)
|
||||
@@ -215,6 +250,7 @@ export default defineComponent({
|
||||
let textureLoader = new THREE.TextureLoader()
|
||||
textureLoader.load(url, // 图片放在public/textures目录下
|
||||
(texture:any) => {
|
||||
data.textureLoader = texture
|
||||
// 3. 配置纹理参数
|
||||
texture.wrapS = THREE.RepeatWrapping;
|
||||
texture.wrapT = THREE.RepeatWrapping;
|
||||
@@ -229,11 +265,11 @@ export default defineComponent({
|
||||
const box = new THREE.Box3().setFromObject(child);
|
||||
const modelWidth = box.getSize(new THREE.Vector3()).x;
|
||||
const modelHeight = box.getSize(new THREE.Vector3()).y;
|
||||
const repeatX = modelWidth / textureWidth;
|
||||
const repeatY = modelHeight / textureHeight;
|
||||
data.repeat.x = 2 - modelWidth / textureWidth;
|
||||
data.repeat.y = 2 - modelHeight / textureHeight;
|
||||
// texture.repeat.set(1, 1); // 纹理重复次数
|
||||
texture.repeat.set(repeatX, repeatY); // 纹理重复次数
|
||||
|
||||
texture.repeat.set(2 - data.repeat.x, 2 - data.repeat.y); // 纹理重复次数
|
||||
|
||||
const newMaterial = new THREE.MeshStandardMaterial({
|
||||
map: texture, // 基础颜色贴图
|
||||
roughness: 0.7, // 表面粗糙度 (0-1)
|
||||
@@ -258,6 +294,8 @@ export default defineComponent({
|
||||
console.error('纹理加载失败:', error);
|
||||
data.load.state = false
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
const addModel = async (url:any)=>{
|
||||
@@ -340,13 +378,43 @@ export default defineComponent({
|
||||
await setModel(modeUrl)
|
||||
data.load.state = false
|
||||
}
|
||||
const changeRepeat = (e:any)=>{
|
||||
clearTimeout(dataTime.updataRepeat)
|
||||
dataTime.updataRepeat = setTimeout(()=>{
|
||||
data.textureLoader.repeat.set(2 - data.repeat.x,2 - data.repeat.y); // 纹理重复次数
|
||||
},1000)
|
||||
}
|
||||
onMounted(()=>{
|
||||
})
|
||||
onBeforeUnmount(()=>{
|
||||
if(data.animationId){
|
||||
cancelAnimationFrame(data.animationId);
|
||||
data.animationId = null;
|
||||
}
|
||||
data.scene.traverse((child:any) => {
|
||||
if (child.material) {
|
||||
child.material.dispose();
|
||||
}
|
||||
if (child.geometry) {
|
||||
child.geometry.dispose();
|
||||
}
|
||||
child = null;
|
||||
});
|
||||
data.renderer.forceContextLoss();
|
||||
data.renderer.dispose();
|
||||
data.scene.clear();
|
||||
data.scene = null;
|
||||
data.camera = null;
|
||||
data.controls = null;
|
||||
data.renderer.domElement = null;
|
||||
data.renderer = null;
|
||||
})
|
||||
return{
|
||||
...toRefs(dataDom),
|
||||
...toRefs(data),
|
||||
openSetData,
|
||||
addMaterial,
|
||||
changeRepeat,
|
||||
}
|
||||
},
|
||||
provide() {
|
||||
@@ -362,6 +430,22 @@ export default defineComponent({
|
||||
position: relative;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
> .parameter{
|
||||
display: flex;
|
||||
> label{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
padding-right: 2rem;
|
||||
// &:not(:last-child){
|
||||
// margin-right: 3rem;
|
||||
// }
|
||||
> span{
|
||||
font-size: 2rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .model{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
Reference in New Issue
Block a user