three+bas实现图片漏斗动画切换图片效果代码

代码语言:html

所属分类:幻灯片

代码描述:three+bas实现图片漏斗动画切换图片效果代码

代码标签: 漏斗 动画 切换 图片 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >
<head>
	<style>
	    html,
body {
  height: 100%;
}

body {
  overflow: hidden;
  margin: 0;
  background-color: #000;
}

canvas {
  position: absolute;
  top: 0;
  left: 50%;
  -webkit-transform: translate(-50%, 0);
          transform: translate(-50%, 0);
}
	</style> 
</head>

<body>  

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.88.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/bas.js"></script>
    <script >
        var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var TEXTURE_SRC_BEFORE = '//repo.bfw.wiki/bfwrepo/image/5d653a3d2a1fe.png'; // https://unsplash.com/photos/dcp4hnQY-z0
var TEXTURE_SRC_AFTER = '//repo.bfw.wiki/bfwrepo/image/5d6539613d08b.png'; // https://unsplash.com/photos/weuWmzv7xnU

var PREFAB = {
  WIDTH: 1,
  HEIGHT: 1
};

var START_DELAY = 500;
var INTERVAL = '10.';
var DURATION_START = '1.2';
var DURATION_END = '1.2';

function init(textureBefore, textureAfter) {
  var image = textureBefore.image;
  var width = image.width;
  var height = image.height;
  var intervalX = width / PREFAB.WIDTH;
  var intervalY = height / PREFAB.HEIGHT;

  var root = new THREERoot({
    cameraPosition: [0, 0, width * 2.5],
    aspect: 0.6 / 1,
    autoStart: false
  });

  var prefab = new THREE.PlaneGeometry(PREFAB.WIDTH, PREFAB.HEIGHT);
  var geometry = new BAS.PrefabBufferGeometry(prefab, intervalX * intervalY);
  var aPosition = geometry.createAttribute('aPosition', 4);

  var i = 0;
  for (var x = 0; x < intervalX; x++) {
    for (var y = 0; y < intervalY; y++) {
      geometry.setPrefabData(aPosition, i++, [x * PREFAB.WIDTH - width / 2, y * PREFAB.HEIGHT - height / 2, 0, Math.random() // random coefficient
      ]);
    }
  }

  textureBefore.minFilter = THREE.LinearFilter;
  textureAfter.minFilter = THREE.LinearFilter;

  var material = new BAS.BasicAnimationMaterial({
    side: THREE.DoubleSide,
    vertexColors: THREE.VertexColors,
    uniforms: {
      uTime: { type: 'f', value: 0 },
      uSize: { type: 'vf2', value: [width, height] },
      mapBefore: { type: 't', value: textureBefore },
      mapAfter: { type: 't', value: textureAfter }
    },
    vertexFunctions: [BAS.ShaderChunk['ease_quad_in_out'], BAS.ShaderChunk['ease_quad_in'], BAS.ShaderChunk['ease_quad_out']],
    vertexParameters: '\n      uniform float uTime;\n      uniform vec2 uSize;\n      uniform sampler2D mapBefore;\n      uniform sampler2D mapAfter;\n      attribute vec4 aPosition;\n      const float interval = ' + INTERVAL + ';\n      const float durationStart = ' + DURATION_START + ';\n      const float durationEnd = ' + DURATION_END + ';\n      const float totalTime = durationStart + interval + durationEnd;\n      const float speed = 60.;\n      const float minWeight = 0.3;\n      const float fallSpeed = 4.;\n      const float xSpeed = 0.03;\n      const float spreadPosition = 0.03;\n    ',
    vertexInit: '\n      vec2 texelCoord = (aPosition.xy + uSize / 2.) / uSize;\n      vec4 texelBefore = texture2D(mapBefore, texelCoord);\n      vec4 texelAfter = texture2D(mapAfter, texelCoord);\n      float bottom = aPosition.y - uSize.y * 1.8;\n      float time = uTime / 50.;\n      float tTime = mod(time, totalTime);\n      float doubleTime = mod(time, totalTime * 2.);\n      float isReverse = step(totalTime, doubleTime);\n      float progress = max(tTime - durationStart, 0.);\n      float nProgress = progress / interval;\n      float move = progress * speed;\n      float weightBefore = pow(1. - texelBefore.r * texelBefore.g * texelBefore.b, 2.) * (1. - minWeight) + minWeight;\n      float weightAfter = pow(1. - texelAfter.r * texelAfter.g * texelAfter.b, 2.) * (1. - minWeight) + minWeight;\n      float order = pow(abs(aPosition.x) / (uSize.x * 0.5), 2.) * 40.;\n      float fall = max(-aPosition.y - uSize.y / 2. + move - order, 0.) * (aPosition.w * 0.2 + 1.) * (0.3 + nProgress) * fallSpeed;\n      float y = aPosition.y - fall * mix(weightBefore, weightAfter, easeQuadIn(min(fall, -bottom) / -bottom)) - move + order * clamp(progress, 0., 1.);\n      float offsetY = easeQuadOut(clamp(tTime / durationStart, 0., 1.)) * uSize.y * 0.9;\n      float endOffsetY = easeQuadIn(clamp((tTime - (durationStart + interval)) / durationEnd, 0., 1.)) * uSize.y * 0.9;\n    ',
    vertexPosition: '\n      transformed.x += aPosition.x / (1. + fall * xSpeed * max(1. - max(-y + (bottom * (1. - spreadPosition)), 0.) / (-bottom * spreadPosition), 0.));\n      transformed.y += max(y, bottom) + offsetY + endOffsetY;\n      transformed.z += aPosition.z;\n    ',
    vertexColor: '\n      vec4 colorBefore = texelBefore * (1. - isReverse) + texelAfter * isReverse;\n      vec4 colorAfter = texelBefore * isReverse + texelAfter * (1. - isReverse);\n      vColor = mix(colorBefore.rgb, colorAfter.rgb, smoothstep(-uSize.y / 2., bottom, y));\n    '
  });
  material.uniforms['mapBefore'].value.needsUpdate = true;
  material.uniforms['mapAfter'].value.needsUpdate = true;

  var mesh = new THREE.Mesh(geometry, material);
  mesh.frustumCulled = false;

  root.add(mesh);

  var time = -50;

  var postShader = new THREE.ShaderPass({
    uniforms: {
      'tDiffuse': { type: 't', value: null },
      'uTime': { type: 'f', value: time }
    },
    vertexShader: '\n      varying vec2 vUv;\n\n      void main () {\n        vUv = uv;\n        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.);\n      }\n    ',
    fragmentShader: '\n      uniform sampler2D tDiffuse;\n      uniform float uTime;\n      varying vec2 vUv;\n      const float interval = ' + INTERVAL + ';\n      const float durationStart = ' + DURATION_START + ';\n      const float durationEnd = ' + DURATION_END + ';\n      const float totalTime = durationStart + interval + durationEnd;\n      const float size = 0.03;\n      const float halfSize = size * 0.5;\n      const float n = size * 4.;\n      const float brightness = 500.;\n      const float speed = 0.006;\n\n      vec4 getMosaicColor (vec2 coord) {\n        return texture2D(tDiffuse, coord);\n        // vec4 mosaicColor = vec4(0.);\n        // for (float x = 0.; x <= size; x += size * 0.2) {\n        //   for (float y = 0.; y <= size; y += size * 0.2) {\n        //     mosaicColor += texture2D(tDiffuse, vec2(coord.x + x, coord.y + y));\n        //   }\n        // }\n        // return mosaicColor;\n      }\n      float lengthN (vec2 v, float n) {\n        vec2 tmp = pow(abs(v), vec2(n));\n        return pow(tmp.x + tmp.y, size / n);\n      }\n      float random (vec2 st) {\n        return fract(sin(dot(st, vec2(12.9898, 4.1414))) * 43758.5453);\n      }\n\n      void main () {\n        vec4 texel = texture2D(tDiffuse, vUv);\n        vec2 mosaicCoord = floor(vUv / size) * size + halfSize;\n        vec4 mosaicColor = getMosaicColor(mosaicCoord);\n        vec2 p = mod(vUv, size) - halfSize;\n        float time = uTime / 50.;\n        float tTime = mod(time, totalTime);\n        float doubleTime = mod(time, totalTime * 2.);\n        float isReverse = step(totalTime, doubleTime);\n        float mosaicBrightness = mosaicColor.r * mosaicColor.g * mosaicColor.b;\n        float isBright = step(0.0005, mosaicBrightness);\n        // float isBright = step(0.02, mosaicBrightness / 36.);\n        float isBlink = isBright * abs(min(step(vUv.y, 0.5) + step(0., tTime - (durationStart + interval)), 1.) * step(durationStart, tTime) - isReverse);\n        float l = (1. - clamp(lengthN(p, n), 0., 1.)) * isBlink;\n        float n = random(mosaicCoord) * 10.;\n        float blink = l * brightness * max(sin(uTime * speed + n) - 0.99, 0.);\n        gl_FragColor = texel + vec4(vec3(blink), 1.);\n      }\n    '
  });
  root.initPostProcessing([postShader, new THREE.BloomPass(1.3, 25, 3.1, 256), new THREE.ShaderPass(THREE.CopyShader)]);

  root.addUpdateCallback(function () {
    time++;
    material.uniforms['uTime'].value = time;
    postShader.uniforms['uTime'].value = time;
  });

  root.update(time);
  root.render();
  setTimeout(function () {
    root.start();
  }, START_DELAY);
}

