国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue3結合three.js實現(xiàn)3D帶有交互的動畫

這篇具有很好參考價值的文章主要介紹了vue3結合three.js實現(xiàn)3D帶有交互的動畫。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

three.js引入
npm install three
安裝軌道控件插件:
npm install three-orbit-controls
安裝渲染器插件:
npm i --save three-css2drender
vue文件中引用:
import * as Three from 'three'
在頁面中創(chuàng)建場景
//創(chuàng)建一個三維場景
const scene = new THREE.Scene();
創(chuàng)建一個透視相機
//創(chuàng)建一個透視相機,窗口寬度,窗口高度
const width = window.innerWidth,
  height = 400;
const camera = new THREE.PerspectiveCamera(38, width / height, 0.25, 100);
//設置相機位置
camera.position.set(-5, 3, 10);
//設置相機方向
camera.lookAt(new THREE.Vector3(0, 2, 0));
初始化渲染器
// 初始化渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearAlpha(0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, height);
renderer.outputEncoding = THREE.sRGBEncoding;
container.appendChild(renderer.domElement);

window.addEventListener("resize", onWindowResize);
初始動畫混合器
// 創(chuàng)建動畫混個器
let mixer = new THREE.AnimationMixer(scene);
// 創(chuàng)建時鐘對象 該對象用于跟蹤時間
let clock = new THREE.Clock();

動畫混合器是用于場景中特定對象的動畫的播放器。當場景中的多個對象獨立動畫時,每個對象都可以使用同一個動畫混合器。

參數(shù):rootObject 混合器播放的動畫所屬的對象。就是包含動畫模型的場景對象。
常用參數(shù)和屬性:
.time 全局的混合器時間。
.clipAction(AnimationClip) 返回所傳入的剪輯參數(shù)的AnimationAction對象。AnimationAction用來調度存儲在AnimationClip中的動畫。
AnimationClip 動畫剪輯,是一個可重用的關鍵幀軌道集,它代表動畫。
.getRoot() 返回混合器的根對象。
.update() 推進混合器時間并更新動畫。在渲染函數(shù)中調用更新動畫。文章來源地址http://www.zghlxwxcb.cn/news/detail-767151.html

創(chuàng)建光源,用于視覺可見
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 20, 0);
 scene.add(hemiLight);

 const dirLight = new THREE.DirectionalLight(0xffffff);
 dirLight.position.set(0, 20, 10);
 scene.add(dirLight);
創(chuàng)建加載glb文件模型
const loader = new GLTFLoader();
loader.load(
   "RobotExpressive.glb",
   function (gltf) {
     // 存儲模型含有動畫集合
     model = gltf.scene;
     scene.add(model);
     createGUI(model, gltf.animations);
   },
   undefined,
   function (e) {
     console.error(e);
   }
 );

最后加上動畫循環(huán)渲染

const animate = () => {
const dt = clock.getDelta();
	if (mixer) mixer.update(dt);
	 requestAnimationFrame(animate);
	 renderer.render(scene, camera);
	 stats.update();
};

完整代碼

<template>
   <div id="my-three"></div>
</template>
<script>
import {
  defineComponent,
  getCurrentInstance,
  onMounted,
  onUnmounted,
  computed,
  reactive,
  toRefs,
} from "vue";

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import Stats from "three/examples/jsm/libs/stats.module.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

