123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- <template>
- <div>
- <div id="container"></div>
- <canvas id="canvas"></canvas>
- <div class="top">
- <el-select v-model="value" size="mini" placeholder="请选择">
- <el-option
- v-for="item in options"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- <el-select v-model="value" size="mini" placeholder="请选择">
- <el-option
- v-for="item in options"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- </div>
- <div class="rt">
- <el-select v-model="value" size="mini" placeholder="请选择">
- <el-option
- v-for="item in options"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- </div>
- <div class="menu">
- <el-button
- v-if="playStatu"
- icon="el-icon-video-play"
- @click="paly"
- circle
- ></el-button>
- <el-button
- v-else
- icon="el-icon-video-pause"
- @click="paly"
- circle
- ></el-button>
- </div>
- </div>
- </template>
- <script>
- import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
- import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
- import * as Three from "three";
- import { SwitchSprite } from "../../public/static/three_sprite_utils";
- import { GridHelper, Raycaster, Vector2 } from "three";
- var camera = null;
- var scene = null;
- var renderer = null;
- var clock = null;
- var orbitControls = null;
- var animationMixer = null;
- var walkAction = null;
- var sprite = null;
- var group = null;
- export default {
- data() {
- return {
- publicPath: process.env.BASE_URL,
- playStatu: true,
- options: [{
- value: '选项1',
- label: '黄金糕'
- }, {
- value: '选项2',
- label: '双皮奶'
- }, {
- value: '选项3',
- label: '蚵仔煎'
- }, {
- value: '选项4',
- label: '龙须面'
- }, {
- value: '选项5',
- label: '北京烤鸭'
- }],
- value: ''
- };
- },
- mounted() {
- this.element = document.getElementById("container");
- // this.animate();
- this.init();
- // this.spriteText()
- },
- methods: {
- paly() {
- this.playStatu == true ? walkAction.play() : walkAction.stop();
- this.playStatu = !this.playStatu;
- },
- //初始化
- init() {
- scene = new Three.Scene();
- clock = new Three.Clock();
- camera = new Three.PerspectiveCamera(
- 70,
- window.innerWidth / window.innerHeight,
- 1,
- 1000
- );
- camera.position.set(5, 21, -1);
- renderer = new Three.WebGLRenderer({ antialias: true });
- orbitControls = new OrbitControls(camera, renderer.domElement);
- orbitControls.target = new Three.Vector3(0, 19, 0);
- animationMixer = new Three.AnimationMixer(scene);
- const container = document.getElementById("container");
- renderer.setSize(window.innerWidth, window.innerHeight);
- container.appendChild(renderer.domElement);
- window.addEventListener("resize", () => this.onWindowResize());
- // PolarGridHelper( radius:标网格的半径, radials:径向线的数量, circles:圆圈数,
- // divisions:每个圆圈使用的线段数, color1:用于网格元素的第一种颜色, color2:用于网格元素的第一种颜色 )
- var radius = 20;
- var radials = 15;
- var circles = 15;
- var divisions = 100;
- var helper02 = new Three.PolarGridHelper(
- radius,
- radials,
- circles,
- divisions,
- "#6adcff",
- "#6adcff"
- );
- // helper02.position.set(0, -20, 0)
- scene.add(helper02);
- let that = this;
- var loader = new FBXLoader();
- loader.load(`${that.publicPath}static/fan1.fbx`, async (fbx3d) => {
- await console.log(fbx3d);
- fbx3d.position.set(0, 12.4, -0.6);
- fbx3d.scale.set(0.2, 0.2, 0.2);
- fbx3d.children[9].material = fbx3d.children[6].material.clone();
- fbx3d.children[6].material = fbx3d.children[6].material.clone();
- fbx3d.children[9].material.transparent = true;
- fbx3d.children[9].material.opacity = 0.3;
- // fbx3d.children[9].material.wireframe = true;
- // fbx3d.children[9].material.wireframeLinewidth = 20
- // fbx3d.children[6].material.wireframe = true;
- // fbx3d.children[9].material.color.set("#00bfff");
- // fbx3d.children[6].material.color.set("#00bfff");
- fbx3d.children[2].materialnew = new Three.MeshPhysicalMaterial({
- color: 0xff0000,
- // 材质像金属的程度. 非金属材料,如木材或石材,使用0.0,金属使用1.0,中间没有(通常).
- // 默认 0.5. 0.0到1.0之间的值可用于生锈的金属外观
- metalness: 1.0,
- // 材料的粗糙程度. 0.0表示平滑的镜面反射,1.0表示完全漫反射. 默认 0.5
- roughness: 0.6,
- // 设置环境贴图
- // 反射程度, 从 0.0 到1.0.默认0.5.
- // 这模拟了非金属材料的反射率。 当metalness为1.0时无效
- // reflectivity: 0.5,
- });
- scene.add(fbx3d);
- scene.add(new Three.AmbientLight(0xffffff, 1.5));
- const animationClip = fbx3d.animations.find(
- (animationClip) => animationClip.name === "Take 001"
- );
- walkAction = animationMixer.clipAction(animationClip);
- });
- //射线
- renderer.domElement.addEventListener("click", (event) => {
- const { offsetX, offsetY } = event;
- const x = (offsetX / window.innerWidth) * 2 - 1;
- const y = -(offsetY / window.innerHeight) * 2 + 1;
- const mousePoint = new Vector2(x, y);
- const raycaster = new Raycaster();
- raycaster.params = { sprite: {} };
- raycaster.setFromCamera(mousePoint, camera);
- let intersects = raycaster.intersectObjects(scene.children, true);
- intersects = intersects.filter(
- (intersect) => !(intersect.object instanceof GridHelper)
- );
- console.log(intersects)
- var selectedMesh = intersects[0].object;
- var newSprite = SwitchSprite(
- selectedMesh.name || "aa",
- selectedMesh.position,
- selectedMesh
- );
- if (newSprite != null) scene.add(newSprite);
- });
- this.render();
- },
- render() {
- // 更新动画
- animationMixer.update(clock.getDelta());
- renderer.render(scene, camera);
- orbitControls.update();
- window.requestAnimationFrame(() => this.render());
- },
- onWindowResize() {
- renderer.setSize(window.innerWidth, window.innerHeight);
- camera.aspect = window.innerWidth / window.innerHeight;
- camera.updateProjectionMatrix();
- },
- },
- beforeDestroy() {
- camera = null;
- scene = null;
- renderer = null;
- clock = null;
- orbitControls = null;
- animationMixer = null;
- walkAction = null;
- },
- };
- </script>
- <style lang="scss" scoped>
- #container {
- width: 1920px;
- height: 100vh;
- }
- .menu {
- position: fixed;
- left: 20px;
- top: 20px;
- background-color: #fff;
- border: 1px solid #fff;
- border-radius: 20px;
- display: flex;
- justify-content: space-around;
- align-items: center;
- }
- .top{
- width: 60%;
- display: flex;
- position: fixed;
- justify-content: space-around;
- top: 20px;
- left: 10%;
- }
- .rt {
- width: 200px;
- min-height: 200px;
- position: fixed;
- right: 20px;
- top: 20px;
- // border: 1px solid #fff;
- // border-radius: 20px;
- }
- </style>
|