var textureBefore = void 0,
    textureAfter = void 0;
function onLoad() {
  textureBefore && textureAfter && init(textureBefore, textureAfter);
}
new THREE.TextureLoader().load(TEXTURE_SRC_BEFORE, function (texture) {
  textureBefore = texture;
  onLoad();
});
new THREE.TextureLoader().load(TEXTURE_SRC_AFTER, function (texture) {
  textureAfter = texture;
  onLoad();
});

// --------------------
// Three.js Wrapper
// forked from https://github.com/zadvorsky/three.bas/blob/86931253240abadf68b7c62edb934b994693ed4a/examples/_js/root.js
// --------------------

var THREERoot = function () {
  function THREERoot(params) {
    var _camera$position,
        _this = this;

    _classCallCheck(this, THREERoot);

    // defaults
    params = Object.assign({
      container: document.body,
      fov: 45,
      zNear: 1,
      zFar: 10000,
      cameraPosition: [0, 0, 30],
      createCameraControls: false,
      autoStart: true,
      pixelRatio: window.devicePixelRatio,
      antialias: window.devicePixelRatio === 1,
      alpha: false,
      clearColor: 0x000000
    }, params);

    // maps and arrays
    this.updateCallbacks = [];
    this.resizeCallbacks = [];
    this.objects = {};

    // renderer
    this.renderer = new THREE.WebGLRenderer({
      antialias: params.antialias,
      alpha: params.alpha
    });
    this.renderer.setPixelRatio(params.pixelRatio);
    this.renderer.setClearColor(params.clearColor);
    this.canvas = this.renderer.domElement;

    // container
    this.container = typeof params.container === 'string' ? document.querySelector(params.container) : params.container;
    this.container.appendChild(this.canvas);

    this.aspect = params.aspect;
    this.setSize();

    // camera
    this.camera = new THREE.PerspectiveCamera(params.fov, this.width / this.height, params.zNear, params.zFar);
    (_camera$position = this.camera.position).set.apply(_camera$position, _toConsumableArray(params.cameraPosition));

    // scene
    this.scene = new THREE.Scene();

    // resize handling
    this.resize();
    window.addEventListener('resize', function () {
      _this.resize();
    });

    // tick / update / render
    params.autoStart && this.tick();

    // optional camera controls
    params.createCameraControls && this.createOrbitControls();

    // pointer
    this.raycaster = new THREE.Raycaster();
    this.pointer = new THREE.Vector2();
  }

  _createClass(THREERoot, [{
    key: 'setSize',
    value: function setSize() {
      if (this.aspect) {
        if (this.container.clientWidth / this.container.clientHeight > this.aspect) {
          this.width = this.container.clientHeight * this.aspect;
          this.height = this.container.clientHeight;
        } else {
          this.width = this.container.clientWidth;
          this.height = this.container.clientWidth / this.aspect;
        }
      } else {
        this.width = this.container.clientWidth;
        this.height = this.container.clientHeight;
      }
    }
  }, {
    key: 'createOrbitControls',
    value: function createOrbitControls() {
      var _this2 = this;

      if (!THREE.TrackballControls) {
        console.error('TrackballControls.js file is not loaded.');
        return;
      }

      this.controls = new THREE.TrackballControls(this.camera, this.canvas);
      this.addUpdateCallback(function () {
        _this2.controls.update();
      });
    }
  }, {
    key: 'start',
    value: function start() {
      this.tick();
    }
  }, {
    key: 'stop',
    value: function stop() {
      cancelAnimationFrame(this.animationFrameId);
    }
  }, {
    key: 'addUpdateCallback',
    value: function addUpdateCallback(callback) {
      this.updateCallbacks.push(callback);
    }
  }, {
    key: 'addResizeCallback',
    value: function addResizeCallback(callback) {
      this.resizeCallbacks.push(callback);
    }
  }, {
    key: 'add',
    value: function add(object, key) {
      key && (this.objects[key] = object);
      this.scene.add(object);
    }
  }, {
    key: 'addTo',
    value: function addTo(object, parentKey, key) {
      key && (this.objects[key] = object);
      this.get(parentKey).add(object);
    }
  }, {
    key: 'get',
    value: function get(key) {
      return this.objects[key];
    }
  }, {
    key: 'remove',
    value: function remove(o) {
      var object = void 0;

      if (typeof o === 'string') {
        object = this.objects[o];
      } else {
        object = o;
      }

      if (object) {
        object.parent.remove(object);
        delete this.objects[o];
      }
    }
  }, {
    key: 'tick',
    value: function tick(time) {
      var _this3 = this;

      this.update(time);
      this.render();
      this.animationFrameId = requestAnimationFrame(function (time) {
        _this3.tick(time);
      });
    }
  }, {
    key: 'update',
    value: function update(time) {
      this.updateCallbacks.forEach(function (callback) {
        callback(time);
      });
    }
  }, {
    key: 'render',
    value: function render() {
      this.renderer.render(this.scene, this.camera);
    }
  }, {
    key: 'resize',
    value: function resize() {
      this.container.style.width = '';
      this.container.style.height = '';
      this.setSize();

      this.camera.aspect = this.width / this.height;
      this.camera.updateProjectionMatrix();

      this.renderer.setSize(this.width, this.height);
      this.resizeCallbacks.forEach(function (callback) {
        callback();
      });
    }
  }, {
    key: 'initPostProcessing',
    value: function initPostProcessing(passes) {
      var _this4 = this;

      var size = this.renderer.getSize();
      var pixelRatio = this.renderer.getPixelRatio();
      size.width *= pixelRatio;
      size.height *= pixelRatio;

      var composer = this.composer = new THREE.EffectComposer(this.renderer, new THREE.WebGLRenderTarget(size.width, size.height, {
        minFilter: THREE.LinearFilter,
        magFilter: THREE.LinearFilter,
        format: THREE.RGBAFormat,
        stencilBuffer: false
      }));

      var renderPass = new THREE.RenderPass(this.scene, this.camera);
      composer.addPass(renderPass);

      for (var i = 0; i < passes.length; i++) {
        var pass = passes[i];
        pass.renderToScreen = i === passes.length - 1;
        composer.addPass(pass);
      }

      this.renderer.autoClear = false;
      this.render = function () {
        _this4.renderer.clear();
        composer.render();
      };

    .........完整代码请登录后点击上方下载按钮下载查看

网友评论0