export default defineComponent({
  name: "index",
  setup() {
    const ctx = getCurrentInstance();
    let state = reactive({
      currentIndex:0,
    });
    //創(chuàng)建一個三維場景
    const scene = new THREE.Scene();
    //創(chuàng)建一個透視相機,窗口寬度,窗口高度
    const width = window.innerWidth,
      height = 400;
    const camera = new THREE.PerspectiveCamera(38, width / height, 0.25, 100);
    //設置相機位置
    camera.position.set(-5, 3, 10);
    //設置相機方向
    camera.lookAt(new THREE.Vector3(0, 2, 0));

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    let mixer = new THREE.AnimationMixer(scene);
    let stats = new Stats();
    let clock = new THREE.Clock();
    let actions = {},
      activeAction,
      previousAction;
    // 默認動畫
    const api = {state:'Walking'}
    //控制器
    // const Controls = new OrbitControls(camera, renderer.domElement);
    onMounted(() => {
      onLoad();
    });
    const onLoad = () => {
      let model, container;
      container = document.getElementById("my-three");

      // scene.background = new THREE.Color(0xe0e0e0);
      scene.fog = new THREE.Fog(0xe0e0e0, 20, 100);

      // lights

      const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
      hemiLight.position.set(0, 20, 0);
      scene.add(hemiLight);

      const dirLight = new THREE.DirectionalLight(0xffffff);
      dirLight.position.set(0, 20, 10);
      scene.add(dirLight);

      // model
      const loader = new GLTFLoader();
      loader.load(
        "RobotExpressive.glb",
        function (gltf) {
          // 存儲模型含有動畫集合
          model = gltf.scene;
          scene.add(model);
          createGUI(model, gltf.animations);
        },
        undefined,
        function (e) {
          console.error(e);
        }
      );

      renderer.setClearAlpha(0);
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, height);
      renderer.outputEncoding = THREE.sRGBEncoding;
      container.appendChild(renderer.domElement);

      window.addEventListener("resize", onWindowResize);
      container.appendChild(stats.dom);
      animate();

      // 點擊動畫
      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 THREE.Vector2(x, y);

        const raycaster = new THREE.Raycaster();
        raycaster.setFromCamera(mousePoint, camera);
        const instersects = raycaster.intersectObjects(scene.children);

        instersects.forEach((item) => {
          console.log(item.object.name);
          if (
            item.object.name == "Head_2" ||
            item.object.name == "Head_3" ||
            item.object.name == "Head_4"
          ) {
            // console.log(instersects);
            // action.stop();
            const states = [
              "Idle",
              "Dance",
              "Death",
              "Sitting",
              "Standing",
              "Jump",
              "Yes",
              "No",
              "Wave",
              "Punch",
              "ThumbsUp",
            ];
            if(state.currentIndex<states.length - 1){
              state.currentIndex = state.currentIndex+1
            }else{
              state.currentIndex  = 0
            }
            fadeToAction(states[state.currentIndex], 0.2);
            mixer.addEventListener("finished", restoreState);
          }
        });
      });
    };
    const createGUI = (model, animations) => {
      const states = [
        "Idle",
        "Walking",
        "Running",
        "Dance",
        "Death",
        "Sitting",
        "Standing",
      ];
      const emotes = ["Jump", "Yes", "No", "Wave", "Punch", "ThumbsUp"];
      for (let i = 0; i < animations.length; i++) {
        const clip = animations[i];
        const action = mixer.clipAction(clip);
        actions[clip.name] = action;
        if (emotes.indexOf(clip.name) >= 0 || states.indexOf(clip.name) >= 4) {
          action.clampWhenFinished = true;
          action.loop = THREE.LoopOnce;
        }
      }
      activeAction = actions["Walking"];
      activeAction.play();
    };
    const fadeToAction = (name, duration) => {
      previousAction = activeAction;
      activeAction = actions[name];

      if (previousAction !== activeAction) {
        previousAction.fadeOut(duration);
      }

      activeAction
        .reset()
        .setEffectiveTimeScale(1)
        .setEffectiveWeight(1)
        .fadeIn(duration)
        .play();
    };
    const restoreState = () => {
      mixer.removeEventListener("finished", restoreState);

      fadeToAction(api.state, 0.2);
    };

    const animate = () => {
      const dt = clock.getDelta();

      if (mixer) mixer.update(dt);

      requestAnimationFrame(animate);

      renderer.render(scene, camera);

      stats.update();
    };
    const onWindowResize = () => {
      camera.aspect = window.innerWidth / height;
      camera.updateProjectionMatrix();

      renderer.setSize(window.innerWidth, height);
    };
    onUnmounted(() => {
      scene.traverse((e) => {
        if (e.BufferGeometry) e.BufferGeometry.dispose();
        if (e.material) {
          if (Array.isArray(e.material)) {
            e.material.forEach((m) => {
              m.dispose();
            });
          } else {
            e.material.dispose();
          }
        }
        if (e.isMesh) {
          e.remove();
        }
      });
      scene.remove();
      renderer.dispose();
      renderer.content = null;
      window.removeEventListener("resize", onWindowResize, false);
    });

    return {
      ...toRefs(state),
      onLoad,
      createGUI,
    };
  },
});
</script>
<style lang="less">
@import "./index.less";
</style>

