artemsemkin

Rhye HTML5 Template - WebGL ignore mobile bar height

Oct 28th, 2020
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class BaseGLAnimation {
  2.  
  3.   constructor({
  4.     target,
  5.     canvas,
  6.     aspect
  7.   }) {
  8.     this.target = target;
  9.     this.canvas = canvas;
  10.  
  11.     if (!BaseGLAnimation.isThreeLoaded() || !this.canvas) {
  12.       return false;
  13.     }
  14.     this.coverMode = aspect ? true : false;
  15.     this.aspect = aspect || window.outerWidth / window.outerHeight;
  16.     this.scene = this._getScene();
  17.     this.viewport = this.coverMode ? this._getViewportCover() : this._getViewport();
  18.     this.camera = this._getCamera();
  19.     this.viewSize = this._getViewSize();
  20.     this.position = this._calculatePosition();
  21.  
  22.     this.renderer = this._getRenderer();
  23.     this.renderer.setPixelRatio(1); // window.devicePixelRatio
  24.     this.renderer.setClearColor(0xffffff, 0.0);
  25.     this.renderer.setSize(this.viewport.width, this.viewport.height);
  26.     this.renderer.setAnimationLoop(this._render.bind(this));
  27.  
  28.     this.loader = this._getTextureLoader();
  29.  
  30.     this.camera.position.z = 1;
  31.     this.camera.updateProjectionMatrix();
  32.     this._updateScene();
  33.  
  34.     this._bindEvents();
  35.   }
  36.  
  37.   _bindEvents() {
  38.     window.$window.on('resize', debounce(() => {
  39.       this._updateScene();
  40.     }, 250));
  41.  
  42.     window.$window.on('arts/barba/transition/start', () => {
  43.       this.destroy();
  44.     });
  45.   }
  46.  
  47.   _render() {
  48.     this.renderer.render(this.scene, this.camera);
  49.   }
  50.  
  51.   _getRenderer() {
  52.     return new THREE.WebGLRenderer({
  53.       canvas: this.canvas,
  54.       powerPreference: 'high-performance',
  55.       alpha: true
  56.     });
  57.   }
  58.  
  59.   _getScene() {
  60.     return new THREE.Scene();
  61.   }
  62.  
  63.   _getCamera() {
  64.     return new THREE.PerspectiveCamera(
  65.       53.1,
  66.       this.viewport.aspectRatio,
  67.       0.1,
  68.       1000
  69.     );
  70.   }
  71.  
  72.   _getTextureLoader() {
  73.     return new THREE.TextureLoader();
  74.   }
  75.  
  76.   _getPlane({
  77.     geometry,
  78.     material
  79.   }) {
  80.     return new THREE.Mesh(geometry, material);
  81.   }
  82.  
  83.   _updateScene() {
  84.     this.viewport = this.coverMode ? this._getViewportCover() : this._getViewport();
  85.     this.viewSize = this._getViewSize();
  86.     this.camera.aspect = this.viewport.aspectRatio;
  87.     this.camera.updateProjectionMatrix();
  88.     this.renderer.setSize(this.viewport.width, this.viewport.height);
  89.   }
  90.  
  91.   _getViewport() {
  92.  
  93.     const width = window.outerWidth;
  94.     const height = window.outerHeight;
  95.     const aspectRatio = width / height;
  96.  
  97.     return {
  98.       width,
  99.       height,
  100.       aspectRatio
  101.     }
  102.   }
  103.  
  104.   _getViewportCover() {
  105.     let
  106.       height = parseFloat(window.outerHeight),
  107.       width = parseFloat(height * this.aspect),
  108.       aspectRatio = this.aspect,
  109.       multiplier = 1
  110.  
  111.     if (this.aspect > 1) {
  112.       multiplier = window.outerWidth > width ? window.outerWidth / width : 1;
  113.     } else {
  114.       multiplier = this.canvas.clientWidth / width;
  115.     }
  116.  
  117.     if (multiplier < 1) {
  118.       multiplier = 1;
  119.     }
  120.  
  121.     width = width * multiplier;
  122.     height = height * multiplier;
  123.  
  124.     return {
  125.       width,
  126.       height,
  127.       aspectRatio
  128.     };
  129.   }
  130.  
  131.   _getViewSize() {
  132.     // fit plane to screen
  133.     // https://gist.github.com/ayamflow/96a1f554c3f88eef2f9d0024fc42940f
  134.  
  135.     const distance = this.camera.position.z;
  136.     const vFov = (this.camera.fov * Math.PI) / 180;
  137.     const height = 2 * Math.tan(vFov / 2) * distance;
  138.     const width = height * this.viewport.aspectRatio;
  139.  
  140.     return {
  141.       width,
  142.       height,
  143.       vFov
  144.     };
  145.   }
  146.  
  147.   _calculatePosition() {
  148.     let
  149.       height = parseFloat(window.outerHeight),
  150.       width = parseFloat(height * this.viewport.aspectRatio),
  151.       multiplier = 1;
  152.  
  153.     if (this.viewport.aspectRatio > 1) {
  154.       multiplier = window.outerWidth > width ? window.outerWidth / width : 1;
  155.     } else {
  156.       multiplier = this.canvas.clientWidth / width;
  157.     }
  158.  
  159.     if (multiplier < 1) {
  160.       multiplier = 1;
  161.     }
  162.  
  163.     width = width * multiplier;
  164.     height = height * multiplier;
  165.  
  166.     return {
  167.       width,
  168.       height
  169.     };
  170.   }
  171.  
  172.   _loadTextures() {
  173.     const self = this,
  174.       promises = [];
  175.  
  176.     this.items.each(function (index) {
  177.       const url = $(this).find('[data-texture-src]').attr('data-texture-src');
  178.  
  179.       promises.push(
  180.         self._loadTexture({
  181.           loader: self.loader,
  182.           url,
  183.           index
  184.         })
  185.       );
  186.     });
  187.  
  188.     return new Promise((resolve, reject) => {
  189.       // resolve textures promises
  190.       Promise.all(promises).then(promises => {
  191.         // all textures are loaded
  192.         promises.forEach((promise, index) => {
  193.           const $img = $(this.items[index]).find('[data-texture-src]');
  194.           // assign texture to item
  195.           this.items[index].texture = promise.texture;
  196.           this.items[index].texture.magFilter = THREE.LinearFilter;
  197.           this.items[index].texture.minFilter = THREE.LinearFilter;
  198.           this.items[index].texture.anisotropy = this.renderer.capabilities.getMaxAnisotropy();
  199.  
  200.           if ($img.is('img')) {
  201.             // load texture back to src (needed for AJAX transition)
  202.             $img.attr('src', $img.attr('data-texture-src'));
  203.           }
  204.         });
  205.  
  206.         resolve();
  207.       });
  208.     });
  209.   }
  210.  
  211.   _loadTexture({
  212.     loader,
  213.     url,
  214.     index
  215.   }) {
  216.     // https://threejs.org/docs/#api/en/loaders/TextureLoader
  217.     return new Promise((resolve, reject) => {
  218.       if (!url) {
  219.         resolve({
  220.           texture: null,
  221.           index
  222.         });
  223.         return;
  224.       }
  225.       // load a resource
  226.       loader.load(
  227.         // resource URL
  228.         url,
  229.  
  230.         // onLoad callback
  231.         texture => {
  232.           resolve({
  233.             texture,
  234.             index
  235.           });
  236.         },
  237.  
  238.         // onProgress callback currently not supported
  239.         undefined,
  240.  
  241.         // onError callback
  242.         error => {
  243.           console.error('An error happened during loading a texture to the canvas.', error);
  244.           reject(error);
  245.         }
  246.       )
  247.     })
  248.   }
  249.  
  250.   _getVertexShader(id) {
  251.     return document.getElementById(id).textContent || false;
  252.   }
  253.  
  254.   _getFragmentShader(id) {
  255.     return document.getElementById(id).textContent || false;
  256.   }
  257.  
  258.   static isThreeLoaded() {
  259.     return (typeof window.THREE === 'object');
  260.   }
  261.  
  262.   destroy() {
  263.     this.renderer.setAnimationLoop(null);
  264.     this.camera = undefined;
  265.     this.scene = undefined;
  266.     this.loader = undefined;
  267.     this.material = undefined;
  268.     // this.renderer = undefined;
  269.     window.$window.off('resize');
  270.   }
  271. }
Add Comment
Please, Sign In to add comment