Three.js + React + Echart(折线图 光线流动效果,柱状图数据动态更新动画) + Svga-Web应用之数据大屏(适配1920*1080 2560*1440 3840*2160)

Web应用之数据大屏

大屏效果

一、技术栈

  1. React 17.0.0 搭建脚手架
  2. Eahcrt常规图表
  3. Svga动画
  4. 3D模型-Three.Js
  5. 大屏适配-目标大屏(4K -3840*2160)

二、React 17.0.0 脚手架搭建

npx create-react-app my-app
cd my-app
npm start

具体详细情况,自行官网查看React官网

三、Echarts常规图表

1、echarts-for-react Echarts的React版本

$ npm install --save echarts-for-react

# `echarts` is the peerDependence of `echarts-for-react`, you can install echarts with your own version.
$ npm install --save echarts
import ReactECharts from 'echarts-for-react';

// render echarts option.
<ReactECharts option={this.getOption()} />

四、Svga动画

1、svga动画支持IOS、安卓、Web
2、官网网站:详细使用
3、Web使用方式:

直接在:https://github.com/svga/SVGAPlayer-Web下载 build/svga.min.js,
并添加至目标页面。
或使用 npm install svgaplayerweb —save 添加依赖,
并在需要使用的 js 中添加 require(‘svgaplayerweb’) 添加 Div 容器,并加载动画,
具体方法参见:https://github.com/svga/SVGAPlayer-Web。
我们还提供了体积更小的轻量版:SVGA.Lite

4、代码实列

Add Div Tag.
<div id="demoCanvas" style="styles..."></div>
Load Animation
var player = new SVGA.Player('#demoCanvas');
var parser = new SVGA.Parser('#demoCanvas'); // Must Provide same selector eg:#demoCanvas IF support IE6+
parser.load('rose_2.0.0.svga', function(videoItem) {
    player.setVideoItem(videoItem);
    player.startAnimation();
})

5、关注点:parse.load的svga文件,最好是网络地址或是将文件放置在服务器地址,使用服务器文件地址引用
5、如果地址存在跨域问题,需要在前端配置代理,具体配置代理,请问度娘。
6、如果配置代理,在parse.load的文件地址是有讲究的,举例如下
(1) 代理的字段:‘/devApi’
(2) 文件地址不代理:https:///images/02top.svga
(3) 文件地址代理:https://
/devApi/images/02top.svga
(4) 代码如下:

//不代理 不需要完整的文件地址
parser.load('images/02top.svga', function(videoItem) {
    player.setVideoItem(videoItem);
    player.startAnimation();
})
//代理 不需要完整的文件地址
parser.load('devApi/images/02top.svga', function(videoItem) {
    player.setVideoItem(videoItem);
    player.startAnimation();
})

7、如果存在多个svga的动画需要加载,可以尝试数组循环调用

五、3D模型-Three.Js

1、three.js install

npm i three --save
import * as THREE from 'three';

2、如果导入模型,需要准备好glb或者gltf格式的模型文件
3、如果不导入就需要,按照three.js 从几何体 材质 场景 相机 一点点 建立自己的3D模型了,很艰辛的
4、至于three.js 的原理:相机,场景,渲染器的基础,请官网,或者百度自行查看,我直接上代码,有详细注释,也算自己给自己的总结:

import React, { Component } from 'react'
//引入three
import * as THREE from 'three'
//导入控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
//对场景环境做处理
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js'
//模型导入器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
//用于解码用KHR_draco_mesh_compression扩展名压缩的资产 暂时没看到使用效果
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'

//对模型进行后期处理 处理辉光 轨迹 等特殊效果
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
//处理增加后期效果 的 辉光后,场景出现
import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
// import { SSAARenderPass } from 'three/examples/jsm/postprocessing/SSAARenderPass.js';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js';
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'

import * as dat from 'dat.gui'

