赞
踩
vue相关的代码片段
<template> <div id="my-three"></div> </template> <script setup> import {ref, onMounted, getCurrentInstance} from "vue"; import * as THREE from "three"; import {OrbitControls} from "three/examples/jsm/controls/OrbitControls" import {FBXLoader} from "three/examples/jsm/loaders/FBXLoader"; import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader"; //gltf import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader'; import imgurl from "@/assets/bj.png" import {ElMessage} from "element-plus"; let height = 0, width const {proxy} = getCurrentInstance(); const emit = defineEmits(['change']) const scene = new THREE.Scene(); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.outputEncoding = THREE.sRGBEncoding; // renderer.outputEncoding = THREE.sRGB; const loader = new GLTFLoader(); var clock = new THREE.Clock(); var mixer = null; let messagelog = null let duration = 9999000000 let camera, controls; onMounted(() => { document.getElementById("my-three")?.appendChild(renderer.domElement); height = document.getElementById("three").offsetHeight; width = document.getElementById("three").offsetWidth; // console.log(height); camera = new THREE.PerspectiveCamera(55, width / height, 0.1, 10000); controls = new OrbitControls(camera, renderer.domElement); controls.enableRotate = false; // 禁用旋转 if (height > 0) { init(); renderModel(); gltfModel1(); render(); } messagelog = ElMessage({ message: '第一步 点击选择养殖蚌', type: 'success', duration: duration, offset: window.screen.height / 2 }) }); function init() { //光源 const ambient = new THREE.AmbientLight(0xdddddd, 0.4); scene.add(ambient); //设置相机位置 // camera.position.set(10, 337, 533); camera.position.set(30, 1017, 1599); // camera.position.set(200, 200, 200); //设置相机方向 // camera.lookAt(0, 400, 0); //辅助坐标轴 // const axesHelper = new THREE.AxesHelper(200); //参数200标示坐标系大小,可以根据场景大小去设置 // scene.add(axesHelper); // scene.background = new THREE.Color(0xeaeaea); const sceneLoader = new THREE.TextureLoader(); let sceneColorTexture = sceneLoader.load(imgurl); // sceneColorTexture.minFilter = THREE.LinearFilter; scene.background = sceneColorTexture; scene.background.matrixAutoUpdate = false; renderer.setPixelRatio(window.devicePixelRatio); renderer.antialias = true; } let actions = [] // const segmentDurations = [2, 10.5,27.5] const segmentDurations = [2, 2, 8.5, 57.5] let currentActionIndex = 0 let currentIndex = 0 let isStop = false // 关键代码 function fetchLocal(e) { return new Promise((resolve, reject) => { plus.io.resolveLocalFileSystemURL(e, entry => { var reader = null; entry.file(file => { reader = new plus.io.FileReader(); reader.onloadend = (read) => { resolve(read.target.result) }; reader.readAsDataURL(file); }, function (error) { alert(error.message); }); }, err => { resolve(e) }) }) } function gltfModel1() { fetchLocal("./xiao.glb").then(res => { loader.load(res, function (obj) { // let scale = 100; // let scale = 300; let scale = 1000; obj.scene.scale.set(scale, scale, scale); // 将模型放大两倍 obj.scene.position.set(0, -1000, 0); // 将模型位置设置为长方形模型的中心点/ obj.scene.rotation.set(0, 0, 0); // 可以根据需要调整模型的旋转 // obj.scene.rotation.y += 0.8; // 旋转 obj.scene.translateY(-80); scene.add(obj.scene) // obj作为参数创建一个混合器,解析播放obj及其子对象包含的动画数据 mixer = new THREE.AnimationMixer(obj.scene); // 获取模型中的动画剪辑 const animations = obj.animations; // 查看动画数据 // obj.animations[0]:获得剪辑对象clip for (let i = 0; i < animations.length; i++) { console.log(animations[i], animations[i].name, 'ok') actions.push(mixer.clipAction(animations[i])); if (animations[i].name == 'Z_初始锚点') { const clip = animations[i]; if (clip) { // 创建动作并播放 const action = mixer.clipAction(clip); action.play(); // 将动画设置为第一帧 mixer.setTime(0); action.paused = true; } } } // console.log(obj) camera = obj.cameras[0] // 获取第一个动画剪辑 }) // }) const pmremGenerator = new THREE.PMREMGenerator(renderer); // 使用hdr作为背景色 pmremGenerator.compileEquirectangularShader(); const rgbeLoader = new RGBELoader(); fetchLocal("./venice_sunset_1k.hdr").then(res => { rgbeLoader.load(res, function (texture) { const envMap = pmremGenerator.fromEquirectangular(texture).texture; pmremGenerator.dispose(); scene.environment = envMap; // 给场景添加环境光效果 console.log(envMap); // scene.background = envMap; // 给场景添加背景图 }) }) // 根据模型名称 window.addEventListener('click', onMouseClick, false); } // let duration = 2000 function onMouseClick(event) { let raycaster = new THREE.Raycaster(); let mouse = new THREE.Vector2(); event.preventDefault(); mouse.x = (event.clientX / width) * 2 - 1; mouse.y = -(event.clientY / height) * 2 + 1; //这里为什么是-号,没有就无法点中 // console.log(event) raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(scene.children, true); if (intersects.length > 0) { // console.log(intersects) const intersectedObject = intersects[0].object; console.log(intersectedObject.name) if ( intersectedObject.name == '钳子003' || intersectedObject.name == '钳子001' || intersectedObject.name == '钳子002' || intersectedObject.name == '钳子' ) { let num = currentActionIndex == 1 ? 2 : 4 play(num) } if(intersectedObject.name == '固定钉'){ play(3) } if(intersectedObject.name == '拨肉针'||intersectedObject.name == 'FBXASC230FBXASC139FBXASC168FBXASC232FBXASC130FBXASC137FBXASC229'){ play(5) } if(intersectedObject.name == '取核针'||intersectedObject.name == 'FBXASC229FBXASC143FBXASC150FBXASC230FBXASC160FBXASC184FBXASC229'){ play(6) } } } let crrshow = 0 function play(index) { // duration = 10 // message.close() if (isStop) return; // duration = 10 if (currentIndex == index) { currentIndex = index + 1; crrshow = index + 1 if (currentIndex >= 7) { currentIndex = 0; } } else { return false; } emit('change', 10) if (messagelog) { messagelog.close() messagelog = null } currentActionIndex = index; isStop = true; actions.forEach((action) => { // console.log(action) action.stop(); if ( (currentActionIndex == 0 && action._clip.name == "A_选蚌") || (currentActionIndex == 1 && action._clip.name == "B_选珍珠") || (currentActionIndex == 2 && action._clip.name == "C_开蚌") || (currentActionIndex == 3 && action._clip.name == "D_固定蚌壳") || (currentActionIndex == 4 && action._clip.name == "E_放回钳子") || (currentActionIndex == 5 && action._clip.name == "F_拨开蚌肉") || (currentActionIndex == 6 && action._clip.name == "G_种珍珠") ) { console.log(action) // 第一次调用 play 启动播放 let num = parseFloat(action._clip.duration).toFixed(2) action.clampWhenFinished = true; action.loop = THREE.LoopOnce; action.enabled = true; action.clampWhenFinished = true; action.play() playNextSegment(num) } }) // playNextSegment() } let Tem = null function playNextSegment(num) { Tem = setTimeout(() => { isStop = false; if (currentActionIndex == 0) { messagelog = ElMessage({ message: '第二步 点击选择珍珠核', type: 'success', duration: duration, offset: window.screen.height / 2 }) } if (currentActionIndex == 1 || currentActionIndex == 3 || currentActionIndex == 5) { let message = currentActionIndex == 1 ? "第三步 点击选择右侧托盘里的钳子" : currentActionIndex == 3 ? "第五步 点击上方钳子放回托盘" : "第七步 点击右侧托盘里的送片针" messagelog = ElMessage({ message, type: 'success', duration: duration, offset: window.screen.height / 2 }) } if (currentActionIndex == 2 || currentActionIndex == 4) { let message = currentActionIndex == 2 ? "第四步 点击左侧托盘里的固定器" : "第六步 点击左侧托盘里的开口针" messagelog = ElMessage({ message: message, type: 'success', duration: duration, offset: window.screen.height / 2 }) } if (currentActionIndex == 6) { messagelog = ElMessage({ message: '育珠结束,请重新开始', type: 'success', duration: duration, offset: window.screen.height / 2 }) setTimeout(() => { initialization() }, 6000) } emit('change', crrshow) }, num * 1000); } function initialization() { if (messagelog) { messagelog.close() messagelog = null } isStop = false; crrshow = 0; currentActionIndex = 0; currentIndex = 0; if (Tem) { clearTimeout(Tem) } actions.forEach((action) => { // console.log(action) action.stop(); if (action._clip.name == 'Z_初始锚点') { action.play(); mixer.setTime(0); action.paused = true; } }) messagelog = ElMessage({ message: '第一步 点击选择养殖蚌', type: 'success', duration: duration, offset: window.screen.height / 2 }) emit('change', crrshow) } function renderModel() { //渲染 renderer.setSize(width, height); //设置渲染区尺寸 renderer.render(scene, camera); //执行渲染操作、指定场景、相机作为参数 // renderer.setClearColor(0x00ff00); // 设置背景颜色为绿色 renderer.toneMapping = THREE.ACESFilmicToneMapping; // 设置曝光度 renderer.toneMappingExposure = 1.5; // 适当调整曝光度 controls.minPolarAngle = Math.PI / 4; // 最小极角为 45 度 controls.maxPolarAngle = Math.PI / 2; // 最大极角为 90 度 } function render() { //校正不同通道颜色 requestAnimationFrame(render); if (mixer !== null) { //clock.getDelta()方法获得两帧的时间间隔 // 更新混合器相关的时间 mixer.update(clock.getDelta()); } renderer.autoClear = false renderer.clear() renderer.outputEncoding = null //THREE.RGBDEncoding controls.update(); renderer.render(scene, camera); } // 画布跟随窗口变化 window.onresize = function () { renderer.setSize(width, height); camera.aspect = width / height; camera.updateProjectionMatrix(); }; // 交互事件 // addEventListener("dblclick", onMouseDblclick, false); function onMouseDblclick(event) { let intersects = getIntersects(event); if (intersects.length !== 0 && intersects[0].object instanceof THREE.Mesh) { const selectedObject = intersects[0].object; let selectedObjects = []; selectedObjects.push(selectedObject); // console.log(selectedObjects); // outlinePass.selectedObjects = selectedObjects; } } //获取与射线相交的对象数组 function getIntersects(event) { let rayCaster = new THREE.Raycaster(); let mouse = new THREE.Vector2(); //通过鼠标点击位置,计算出raycaster所需点的位置,以屏幕为中心点,范围-1到1 mouse.x = (event.clientX / width) * 2 - 1; mouse.y = -(event.clientY / height) * 2 + 1; //这里为什么是-号,没有就无法点中 //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置 rayCaster.setFromCamera(mouse, camera); return rayCaster.intersectObjects(scene.children); } defineExpose({ play, initialization }) </script> <style scoped lang="scss"></style>
vue打包导入uniapp 的代码片段运行之后可以在安卓app正在运行显示
<template> <view class=""> <web-view :src="src"></web-view> </view> </template> <script> export default { data() { return { src: '' } }, onLoad() { let num =(new Date()).getTime() this.src = '/static/dist/index.html?id='+num; }, methods: { } } </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。