threejs 实现波动光圈效果 学习笔记

threejs yekong

使用threejs 实现波动光圈效果

使用threejs 实现波动光圈效果

演示效果

演示效果

引入图片资源

var material = new THREE.MeshBasicMaterial({
  color: 0x00ffff,//设置光圈颜色
  map: textureLoader.load('assets/fluctuationsInAperture.png'),
  transparent: true, //使用背景透明的png贴图,注意开启透明计算
  // side: THREE.DoubleSide, //双面可见
});
var mesh = new THREE.Mesh(geometry, material);

控制图片的变化

// 光圈大小在1~2.5倍之间变化
var _s = 2.5;
// 渲染函数
function render() {
  _s += 0.01;
  mesh.scale.set(_s, _s, _s);
  if (_s <= 1.3) {
    mesh.material.opacity = (_s - 1.0) * 3.3;//3.3约等于1/(1.3-1.0),保证透明度在0~1之间变化
  } else if (_s > 1.3 && _s <= 2.5) {
    mesh.material.opacity = 1 - (_s - 1) / 1.5;//缩放2.5对应0 缩放1.0对应1
  } else {
    _s = 1.0;
  }
  renderer.render(scene, camera); //执行渲染操作
  requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}
render();

图片准备

图片准备

完整实例代码

<!--波动光圈-->
<template>
  <div class="homebody">
    <div class="canvasGLTFBody">
      <div ref='canvasGLTF' class="canvasGLTF">
      </div>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three'
// 引入Three.js扩展库
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { devIp } from '@/api/ipConfig'

export default {
  name: 'fluctuationsInAperture',
  data () {
    return {
      list: []
    }
  },
  created: function () {

  },
  mounted: function () {
    var that = this
    /**
     * 创建场景对象Scene
     */
    var scene = new THREE.Scene()
    // 矩形平面网格模型设置背景透明的png贴图
    var geometry = new THREE.PlaneBufferGeometry(60, 60) //默认在XOY平面上
    var textureLoader = new THREE.TextureLoader() // TextureLoader创建一个纹理加载器对象
    var material = new THREE.MeshBasicMaterial({
      color: 0x00ffff,//设置光圈颜色
      map: textureLoader.load(devIp + 'assets/fluctuationsInAperture.png'),
      transparent: true, //使用背景透明的png贴图,注意开启透明计算
      // side: THREE.DoubleSide, //双面可见
    })
    var mesh = new THREE.Mesh(geometry, material)
    // mesh.rotateX(-Math.PI / 2); //旋转到XOZ平面
    scene.add(mesh)
    /**
     * 相机设置
     */
    var width = window.innerWidth //窗口宽度
    var height = window.innerHeight //窗口高度
    var k = width / height //窗口宽高比
    var s = 150 //三维场景显示范围控制系数,系数越大,显示的范围越大
    //创建相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000)
    camera.position.set(200, 300, 200) //设置相机位置
    // camera.position.set(0, 0, 200); //设置相机位置
    camera.lookAt(scene.position) //设置相机方向(指向的场景对象)
    /**
     * 创建渲染器对象
     */
    var renderer = new THREE.WebGLRenderer()
    renderer.setSize(width, height) //设置渲染区域尺寸
    // renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色

    // 光圈大小在1~2.5倍之间变化
    var _s = 2.5

    // 渲染函数
    function render () {
      _s += 0.01
      mesh.scale.set(_s, _s, _s)
      if (_s <= 1.3) {
        mesh.material.opacity = (_s - 1.0) * 3.3//3.3约等于1/(1.3-1.0),保证透明度在0~1之间变化
      } else if (_s > 1.3 && _s <= 2.5) {
        mesh.material.opacity = 1 - (_s - 1) / 1.5//缩放2.5对应0 缩放1.0对应1
      } else {
        _s = 1.0
      }
      renderer.render(scene, camera) //执行渲染操作
      requestAnimationFrame(render) //请求再次执行渲染函数render,渲染下一帧
    }

    render()
    //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
    var controls = new OrbitControls(camera, renderer.domElement)
    that.$refs.canvasGLTF.appendChild(renderer.domElement)
  },
  methods: {}
}
</script>

<style lang="scss" scoped>
.homebody {
  width: 100%;
  height: 100%;
  position: absolute;
  background: #0f1633;
  //position: relative;

  .pageMain {
    position: relative;
    width: calc(100% - 60px - 60px);
    margin: 0 auto;
    height: calc(100% - 108px - 150px);
  }
}
</style>

其他实现方式

也可以通过ae实现动画,通过lottie渲染到页面中,例如:3d可视化案例 厂房中的标注动画。

喜欢