到了這里,關于vue3結合three.js實現(xiàn)3D帶有交互的動畫的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • vue2+three.js實現(xiàn)類似VR、3D全景效果

    vue2+three.js實現(xiàn)類似VR、3D全景效果

    效果圖: 倆圖標是我自己加的前進后退按鈕,也是百度了好久,再加上GPT的幫助,才給搞出來。因為需求急,都不看官方文檔,百度到一個能跑的demo之后改吧改吧,就先用著了。 下面是代碼: 這里 代碼有很多用不到的地方和需要優(yōu)化的地方,我是來不及改了,就先這樣吧

    2024年02月15日
    瀏覽(87)
  • vue2+three.js+blender(實現(xiàn)3d 模型引入并可點擊效果)

    vue2+three.js+blender(實現(xiàn)3d 模型引入并可點擊效果)

    2023.9.13今天我學習了如何把3d建模里面的模型引入到vue中,并可以實現(xiàn)拖動,點擊的效果: 首先安裝: npm install three 相關代碼如下: ?如果沒有圖片可以去 Three.js--》建模軟件如何加載外部3D模型?_threejs加載3d模型_亦世凡華、的博客-CSDN博客

    2024年02月03日
    瀏覽(98)
  • VUE使用Three.js實現(xiàn)模型,點擊交互,相機旋轉視角跟隨移動(Threejs中使用Tweenjs,含demo源碼)

    VUE使用Three.js實現(xiàn)模型,點擊交互,相機旋轉視角跟隨移動(Threejs中使用Tweenjs,含demo源碼)

    目錄 一、Three.js是什么? 二、VUE簡單使用Three.js步驟 1.npm安裝 2.template模板 3.引入庫 4.定義全局變量 5.初始化場景 6.初始化相機 7.初始化燈光 8.初始化渲染器 9.創(chuàng)建模型(這里我搭建的模型是一個簡單雙面貨架模型) 10.根據瀏覽器窗口自適應 11.初始化函數(shù),頁面加載完成時調用

    2024年02月03日
    瀏覽(104)
  • 【案例】3D地球(vue+three.js)

    【案例】3D地球(vue+three.js)

    需要下載插件 有人找不到合適的地球平面圖的話,可直接地球平面圖

    2024年02月06日
    瀏覽(25)
  • vue3項目中使用three.js

    vue3項目中使用three.js

    在vue3項目中,通過three.js使用了一段短小但完整的代碼實現(xiàn)了實際的三維效果圖。 Three.js是一個輕量級,跨平臺的Javascript庫,可以在瀏覽器上結合HTML5的canvas,SVG或者WebGL,創(chuàng)建和展示3D模型和動畫。 Three.js允許我們在不依賴任何瀏覽器插件的情況下,創(chuàng)建一個GPU加速的3D動畫場

    2024年01月23日
    瀏覽(33)
  • TransformControls 是 Three.js 中的一個類,用于在網頁中進行 3D 場景中物體的交互式操作。

    TransformControls 是 Three.js 中的一個類,用于在網頁中進行 3D 場景中物體的交互式操作。

    demo案例 TransformControls 是 Three.js 中的一個類,用于在網頁中進行 3D 場景中物體的交互式操作。讓我們來詳細講解它的輸入參數(shù)、輸出、屬性和方法: 輸入參數(shù): TransformControls 構造函數(shù)通常接受兩個參數(shù): camera (THREE.Camera):用于渲染場景的攝像機。這個參數(shù)是必需的。

    2024年04月15日
    瀏覽(93)
  • Vue+Three.js建造3D小房子

    Vue+Three.js建造3D小房子

    前言 一、Three.js簡介 二、開發(fā)步驟 1.安裝Three.js 2.創(chuàng)建容器 3.創(chuàng)建模型 總結 3D模型給人一種更真實的感受,帶來極致的視覺體驗。本文介紹Vue結合Three.js開發(fā)3D小房子,接觸過OpenGL的小伙伴看起來會更輕松一點。 Three.js,一個WebGL引擎,基于JavaScript,可直接運行GPU驅動游戲與

    2024年02月07日
    瀏覽(26)
  • Three.js--》實現(xiàn)3d小島模型搭建

    Three.js--》實現(xiàn)3d小島模型搭建

    目錄 項目搭建 初始化three.js基礎代碼 設置環(huán)境背景 設置水面樣式 添加天空小島 今天簡單實現(xiàn)一個three.js的小Demo,加強自己對three知識的掌握與學習,只有在項目中才能靈活將所學知識運用起來,話不多說直接開始。 項目搭建 本案例還是借助框架書寫three項目,借用vite構建

    2024年02月05日
    瀏覽(430)
  • Three.js--》實現(xiàn)3d踢球模型展示

    Three.js--》實現(xiàn)3d踢球模型展示

    目錄 項目搭建 初始化three.js基礎代碼 設置環(huán)境紋理加載模型 使用Cannon-es實現(xiàn)物理世界 今天簡單實現(xiàn)一個three.js的小Demo,加強自己對three知識的掌握與學習,只有在項目中才能靈活將所學知識運用起來,話不多說直接開始。 項目搭建 本案例還是借助框架書寫three項目,借用

    2024年02月11日
    瀏覽(100)
  • Three.js--》實現(xiàn)3d字體模型展示

    Three.js--》實現(xiàn)3d字體模型展示

    目錄 項目搭建 初始化three.js基礎代碼 設置環(huán)境紋理 加載字體模型 今天簡單實現(xiàn)一個three.js的小Demo,加強自己對three知識的掌握與學習,只有在項目中才能靈活將所學知識運用起來,話不多說直接開始。 項目搭建 本案例還是借助框架書寫three項目,借用vite構建工具搭建vue項

    2024年02月07日
    瀏覽(93)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包