three.js 纹理动画实现

需求:

1、使用一张长图、分别播放这张长图的不同位置 来达到动态内容的目的

解决方案:

1、纹理创建并指定重复方向:this.texture.wrapS = this.texture.wrapT = THREE.RepeatWrapping;

2、设定纹理显示范围(就是你的图片要显示的一格动画范围):texture.repeat.set( 1 / this.tilesHorizontal宽, 1 / this.tilesVertical高 );

3、然后就是更改 texture.offset.x  、texture.offset.y 的事情了

一般的动画的话 可以直接在动画函数体内直接更改这两个参数值、

当然这个自带的动画更新函数是很快的、要不想播放的这么快怎么解决呢、

4、这个就要涉及函数类了、先创建一个类、然后创建纹理的时候 new 继承一份类型、 然后在这个类里面加一个方法、去更新继承的这个类的参数、最后在场景动画里面调取的时候去处理就可以了。

不用参考我下面的写法、我这个就是直接copy过来的、这些都可以根据实际的场景去自定义一套自己的规则。

Addtexture(){  
      this.texture = new THREE.TextureLoader().load(this.path+"btn/c.png")// this.texture.repeat.set(1/4,  1/6);
      this.test = new this.TextureAnimator(this.texture, 4, 6, 16, 55)
      
      // this.updatetexture()
    },
    update(){
      var delta = this.clock.getDelta(); 
      this.test.update(1000*delta)
    },
  TextureAnimator(texture, tilesHoriz, tilesVert, numTiles, tileDispDuration) 
  {    
    // note: texture passed by reference, will be updated by the update function.
      
    this.tilesHorizontal = tilesHoriz;
    this.tilesVertical = tilesVert;
    // how many images does this spritesheet contain?
    //  usually equals tilesHoriz * tilesVert, but not necessarily,
    //  if there at blank tiles at the bottom of the spritesheet. 
    this.numberOfTiles = numTiles;
    texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 
    texture.repeat.set( 1 / this.tilesHorizontal, 1 / this.tilesVertical );

    // how long should each image be displayed?
    this.tileDisplayDuration = tileDispDuration;

    // how long has the current image been displayed?
    this.currentDisplayTime = 0;

    // which image is currently being displayed?
    this.currentTile = 0;
      
    this.update = function( milliSec )
    {
      this.currentDisplayTime += milliSec;
      while (this.currentDisplayTime > this.tileDisplayDuration)
      {
        this.currentDisplayTime -= this.tileDisplayDuration;
        this.currentTile--;
        if (this.currentTile == this.numberOfTiles)
          this.currentTile = 0;
        var currentColumn = this.currentTile % this.tilesHorizontal;
        texture.offset.x = currentColumn / this.tilesHorizontal;
        var currentRow = Math.floor( this.currentTile / this.tilesHorizontal );
        texture.offset.y = currentRow / this.tilesVertical;
      }
    };
  },
    AddPlaneBuffer(spot) {// 方向按键模型
    
      var geometry = new THREE.PlaneBufferGeometry(2, 5, 32);
      var material = new THREE.MeshBasicMaterial({
        map: this.texture,
        side: THREE.DoubleSide,
        transparent: true, // 调整黑色背景问题。
      });
      var plane = new THREE.Mesh(geometry, material);
      plane.name = spot.name;
      plane.ivt = spot.ivt;
      plane.modeltype = spot.type;
      plane.XYZ = spot.cpoint
      plane.size = spot.size
      plane.position.set(spot.spot.x,spot.spot.y,spot.spot.z);
      plane.lookAt(0, 999, 0);
      this.scene.add(plane);
    },
    animate() { // 实时更新动画函数
      this.renderer.render(this.scene, this.camera);
      window.requestAnimationFrame(() => this.animate());
      this.orbitControls.update();
      this.update()
      TWEEN.update();
    },

 

posted @ 2020-11-12 16:15  睡到自然醒ccc  阅读(1236)  评论(2编辑  收藏  举报