云生成

This commit is contained in:
X1627315083
2025-04-23 09:39:24 +08:00
parent b776f6a0c5
commit 42dfa3c032
22 changed files with 604 additions and 144 deletions

View File

@@ -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%;