import gsap from 'gsap'
class B3Model extends Component {
    constructor(props) {
        super(props)
        this.state = {
            commonModel: null,
        }
        //性能控制器,显示当前模型的性能数据
        // const stats = new Stats()
        //3d模型导入工具
        const fltfLoader = new GLTFLoader()
        //一个几何图形的加载器,用德拉科库压缩。
        const dracoLoader = new DRACOLoader()
        //该对象用于跟踪时间。如果performance.now可用,则 Clock 对象通过该方法实现,否则回落到使用略欠精准的Date.now来实现。
        const clock = new THREE.Clock()
        let mixer
        //渲染的容器
        this.container = null;
        //渲染器
        this.renderer = null;
        this.pmremGenerator = null;
        this.scene = null
        this.camera = null
        this.controls = null
        this.composer = null
        this.outLinePass = null
        this.effectFXAA = null
        this.mouse = null
        this.rayCaster = null
        this.ssaaRenderPass = null
        this.initTime = new Date();//上次时间
        this.initNumber = 1;
        this.rendererer = () => {
            this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
            this.container = document.getElementById('b3Screen');
            //Window 接口的devicePixelRatio返回当前显示设备的物理像素分辨率
            // 与CSS像素分辨率之比。 此值也可以解释为像素大小的比率:一个CSS像素
            // 的大小与一个物理像素的大小。 简单来说,它告诉浏览器应使用多少屏幕
            // 实际像素来绘制单个CSS像素。
            this.renderer.setPixelRatio(window.devicePixelRatio)
            //渲染器设置尺寸
            this.renderer.setSize(this.container.clientWidth, this.container.clientHeight)
            //定义呈现程序的输出编码。默认是THREE.LinearEncoding。
            this.renderer.outputEncoding = THREE.sRGBEncoding
            this.renderer.shadowMap.enabled = true
            this.renderer.physicallyCorrectLights = true
            //渲染器放置到实际的dom上面
            this.container.appendChild(this.renderer.domElement)
            this.pmremGenerator = new THREE.PMREMGenerator(this.renderer)
        }
        //场景
        this.scener = () => {
            this.scene = new THREE.Scene()
            // 创建一个纹理图片加载器加载图片
            // var textureLoader = new THREE.TextureLoader();
            // var texture = textureLoader.load('b3Image/background.png');
            // 纹理对象Texture赋值给场景对象的背景属性.background
            // scene.background = texture
            //场景的背景颜色
            this.scene.background = new THREE.Color("rgb(0, 0, 0)")
            //理论想加一个光源
            // const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
            // directionalLight.position.set(15, 10, 0);
            // this.scene.add(directionalLight);
            this.scene.environment = this.pmremGenerator.fromScene(
                new RoomEnvironment(),
                0.04
            ).texture
            // const axesHelper = new THREE.AxesHelper(5);
            // this.scene.add(axesHelper);
        }
        //设置相机
        this.camerer = () => {
            this.camera = new THREE.PerspectiveCamera(
                60,
                window.innerWidth / window.innerHeight,
                0.1,
                1000
            )
            this.camera.position.set(0, 2, -2)
        }
        //控制器
        this.controlser = () => {
            let THAT = this;
            this.controls = new OrbitControls(this.camera, this.renderer.domElement)
            this.controls.target.set(0, .5, 0)
            // 更新控制。必须在任何手动改变相机变换后调用,或者在更新循环中,如果设置了. autorotate或. enabledamping。
            this.controls.update()
            this.controls.enabled = false
            // 启用或禁用摄像机平移。默认是正确的。
            this.controls.enablePan = true
            // 设置为true使能阻尼(惯性),可以用来给控制的重量感。默认是假的。
            // 注意,如果启用了此功能,则必须在动画循环中调用.update()。
            this.controls.enableDamping = true
            // 视角最小距离
            // this.controls.minDistance = 1;
            // 视角最远距离
            // this.controls.maxDistance = 5000;
            this.controls.dampingFactor = 0.5;
            //设置模型垂直旋转的最大和最小角度
            this.controls.minPolarAngle = 0;
            this.controls.maxPolarAngle = Math.PI / 2.7;

        }
        //模型加载
        this.moduleLoader = () => {
            let THAT = this;
            //模型文件和模型输出格式文件都放置在public
            // dracoLoader.setDecoderPath('js/libs/draco/gltf/')
            //用于解码用KHR_draco_mesh_compression扩展名压缩的资产。
            // fltfLoader.setDRACOLoader(dracoLoader)
            // 'models/gltf/LittlestTokyo.glb'
            fltfLoader.load(
                'models/glb/B30215.glb',
                function (gltf) {
                    //获取到整体模型的场景
                    const model = gltf.scene
                    //改变模型子模型的属性
                    //需要判断没个子模型具有的数据 然后给模型添加上去
                    model.children = model.children.filter(item => item.name !== "camera")
                    let modelChildrenArray = [];
                    model.children.forEach(item => {
                        //1、判断是否是mesh
                        if (item.isMesh) {
                            //改变部分模型的透明度
                            item.material.shininess = 1;
                            item.castShadow = true
                            item.receiveShadow = true
                            item.material.transparent = true
                            if (item.name === 'building02' || item.name === 'building03' || item.name === 'building03') {
                                //修改模型透明 需要修改此属性为false 否则会造成底部马赛克问题
                                item.material.depthTest = false;
                                item.material.opacity = 0.2
                            }
                            if (item.name === "b3") {
                                //关闭b3的透明度
                                item.material.transparent = false
                            }
                            //修改蓝色组件的颜色
                            if (item.name === 'plate07') {
                                //此材质 有发光属性 发光强度过高 导致太亮了 修改发光强度
                                item.material.emissiveIntensity = 1
                            }
                        }
                        //找到底部地面 把地面的材质修改为不改光材质
                        if (item.name === 'ground') {
                            item.material = new THREE.MeshBasicMaterial({ color: item.material.color })
                        }
                        //对组件感光处理
                        modelChildrenArray.push(item)
                    })
                    //初始位置
                    // model.position.set(-0.65, 0.97, -0.38)
                    model.scale.set(0.03, 0.03, 0.03)
                    gsap.to(model.position, {
                        x: -0.65,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(model.position, {
                        y: 0.97,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(model.position, {
                        z: -0.38,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })

                    gsap.to(model.rotation, {
                        x: 0,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(model.rotation, {
                        y: Math.PI / 1.7224,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(model.rotation, {
                        z: Math.PI / 14.40367,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })

                    gsap.to(model.scale, {
                        x: 0.015,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(model.scale, {
                        y: 0.015,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(model.scale, {
                        z: 0.015,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    // model.scale.set(0.015, 0.015, 0.015)
                    // model.rotation.x = 0
                    // model.rotation.y = Math.PI / 1.7224
                    // model.rotation.z = Math.PI / 14.40367

                    THAT.setState({
                        commonModel: model
                    }, () => {
                        // console.log(THAT.state.commonModel)
                        THAT.scene.add(THAT.state.commonModel)
                        THAT.animate(THAT.state.commonModel)
                        THAT.setState({
                            loading: false
                        }, () => {
                            // THAT.initLocation()
                        })
                    })
                },
                undefined,
                function (e) {
                    console.error(e)
                }
            )
        }
        //后期处理 outLine效果
        this.initBloom = () => {
            //将效果和渲染器合并
            //选中物体的插件 光线捕捉器
            this.rayCaster = new THREE.Raycaster()
            //选中的原理是鼠标从我们看向的正面发出一束光线 穿过几个物体就把物体放在一个数据
            this.mouse = new THREE.Vector2()
            //使用renderTarget 渲染composer
            const pixelRatio = this.renderer.getPixelRatio();
            var renderTarget = new THREE.WebGLRenderTarget(
                this.container.clientWidth * pixelRatio,
                this.container.clientHeight * pixelRatio,
                {
                    minFilter: THREE.LinearFilter,
                    magFilter: THREE.LinearFilter,
                    format: THREE.RGBAFormat,
                    stencilBuffer: false,
                    type: THREE.FloatType,
                }
            );
            renderTarget.texture.name = "EffectComposer.rt1";
            this.composer = new EffectComposer(this.renderer);
            //对composer的进一步处理
            this.composer.setPixelRatio(window.devicePixelRatio);
            this.composer.setSize(this.container.clientWidth, this.container.clientHeight);
            let renderPass = new RenderPass(this.scene, this.camera);
            this.composer.addPass(renderPass)

            //处理条带
            // this.ssaaRenderPass = new SSAARenderPass(this.scene, this.camera);
            // this.composer.addPass(this.ssaaRenderPass)
            //处理背景变暗
            let effectColorSpaceConversion = new ShaderPass(GammaCorrectionShader)
            this.composer.addPass(effectColorSpaceConversion)
            //轮廓线
            this.outLinePass = new OutlinePass(new THREE.Vector2(this.container.clientWidth, this.container.clientHeight), this.scene, this.camera)
            //轮廓线 配置
            const params = {
                edgeStrength: 5.0,
                edgeGlow: 2.0,
                edgeThickness: 1.0,
                pulsePeriod: 3.5,
                rotate: false,
                usePatternTexture: false
            };
            this.outLinePass.edgeStrength = params.edgeStrength;//包围线浓度
            this.outLinePass.edgeGlow = params.edgeGlow;//边缘线范围
            this.outLinePass.edgeThickness = params.edgeThickness;//边缘线浓度
            this.outLinePass.pulsePeriod = params.pulsePeriod;;//包围线闪烁频率
            this.outLinePass.visibleEdgeColor.set('#8DDBFF');//包围线颜色
            this.outLinePass.hiddenEdgeColor.set('#8DDBFF');//被遮挡的边界线颜色
            this.composer.addPass(this.outLinePass)
            //处理锯齿
            this.effectFXAA = new ShaderPass(FXAAShader);
            this.effectFXAA.uniforms["resolution"].value.set(
                1 / this.container.clientWidth,
                1 / this.container.clientHeight
            )
            this.effectFXAA.renderToScreen = true;
            // 解决 增加 边缘线闪烁 后场景变暗的问题
            this.composer.addPass(this.effectFXAA)
        }
        this.resizeRendererToDisplaySize = (renderer) => {
            if (renderer) {
                const { width, height, clientWidth, clientHeight } = renderer.domElement;
                const needResize = width !== clientWidth || height !== clientHeight;
                if (needResize) {
                    renderer.setSize(clientWidth, clientHeight, false);
                }
                return needResize;
            }
        }
        this.animate = (model) => {
            let THAT = this;
            let CurrentTime = new Date();//本次时间
            let MODEL = THAT.scene.children[0]
            // console.log(`${(CurrentTime - THAT.initTime) / 1000 / 60} --- ${THAT.initNumber}`)
            if (THAT.initNumber === 1) {
                if ((CurrentTime - THAT.initTime) / 1000 / 60 >= 0.5 && THAT.props.animateFlag) {
                    THAT.outLinePass.selectedObjects = []
                    console.log(THAT.initNumber + '整数分钟了')
                    this.props.changeModelLocation('facade')
                    THAT.initNumber = THAT.initNumber + 1;
                    //到南立面
                    // MODEL.position.set(-2.26, -0.38, 4.46)
                    // MODEL.scale.set(0.06, 0.06, 0.06)
                    // MODEL.rotation.x = 0
                    // MODEL.rotation.y = Math.PI / 1.8
                    // MODEL.rotation.z = - Math.PI / 92
                    //使用gsap动画
                    gsap.to(MODEL.position, {
                        x: -2.26,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(MODEL.position, {
                        y: -0.38,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(MODEL.position, {
                        z: 4.46,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })

                    gsap.to(MODEL.rotation, {
                        x: 0,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(MODEL.rotation, {
                        y: Math.PI / 1.8,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(MODEL.rotation, {
                        z: - Math.PI / 92,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })

                    gsap.to(MODEL.scale, {
                        x: 0.06,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(MODEL.scale, {
                        y: 0.06,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    gsap.to(MODEL.scale, {
                        z: 0.06,
                        duration: 5,
                        ease: 'power1.inOut',
                        yoyo: true
                    })
                    if (MODEL.children.length > 0) {
                        MODEL.children.forEach(item => {
                            if (item.name === 'plate07') {
                                THAT.outLinePass.selectedObjects = [item]
                            }
                            if (item.name === 'plate09') {
                                THAT.outLinePass.selectedObjects.push(item)
                            }
                        })
                    }
                }
            } else {
                if ((CurrentTime - THAT.initTime) / 1000 / 60 >= THAT.initNumber * 0.5 && THAT.props.animateFlag) {
                    console.log(THAT.initNumber + '整数分钟了')
                    //南立面
                    if ((THAT.initNumber - 1) % 4 === 0) {
                        THAT.outLinePass.selectedObjects = []
                        THAT.props.changeModelLocation('facade')
                        gsap.to(MODEL.position, {
                            x: -2.26,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.position, {
                            y: -0.38,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.position, {
                            z: 4.46,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })

                        gsap.to(MODEL.rotation, {
                            x: 0,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.rotation, {
                            y: Math.PI / 1.8,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.rotation, {
                            z: - Math.PI / 92,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })

                        gsap.to(MODEL.scale, {
                            x: 0.06,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.scale, {
                            y: 0.06,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.scale, {
                            z: 0.06,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        if (MODEL.children.length > 0) {
                            MODEL.children.forEach(item => {
                                if (item.name === 'plate07') {
                                    THAT.outLinePass.selectedObjects = [item]
                                }
                                if (item.name === 'plate09') {
                                    THAT.outLinePass.selectedObjects.push(item)
                                }
                            })
                        }
                    }
                    //屋顶
                    if ((THAT.initNumber - 2) % 4 === 0 || THAT.initNumber === 2) {
                        THAT.outLinePass.selectedObjects = []
                        this.props.changeModelLocation('roof')
                        //隆顶位置01
                        //设置模型的位置 设置模型的放大的比例 设置模型初始化角度
                        gsap.to(MODEL.position, {
                            x: -1.45,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.position, {
                            y: -1.18,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.position, {
                            z: -0.915,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })

                        gsap.to(MODEL.rotation, {
                            x: - Math.PI / 10.94,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.rotation, {
                            y: Math.PI / 2,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.rotation, {
                            z: - Math.PI / 10.94,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })

                        gsap.to(MODEL.scale, {
                            x: 0.033,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.scale, {
                            y: 0.033,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.scale, {
                            z: 0.033,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        // MODEL.position.set(-1.45, -1.18, -0.915)
                        // MODEL.scale.set(0.033, 0.033, 0.033)
                        // MODEL.rotation.x = - Math.PI / 10.94
                        // MODEL.rotation.y = Math.PI / 2
                        // MODEL.rotation.z = - Math.PI / 10.94
                        if (MODEL.children.length > 0) {
                            MODEL.children.forEach(item => {
                                if (item.name === 'plate01') {
                                    THAT.outLinePass.selectedObjects = [item]
                                }
                            })
                        }
                    }
                    //阳光房
                    if ((THAT.initNumber - 3) % 4 === 0 || THAT.initNumber === 3) {
                        THAT.outLinePass.selectedObjects = []
                        this.props.changeModelLocation('sun')
                        //阳光房 02
                        gsap.to(MODEL.position, {
                            x: -3.33,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.position, {
                            y: -1.18,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.position, {
                            z: 0.16,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })

                        gsap.to(MODEL.rotation, {
                            x: 0,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.rotation, {
                            y: Math.PI / 1.21654,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.rotation, {
                            z: 0,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })

                        gsap.to(MODEL.scale, {
                            x: 0.06,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.scale, {
                            y: 0.06,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.scale, {
                            z: 0.06,
                            duration: 3,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        // MODEL.position.set(-3.33, -1.18, 0.16)
                        // MODEL.scale.set(0.06, 0.06, 0.06)
                        // MODEL.rotation.x = 0
                        // MODEL.rotation.y = Math.PI / 1.21654
                        // MODEL.rotation.z = 0
                        if (MODEL.children.length > 0) {
                            MODEL.children.forEach(item => {
                                if (item.name === 'plate06') {
                                    THAT.outLinePass.selectedObjects = [item]
                                }
                            })
                        }
                    }
                    //整体
                    if ((THAT.initNumber - 4) % 4 === 0 || THAT.initNumber === 4) {
                        THAT.outLinePass.selectedObjects = []
                        this.props.changeModelLocation('all')
                        gsap.to(MODEL.position, {
                            x: -0.65,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.position, {
                            y: 0.97,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.position, {
                            z: -0.38,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })

                        gsap.to(MODEL.rotation, {
                            x: 0,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.rotation, {
                            y: Math.PI / 1.7224,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.rotation, {
                            z: Math.PI / 14.40367,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })

                        gsap.to(MODEL.scale, {
                            x: 0.015,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.scale, {
                            y: 0.015,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                        gsap.to(MODEL.scale, {
                            z: 0.015,
                            duration: 5,
                            ease: 'power1.inOut',
                            yoyo: true
                        })
                    }
                    THAT.initNumber = THAT.initNumber + 1;
                }
            }
            mixer = new THREE.AnimationMixer(model)
            const delta = clock.getDelta()
            mixer.update(delta)
            if (this.resizeRendererToDisplaySize(THAT.renderer)) {
                const canvas = THAT.renderer.domElement;
                THAT.camera.aspect = canvas.clientWidth / canvas.clientHeight;
                THAT.camera.updateProjectionMatrix();
                THAT.composer.setSize(canvas.width, canvas.height);
            }
            // THAT.renderer.render(THAT.scene, THAT.camera)
            THAT.composer.render(delta)
            THAT.controls.update()
            requestAnimationFrame(this.animate)
        }
        //手动出发模型动画
        this.mateChangeModelLocation = (type) => {
            let THAT = this;
            let MODEL = THAT.scene.children[0]
            if (type === 'all') {
                THAT.outLinePass.selectedObjects = []
                this.props.changeModelLocation('all')
                gsap.to(MODEL.position, {
                    x: -0.65,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.position, {
                    y: 0.97,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.position, {
                    z: -0.38,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })

                gsap.to(MODEL.rotation, {
                    x: 0,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.rotation, {
                    y: Math.PI / 1.7224,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.rotation, {
                    z: Math.PI / 14.40367,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })

                gsap.to(MODEL.scale, {
                    x: 0.015,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.scale, {
                    y: 0.015,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.scale, {
                    z: 0.015,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
            } else if (type === 'facade') {
                THAT.outLinePass.selectedObjects = []
                THAT.props.changeModelLocation('facade')
                gsap.to(MODEL.position, {
                    x: -2.26,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.position, {
                    y: -0.38,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.position, {
                    z: 4.46,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })

                gsap.to(MODEL.rotation, {
                    x: 0,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.rotation, {
                    y: Math.PI / 1.8,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.rotation, {
                    z: - Math.PI / 92,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })

                gsap.to(MODEL.scale, {
                    x: 0.06,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.scale, {
                    y: 0.06,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.scale, {
                    z: 0.06,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                if (MODEL.children.length > 0) {
                    MODEL.children.forEach(item => {
                        if (item.name === 'plate07') {
                            THAT.outLinePass.selectedObjects = [item]
                        }
                        if (item.name === 'plate09') {
                            THAT.outLinePass.selectedObjects.push(item)
                        }
                    })
                }
            } else if (type === 'roof') {
                THAT.outLinePass.selectedObjects = []
                this.props.changeModelLocation('roof')
                //隆顶位置01
                //设置模型的位置 设置模型的放大的比例 设置模型初始化角度
                gsap.to(MODEL.position, {
                    x: -1.45,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.position, {
                    y: -1.18,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.position, {
                    z: -0.915,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })

                gsap.to(MODEL.rotation, {
                    x: - Math.PI / 10.94,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.rotation, {
                    y: Math.PI / 2,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.rotation, {
                    z: - Math.PI / 10.94,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })

                gsap.to(MODEL.scale, {
                    x: 0.033,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.scale, {
                    y: 0.033,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.scale, {
                    z: 0.033,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                // MODEL.position.set(-1.45, -1.18, -0.915)
                // MODEL.scale.set(0.033, 0.033, 0.033)
                // MODEL.rotation.x = - Math.PI / 10.94
                // MODEL.rotation.y = Math.PI / 2
                // MODEL.rotation.z = - Math.PI / 10.94
                if (MODEL.children.length > 0) {
                    MODEL.children.forEach(item => {
                        if (item.name === 'plate01') {
                            THAT.outLinePass.selectedObjects = [item]
                        }
                    })
                }
            } else if (type === 'sun') {
                THAT.outLinePass.selectedObjects = []
                this.props.changeModelLocation('sun')
                //阳光房 02
                gsap.to(MODEL.position, {
                    x: -3.33,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.position, {
                    y: -1.18,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.position, {
                    z: 0.16,
                    duration: 5,
                    ease: 'power1.inOut',
                    yoyo: true
                })

                gsap.to(MODEL.rotation, {
                    x: 0,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.rotation, {
                    y: Math.PI / 1.21654,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.rotation, {
                    z: 0,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })

                gsap.to(MODEL.scale, {
                    x: 0.06,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.scale, {
                    y: 0.06,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                gsap.to(MODEL.scale, {
                    z: 0.06,
                    duration: 3,
                    ease: 'power1.inOut',
                    yoyo: true
                })
                // MODEL.position.set(-3.33, -1.18, 0.16)
                // MODEL.scale.set(0.06, 0.06, 0.06)
                // MODEL.rotation.x = 0
                // MODEL.rotation.y = Math.PI / 1.21654
                // MODEL.rotation.z = 0
                if (MODEL.children.length > 0) {
                    MODEL.children.forEach(item => {
                        if (item.name === 'plate06') {
                            THAT.outLinePass.selectedObjects = [item]
                        }
                    })
                }
            }
        }
        this.pageClick = (e) => {
            let THAT = this
            let x, y
            x = e.clientX
            y = e.clientY
            THAT.mouse.x = (x / THAT.container.clientWidth) * 2 - 1
            THAT.mouse.y = -(y / THAT.container.clientHeight) * 2 + 1
            THAT.rayCaster.setFromCamera(THAT.mouse, THAT.camera)
            let intersects = THAT.rayCaster.intersectObjects([THAT.scene], true)
            if (intersects.length > 0) {
                THAT.outLinePass.selectedObjects = [intersects[0].object]
            }
        }
        //获取当前模型的位置
        this.initLocation = () => {
            let THAT = this;
            const gui = new dat.GUI({
                width: 200
            })
            // const f = gui.addFolder('B3模型控制器');
            //设置最大值max 最小值min 步调step 名字name 改变的回调 
            //控制x y z 
            gui.add(THAT.scene.position, 'x').min(-10).max(10).step(0.01).name('positionX').onFinishChange((value) => {
                console.log(value)
            });
            gui.add(THAT.scene.position, 'y').min(-10).max(10).step(0.01).name('positionY').onFinishChange((value) => {
                console.log(value)
            });
            gui.add(THAT.scene.position, 'z').min(-10).max(10).step(0.005).name('positionZ').onFinishChange((value) => {
                console.log(value)
            });
            //控制旋转
            gui.add(THAT.scene.rotation, 'x').min(-Math.PI).max(Math.PI).step(Math.PI / 180 / 2).name('rotationX').onFinishChange((value) => {
                console.log(value)
            });
            gui.add(THAT.scene.rotation, 'y').min(-Math.PI).max(Math.PI).step(Math.PI / 180 / 2).name('rotationY').onFinishChange((value) => {
                console.log(value)
            });
            gui.add(THAT.scene.rotation, 'z').min(-Math.PI).max(Math.PI).step(Math.PI / 180 / 2).name('rotationZ').onFinishChange((value) => {
                console.log(value)
            });
            //控制放到缩小
            gui.add(THAT.scene.children[0].scale, 'x').min(0).max(10).step(0.0001).name('modelpositionX').onFinishChange((value) => {
                console.log(value)
                THAT.scene.children[0].scale.set(value, value, value)
            });
        }
        this.init = () => {
            let THAT = this;
            THAT.rendererer();
            THAT.scener();
            THAT.camerer();
            THAT.controlser();
            THAT.initBloom();
            THAT.moduleLoader();

            window.onresize = function () {
                THAT.camera.aspect = THAT.container.clientWidth / THAT.container.clientHeight
                THAT.camera.updateProjectionMatrix()
                //renderer 根据尺寸重绘
                THAT.renderer.setSize(THAT.container.clientWidth, THAT.container.clientHeight)
                //后期处理 根据尺寸重绘
                THAT.composer.setSize(THAT.container.clientWidth, THAT.container.clientHeight)
                //使用着色解决锯齿
                THAT.effectFXAA.uniforms["resolution"].value.set(
                    1 / THAT.container.clientWidth,
                    1 / THAT.container.clientHeight
                )
            }
        }
    }
    componentDidMount() {
        this.init();
    }
    render() {
        return (
            <div className='b3-screen-content' id="b3Screen">

            </div>
        )
    }
}
export default B3Model 
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值