1var Digital = (function () { 2 3 function Digital() { 4 if (!(this instanceof Digital)) { 5 return new Digital(); 6 } 7 } 8 9 var superEaseIN = "M0,0,C0,0,0.668,0,0.84,0.036,1.076,0.085,0.922,1,1,1"; 10 11 12 Digital.prototype.Init = function(selector){ 13 this.el = document.querySelector(selector), 14 // this.stickyOverflow = this.el.querySelector(".sticky-overflow"), 15 this.matrixContainer = this.el.querySelector(".experience-display-matrix"), 16 this.displayHardware = this.el.querySelector(".display-hardware img"), 17 this.posterFrame = this.el.querySelector(".display-posterframe img"), 18 this.endFrame = this.el.querySelector(".display-endframe img"), 19 this.anchorEl = this.el.querySelector(".timeline-display"), 20 // this.animGroup = this.anim.getGroupForTarget(this.el), 21 this.screenSize = parseFloat(getComputedStyle(this.matrixContainer).getPropertyValue("--screen-to-hardware-ratio")), 22 this.camera, 23 this.perspective, 24 this.scene, 25 this.keyFrames = [], 26 this.renderer, 27 this.layers = {}, 28 this.baseKeyframes = { 29 start: "a0t", 30 end: "a0t + 140vh", 31 anchors: [this.anchorEl], 32 disabledWhen: ["no-enhanced"] 33 }, 34 this.textureOptions = { 35 HARDWARE_TEXTURE: {}, 36 POSTERFRAME_TEXTURE: {}, 37 ENDFRAME_TEXTURE: {}, 38 DOT_COUNT_MULTIPLIER: { 39 S: .5, 40 M: .75 41 } 42 }, 43 this.dotMultiple = 1, 44 this.isWebGLFallback = !1, 45 this._fallbackInitialized = !1, 46 this._render = this._render.bind(this); 47 // this._destroy = this._destroy.bind(this); 48 this.scrollTriggers = []; 49 50 var self = this; 51 loadjs.ready('threejs', function () { 52 self.mounted(); 53 }); 54 if (!loadjs.isDefined('threejs')) { 55 // loadjs(['/plugins/threejs/three.min.js?_=' + cacheId], 'threejs'); 56 loadjs([ 57 'module!/plugins/threejs/threejs-wrapper.js?_=' + cacheId, 58 59 '/plugins/threejs/globe-2.34.2.gl.min.js?_=' + cacheId, 60 '/js-static/year-in-review-2026/threejs.js?_=' + cacheId, 61 ], 'threejs'); 62 } 63 var onResize = _.debounce(this.onResizeDebounced, 500); 64 $(window).resize(onResize); 65 } 66 67 Digital.prototype.mounted = function() { 68 // this.gum.once(h.EVENTS.THREE_LOADED, ()=>{ 69 // this.THREE = window.THREE, 70 // this._initialize() 71 // } 72 // ), 73 // this.gum.once(h.EVENTS.THREE_NOT_LOADED, ()=>{ 74 // this._initializeFallback() 75 // } 76 // ), 77 this.THREE = window.THREE; 78 79 // Allow forcing the non-WebGL fallback for testing via query param. 80 // Example: ?webglFallback=1 81 if (this._shouldForceWebGLFallback()) { 82 this._initializeFallback({ reason: 'forced' }); 83 return; 84 } 85 86 this._initialize(); 87 } 88 89 Digital.prototype._shouldForceWebGLFallback = function() { 90 try { 91 var params = new URLSearchParams(window.location && window.location.search ? window.location.search : ""); 92 var v = params.get('webglFallback'); 93 if (v === null) { 94 return !1; 95 } 96 v = String(v).toLowerCase(); 97 return v === '1' || v === 'true' || v === 'yes'; 98 } catch (e) { 99 return !1; 100 } 101 } 102 103 Digital.prototype._isChromeBelow110 = function() { 104 try { 105 // Prefer UA-CH where available. 106 var uaData = navigator.userAgentData; 107 if (uaData && uaData.brands && uaData.brands.length) { 108 // brands: [{brand: 'Google Chrome', version: '119'}, ...] 109 for (var i = 0; i < uaData.brands.length; i++) { 110 var b = uaData.brands[i]; 111 var brand = (b.brand || '').toLowerCase(); 112 if (brand.indexOf('chrome') !== -1 && brand.indexOf('chromium') === -1) { 113 var v = parseInt(b.version, 10); 114 return !isNaN(v) && v < 110; 115 } 116 } 117 } 118 119 var ua = (navigator && navigator.userAgent) ? navigator.userAgent : ''; 120 // Exclude Edge/Opera which also contain 'Chrome/'. 121 if (!ua || /Edg\//.test(ua) || /OPR\//.test(ua)) { 122 return !1; 123 } 124 var match = ua.match(/Chrome\/(\d+)/); 125 if (!match || !match[1]) { 126 return !1; 127 } 128 var major = parseInt(match[1], 10); 129 return !isNaN(major) && major < 110; 130 } catch (e) { 131 return !1; 132 } 133 } 134 135 Digital.prototype._trackScrollTrigger = function(trigger) { 136 trigger && this.scrollTriggers.push(trigger); 137 } 138 139 Digital.prototype._killScrollTriggers = function() { 140 if (this.scrollTriggers && this.scrollTriggers.length) {
141 this.scrollTriggers.forEach(function(trigger){ 142 if (trigger && trigger.kill) { 143 trigger.kill(); 144 } 145 }); 146 } 147 this.scrollTriggers = []; 148 } 149 150 Digital.prototype._initialize = function() { 151 this.textureLoader = new this.THREE.TextureLoader; 152 var self = this; 153 Promise.all([this._loadImage(this.displayHardware, "HARDWARE_TEXTURE"), this._loadImage(this.posterFrame, "POSTERFRAME_TEXTURE")]).then(function(){ 154 // self.textureOptions.HARDWARE_TEXTURE = self.textureLoader.load(self.displayHardware.currentSrc, self._render); 155 self.textureOptions.POSTERFRAME_TEXTURE = self.textureLoader.load(self.posterFrame.currentSrc, self._render); 156 self.textureOptions.ENDFRAME_TEXTURE = self.textureLoader.load(self.endFrame.currentSrc, self._render); 157 self._setupEvents(); 158 }) 159 } 160 161 // _initializeFallback() { 162 // this.animGroup.addKeyframe(this.matrixContainer, r(r({}, this.baseKeyframes), {}, { 163 // end: "".concat(this.baseKeyframes.start, " + 20vh"), 164 // opacity: [0, 1] 165 // })), 166 // this.animGroup.addKeyframe(this.matrixContainer, r(r({}, this.baseKeyframes), {}, { 167 // end: "".concat(this.baseKeyframes.end, " + 60vh"), 168 // scale: [2.75, .24], 169 // easeFunction: "bezier(0.16, 0.00, 0.34, 1.00)" 170 // })) 171 // } 172 Digital.prototype._setupEvents = function() { 173 if (!window.ScrollTrigger) { 174 return; 175 } 176 try { 177 this._createRenderer(); 178 this._addLayers(); 179 this._setupKeyframes(); 180 this._sceneScaler(); 181 } catch (err) { 182 this._initializeFallback({ reason: 'webgl', error: err }); 183 } 184 // this.anim.once("enhanced-destroy", this._destroy) 185 } 186 187 Digital.prototype._createRenderer = function() { 188 this.stickyWidth = $(window).width(), 189 this.stickyHeight = $(window).height(), 190 this.perspective = 800; 191 // three r171 no longer exposes RAD2DEG on Math; inline conversion to avoid undefined 192 const e = 2 * Math.atan(this.stickyHeight / 2 / this.perspective) * (180 / Math.PI); 193 this.camera = new this.THREE.PerspectiveCamera(e,this.stickyWidth / this.stickyHeight,1,5e4), 194 this.camera.position.x = 0, 195 this.camera.position.y = 0, 196 this.camera.position.z = 1, 197 this.scene = new this.THREE.Scene, 198 this.scene.background = null, 199 this.renderer = new this.THREE.WebGLRenderer({ 200 antialias: !0, 201 alpha: !0 202 }); 203 204 // If the browser/GPU can't create a context, THREE may construct a renderer 205 // that doesn't actually have a usable WebGL context. 206 if (!this.renderer || !this.renderer.getContext || !this.renderer.getContext()) { 207 throw new Error('Could not create a WebGL context'); 208 } 209 210 this.renderer.setClearColor(0, 0), 211 this.renderer.setPixelRatio(Math.min(1.5, window.devicePixelRatio)), 212 this._updateMatrix(), 213 this.matrixContainer.prepend(this.renderer.domElement) 214 } 215 216 Digital.prototype._initializeFallback = function(meta) { 217 if (this._fallbackInitialized) { 218 return; 219 } 220 this._fallbackInitialized = !0; 221 this.isWebGLFallback = !0; 222 223 // Best-effort cleanup if a canvas was partially created. 224 try { 225 if (this.renderer && this.renderer.domElement && this.renderer.domElement.parentNode) { 226 this.renderer.domElement.parentNode.removeChild(this.renderer.domElement); 227 } 228 } catch (e) {} 229 230 // Kill any WebGL keyframes/triggers that may have been set up. 231 this._killScrollTriggers(); 232 233 // Fallback UX: show the poster frame image, fade it in, and scale it down on scroll. 234 // (No WebGL / no shaders / no layers.) 235 if (!window.ScrollTrigger || !window.gsap || !this.posterFrame) { 236 // If animation libs are missing, just ensure the image is visible. 237 try { 238 this.posterFrame.style.opacity = '1'; 239 this.posterFrame.style.transform = 'none'; 240 } catch (e) {} 241 return; 242 } 243 244 var self = this; 245 246 // The poster/end frame <picture> elements are intentionally hidden (Bootstrap d-none) 247 // in the enhanced/WebGL mode because they're used as texture sources. 248 // For the fallback we must make the poster visible. 249 var posterTarget = null; 250 try { 251 posterTarget = self.posterFrame.closest ? (self.posterFrame.closest('.display-posterframe') || self.posterFrame) : self.posterFrame; 252 if (posterTarget && posterTarget.classList && posterTarget.classList.contains('d-none')) { 253 posterTarget.classList.remove('d-none'); 254 } 255 } catch (e) { 256 posterTarget = self.posterFrame; 257 } 258 259 var fallbackEase = 'none'; 260 // try { 261 // if (window.CustomEase && window.CustomEase.create) { 262 // fallbackEase = window.CustomEase.create('digitalFallbackScale', 'M0,0,C0,0,0.668,0,0.84,0.036,1.076,0.085,0.922,1,1,1'); 263 // } 264 // } catch (e) {} 265 266 // Ensure the poster can fill the matrix without affecting layout. 267 try { 268 if (self.matrixContainer && window.getComputedStyle && getComputedStyle(self.matrixContainer).position === 'static') { 269 self.matrixContainer.style.position = 'relative'; 270 } 271 } catch (e) {} 272 273 try { 274 gsap.set(posterTarget, { display: 'block', width: '100%', height: '100%' }); 275 } catch (e) {} 276 277 // If posterTarget is the <picture>, also force the <img> to fill. 278 try { 279 if (self.posterFrame) { 280 gsap.set(self.posterFrame, { display: 'block', width: '100%', height: '100%', objectFit: 'cover' }); 281 } 282 } catch (e) {} 283 284 // Make sure the poster starts hidden for the fade-in. 285 gsap.set(posterTarget, { autoAlpha: 0, scale: 1, transformOrigin: '50% 50%' }); 286 287 var pinTrigger = ScrollTrigger.create({ 288 trigger: '.experience-display-matrix', 289 start: 'top top', 290 end: '+=200%', 291 pin: '.experience-display-matrix', 292 pinSpacing: false 293 }); 294 self._trackScrollTrigger(pinTrigger); 295 296 // Fade the matrix background in alongside the poster. 297 var matrixBg = document.querySelector('.year-in-review-2026--matrix-bg'); 298 if (matrixBg) { 299 gsap.set(matrixBg, { autoAlpha: 0 }); 300 var bgTargetAlpha = self._isChromeBelow110() ? 0.5 : 1; 301 var bgFadeTween = gsap.to(matrixBg, { 302 autoAlpha: bgTargetAlpha, 303 ease: 'none', 304 scrollTrigger: { 305 trigger: '.experience-display-matrix', 306 start: 'top top', 307 end: '+=15%', 308 scrub: true, 309 invalidateOnRefresh: true 310 } 311 }); 312 self._trackScrollTrigger(bgFadeTween.scrollTrigger); 313 } 314 315 var fadeTween = gsap.to(posterTarget, { 316 autoAlpha: 1, 317 ease: 'none', 318 scrollTrigger: { 319 trigger: '.experience-display-matrix', 320 start: 'top top', 321 end: '+=15%', 322 scrub: true, 323 invalidateOnRefresh: true 324 } 325 }); 326 self._trackScrollTrigger(fadeTween.scrollTrigger); 327 328 var scaleTween = gsap.to(posterTarget, { 329 scale: 0.5, 330 ease: fallbackEase, 331 scrollTrigger: { 332 trigger: '.experience-display-matrix', 333 start: 'top top', 334 end: '+=200%', 335 scrub: true, 336 invalidateOnRefresh: true 337 } 338 }); 339 self._trackScrollTrigger(scaleTween.scrollTrigger); 340 } 341 342 Digital.prototype._addLayers = function() { 343 this.updateCachedHeight(); 344 this._killScrollTriggers(); 345 this.materialOptions = e(167, this).bind(this)(); 346 var self = this; 347 Object.keys(this.materialOptions.layers).map(e=>{ 348 this.layers[e] = new Mesh(r({ 349 id: e, 350 el: this.el, 351 THREE: this.THREE, 352 stickyWidth: this.stickyWidth, 353 stickyHeight: this.stickyHeight, 354 }, this.materialOptions.layers[e])), 355 this._layerKeyframeMaker(this.layers[e]), 356 this.scene.add(this.layers[e].mesh); 357 358 } 359 ) 360 } 361 362 Digital.prototype.updateCachedHeight = function() { 363 var self = window.Digital || this; 364 self.digitalMatrixHeight = $('.digital-matrix').height() / 2; 365 } 366 367 368 Digital.prototype._setupKeyframes = function() { 369 var self = this; 370 371 var pinTrigger = ScrollTrigger.create({ 372 trigger: '.experience-display-matrix', 373 start: 'top top', 374 end: '+=200%', 375 pin: '.experience-display-matrix', 376 pinSpacing: false 377 }); 378 this._trackScrollTrigger(pinTrigger); 379 380 var camera = {z: 1}; 381 var cameraTween = gsap.to(camera, { 382 z: 900, 383 ease: CustomEase.create("custom", "M0,0,C0,0,0.074,-0.001,0.11,0.034,0.321,0.245,1,1,1,1"), 384 onUpdate(){ 385 self.camera.position.z = camera.z; 386 self._render(); 387 }, 388 scrollTrigger: { 389 trigger: '.experience-display-matrix', 390 start: 'top top', 391 end: '+=200%', 392 scrub: true, 393 onLeave: function(){ 394 setTimeout(function(){ 395 self._render(); 396 }, 1000); 397 setTimeout(function(){ 398 self._render(); 399 }, 2000); 400 self._render(); 401 } 402 } 403 }); 404 this._trackScrollTrigger(cameraTween.scrollTrigger); 405 406 // Fade in the background near the end of the main scroll animation. 407 var matrixBg = document.querySelector('.year-in-review-2026--matrix-bg'); 408 if (matrixBg) { 409 gsap.set(matrixBg, { autoAlpha: 0 }); 410 var bgTargetAlpha = self._isChromeBelow110() ? 0.5 : 1; 411 var bgFadeTween = gsap.to(matrixBg, { 412 autoAlpha: bgTargetAlpha, 413 ease: 'none', 414 scrollTrigger: { 415 trigger: '.year-review-2026-network-bottom-trigger', 416 start: "bottom bottom", 417 endTrigger: '.year-review-2022-network', 418 end: "top bottom", 419 scrub: true, 420 invalidateOnRefresh: true 421 } 422 }); 423 } 424 425 426 return; 427 this.animGroup.addKeyframe(this.renderer, r(r({}, this.baseKeyframes), {}, { 428 start: "".concat(this.baseKeyframes.start, " - 50vh"), 429 end: "a0b", 430 progress: [0, 1], 431 event: "render" 432 })).controller.friendlyName = "renderer", 433 this.animGroup.getControllerForTarget(this.renderer).on("render", ()=>{ 434 this._render() 435 } 436 ), 437 this.animGroup.addKeyframe(this.camera, r(r({}, this.baseKeyframes), {}, { 438 zPosition: [1, 800], 439 event: "update-camera", 440 easeFunction: "bezier(0.97, 0.00, 0.90, 0.45)" 441 })).controller.friendlyName = "camera", 442 this.animGroup.getControllerForTarget(this.camera).on("update-camera", e=>{ 443 this.camera.position.z = e.tweenProps.zPosition.current 444 } 445 ), 446 this.sceneScaleAnim = this.animGroup.addKeyframe(this.matrixContainer, r(r({}, this.baseKeyframes), {}, { 447 start: this.baseKeyframes.end, 448 end: "".concat(this.baseKeyframes.end, " + 60vh"), 449 uScale: [1, "(css(--scene-size) / ".concat(Math.max(this.stickyWidth, this.stickyHeight), ")")], 450 event: "update-scale", 451 easeFunction: "bezier(0.16, -0.32, 0.00, 1.00)" 452 })), 453 this.animGroup.getControllerForTarget(this.matrixContainer).on("update-scale", e=>{ 454 this.scene.scale.x = e.tweenProps.uScale.current, 455 this.scene.scale.y = e.tweenProps.uScale.current 456 } 457 ) 458 } 459 460 Digital.prototype._sceneScaler = function(item) { 461 var self = this; 462 463 var scaleObj = {scale: 1}; 464 var size = self.stickyWidth + 300; 465 // if(self.stickyWidth > 420) { 466 // size = 400; 467 // } 468 469 // if(self.stickyWidth > 768) { 470 // size = self.stickyWidth +; 471 // } 472 473 if(self.stickyWidth > 1024) { 474 size = 1024; 475 } 476 477 if(self.stickyWidth > 1200) { 478 size = 1200; 479 } 480 481 var scaleTween = gsap.to(scaleObj, { 482 scale: size / Math.max(this.stickyWidth, this.stickyHeight),
483 onUpdate(){ 484 self.scene.scale.x = scaleObj.scale; 485 self.scene.scale.y = scaleObj.scale; 486 }, 487 scrollTrigger: { 488 trigger: '.experience-display-matrix', 489 start: 'top top', 490 end: '+=200%', 491 scrub: true 492 } 493 }); 494 this._trackScrollTrigger(scaleTween.scrollTrigger); 495 } 496 497 Digital.prototype._layerKeyframeMaker = function(item) { 498 // console.log('e.mesh.material.uniforms.uOpacity',e.mesh.material.uniforms.uOpacity); 499 // try { 500 // e.mesh.material.opacity = 1.0; 501 // e.mesh.material.uniforms.uOpacity.value = 1.0; 502 // } catch (error) { 503 // console.error(error); 504 // } 505 // console.log(e.mesh); 506 // e.mesh.material.uniforms.uOpacity.value = 1; 507 508 if(item.id == "layer0") { 509 var opacityStart = this.digitalMatrixHeight * 0.6; 510 var opacityDuration = this.digitalMatrixHeight * 0.4; 511 512 var tween = gsap.fromTo(item.mesh.material.uniforms.uOpacity, { value: 0 }, { value: 1, scrollTrigger: { 513 trigger: '.digital-matrix', 514 start: () => "top+=" + opacityStart + " top", 515 end: () => "+=" + opacityDuration, 516 scrub: true, 517 invalidateOnRefresh: true 518 } }); 519 this._trackScrollTrigger(tween.scrollTrigger); 520 521 var zProperty = item.mesh.material.uniforms.uZPosition; 522 var zDuration = this.digitalMatrixHeight * 0.8; 523 var tween2 = gsap.fromTo(item.mesh.position, { z: zProperty.start }, { z: zProperty.end, scrollTrigger: { 524 trigger: '.digital-matrix', 525 start: () => "top+=" + opacityStart + " top", 526 end: () => "+=" + zDuration, 527 scrub: true, 528 invalidateOnRefresh: true 529 } }); 530 this._trackScrollTrigger(tween2.scrollTrigger); 531 532 // item.mesh.material.uniforms.uZPosition.value = 1; 533 534 // var tween2 = TweenMax.fromTo(item.mesh.material.uniforms.uZPosition, 1, { value: 100 }, { value: 1 } ); 535 // this.scenes.push(new ScrollMagic.Scene({ triggerElement: '.digital-matrix', triggerHook: 0.0, reverse: true, offset: 200, duration: "30%"}) 536 // .setTween(tween2) 537 // .addTo(this.controller) 538 // ); 539 } 540 else { 541 var offset = this.digitalMatrixHeight * 0.4; 542 var duration = this.digitalMatrixHeight * 0.7; 543 if(item.id == "layer1") { 544 duration = this.digitalMatrixHeight * 0.5; 545 } 546 if(item.id == "layer2" || item.id == "layer3") { 547 duration = this.digitalMatrixHeight * 0.4; // speed up mid layers to reduce visible offset 548 } 549 550 for (var property in item.mesh.material.uniforms) { 551 if (Object.hasOwnProperty.call(item.mesh.material.uniforms, property)) { 552 var variable = item.mesh.material.uniforms[property]; 553 554 if(typeof variable.start != "undefined" && typeof variable.end != "undefined") { 555 var tween; 556 557 if(property == "uOpacity" && item.id != "layer1") { 558 offset = this.digitalMatrixHeight * 0.6; 559 duration = this.digitalMatrixHeight * 0.35; // quicker fade to avoid lingering misalignment 560 } 561 var start = offset; 562 var end = duration; 563 564 if(property == "uZPosition") { 565 tween = gsap.fromTo(item.mesh.position, { z: variable.start }, { z: variable.end, scrollTrigger: { 566 trigger: '.digital-matrix', 567 start: () => "top+=" + start + " top", 568 end: () => "+=" + end, 569 scrub: true, 570 invalidateOnRefresh: true 571 } }); 572 } else { 573 tween = gsap.fromTo(item.mesh.material.uniforms[property], { value: variable.start }, { value: variable.end, scrollTrigger: { 574 trigger: '.digital-matrix', 575 start: () => "top+=" + start + " top", 576 end: () => "+=" + end, 577 scrub: true, 578 invalidateOnRefresh: true 579 } }); 580 } 581 582 this._trackScrollTrigger(tween.scrollTrigger); 583 } 584 } 585 } 586 } 587 // else if(item.id == "hardware") { 588 // item.mesh.material.uniforms.uZPosition.value = 50; 589 // console.log('uniforms',item.mesh.material.uniforms); 590 // } 591 592 } 593 594 Digital.prototype._loadImage = function(e, t) { 595 return new Promise((i,s)=>{ 596 e.complete ? (e.addEventListener("load", ()=>{ 597 this.textureOptions[t].image && (this.textureOptions[t].image.src = e.currentSrc, 598 this.textureOptions[t].needsUpdate = !0, 599 this._render()) 600 } 601 ), 602 i(e)) : e.onload = ()=>i(e), 603 e.onerror = s 604 } 605 ) 606 } 607 608 Digital.prototype._resizeMatrixVertices = function() { 609 var self = window.Digital; 610 let e = .5 * Math.max(self.stickyWidth, self.stickyHeight);
611 Object.keys(self.layers).map(function(t){ 612 let i = self.layers[t].mesh.geometry.getAttribute("position") 613 , s = i.array 614 , n = "hardware" !== t ? e * self.screenSize : e; 615 s[0] = -n, 616 s[1] = n, 617 s[3] = n, 618 s[4] = n, 619 s[6] = -n, 620 s[7] = -n, 621 s[9] = n, 622 s[10] = -n, 623 i.needsUpdate = !0 624 } 625 ) 626 } 627 Digital.prototype._updateMatrix = function() { 628 var self = window.Digital; 629 self.camera.fov = 2 * Math.atan(self.stickyHeight / 2 / self.perspective) * (180 / Math.PI), 630 self.camera.aspect = self.stickyWidth / self.stickyHeight, 631 self.camera.updateProjectionMatrix(), 632 self.renderer.setSize(self.stickyWidth, self.stickyHeight) 633 } 634 // Digital.prototype._updateScaleAnim = function() { 635 // this.sceneScaleAnim.overwriteProps({ 636 // uScale: [1, "(css(--scene-size) / ".concat(Math.max(this.stickyWidth, this.stickyHeight), ")")] 637 // }) 638 // } 639 Digital.prototype._render = function() { 640 if (this.isWebGLFallback || !this.renderer) { 641 return; 642 } 643 this.renderer.render(this.scene, this.camera) 644 } 645 // _destroy() {} 646 Digital.prototype.onResizeDebounced = function(e) { 647 if(window.THREE) { 648 var self = window.Digital || this; 649 650 self.stickyWidth = $(window).width(), 651 self.stickyHeight = $(window).height(); 652 653 // Fallback mode: rebuild only the simple ScrollTrigger animation. 654 if (self.isWebGLFallback) { 655 self._fallbackInitialized = !1; 656 self._initializeFallback({ reason: 'resize' }); 657 try { ScrollTrigger.refresh(); } catch (e) {} 658 return; 659 } 660 661 self.camera.aspect = self.stickyWidth / self.stickyHeight; 662 self.renderer.setSize(self.stickyWidth, self.stickyHeight); 663 // self._resizeMatrixVertices.bind(self)() 664 self._updateMatrix.bind(self)(); 665 666 var self = self; 667 self._killScrollTriggers(); 668 self.updateCachedHeight(); 669 Object.keys(self.layers).map(function(t){ 670 self._layerKeyframeMaker(self.layers[t]); 671 }); 672 self._sceneScaler(); 673 self._setupKeyframes(); 674 675 676 self._render(); 677 setTimeout(function() { 678 self._render(); 679 }, 1000); 680 } 681 682 } 683 // static IS_SUPPORTED() { 684 // return document.documentElement.classList.contains("enhanced") 685 // } 686 687 return Digital; 688}())(); 689 690 691 692function e(id, el) { 693 var functions = { 694 166: [function () { 695 "use strict"; 696 697 return { 698 material: { 699 fragmentShader: [e(173, el).bind(this)().frag, "\n\t\tvoid main() {\n\t\t\tvec4 color = texture2DGradEXT(uTexture, vUv, dFdx(vUv), dFdy(vUv));\n\t\t\tgl_FragColor = color;\n\t\t}\n\t"].join("\n"), 700 uniforms: { 701 uTexture: { 702 value: el.textureOptions.HARDWARE_TEXTURE 703 }, 704 uZPosition: { 705 name: "Z position", 706 value: 700, 707 start: 700, 708 end: 1.5 709 } 710 } 711 } 712 } 713 } 714 , { 715 173: 173 716 }], 717 167: [function () { 718 "use strict"; 719 720 return { 721 layers: { 722 // hardware: e(166, el).bind(this)(), 723 layer0: e(168, el).bind(this)(), 724 layer1: e(169, el).bind(this)(), 725 layer2: e(170, el).bind(this)(), 726 layer3: e(171, el).bind(this)(), 727 layer4: e(172, el).bind(this)() 728 }, 729 shaderConstants: e(173, el).bind(this)() 730 } 731 } 732 , { 733 166: 166, 734 168: 168, 735 169: 169, 736 170: 170, 737 171: 171, 738 172: 172, 739 173: 173 740 }], 741 168: [function () { 742 "use strict"; 743 744 return { 745 material: { 746 fragmentShader: [e(173, el).bind(this)().frag, "\n\t\tvoid main() {\n\t\t\tvec4 tex = texture2DGradEXT(uTexture, vUv, dFdx(vUv), dFdy(vUv));\n\t\t\tgl_FragColor = vec4(tex.rgb, tex.a * uOpacity);\n\t\t}\n\t"].join("\n"), 747 uniforms: { 748 uTexture: { 749 value: el.textureOptions.ENDFRAME_TEXTURE 750 }, 751 uZPosition: { 752 name: "Z position", 753 value: 300, 754 start: 300, 755 end: 1 756 }, 757 uOpacity: { 758 name: "Opacity", 759 value: 0, 760 start: 0, 761 end: 1 762 } 763 } 764 } 765 } 766 } 767 , { 768 173: 173 769 }], 770 169: [function () { 771 "use strict"; 772 773 return { 774 material: { 775 fragmentShader: [e(173, el).bind(this)().frag, "\n\t\tvoid main() {\n\t\t\tfloat N = uDotCount;\n\t\t\tvec2 center = vec2(0.5);\n\t\t\tvec2 dxy = vec2(1.0 / N);\n\t\t\tvec2 textureUv = (dxy * floor(vUv / dxy)) + (dxy * 0.5);\n\t\t\tvec2 pt = fract(vUv / dxy) - center;\n\n\t\t\tvec4 tex = texture2DGradEXT(uTexture, textureUv, dFdx(textureUv), dFdy(textureUv));\n\n\t\t\t// set base color of bordered squircle\n\t\t\tvec4 color = vec4(uStartColor, uOpacity);\n\n\t\t\t// bordered squircle\n\t\t\tcolor *= borderedSquircle(vec2(pt), vec2(uDotSize), uDotRadius, uDotThickness, 0.0);\n\n\t\t\t// glow\n\t\t\tcolor += tex * borderedSquircle(vec2(pt), vec2(uGlowSize), uGlowRadius, uGlowThickness, uGlowBlend);\n\n\t\t\tgl_FragColor = color * uOpacity;\n\t\t}\n\t"].join("\n"), 776 uniforms: { 777 uStartColor: { 778 value: new el.THREE.Color("#26a5ff") 779 }, 780 uTexture: { 781 value: el.textureOptions.POSTERFRAME_TEXTURE 782 }, 783 uDotCount: { 784 value: 104 * el.dotMultiple 785 }, 786 uDotSize: { 787 value: .26 788 }, 789 uDotRadius: { 790 value: .09 791 }, 792 uDotThickness: { 793 value: .09 794 }, 795 uGlowSize: { 796 value: .2 797 }, 798 uGlowRadius: { 799 value: .14 800 }, 801 uGlowThickness: { 802 value: .28 803 }, 804 uGlowBlend: { 805 value: .36 806 }, 807 uZPosition: { 808 value: 1, 809 start: 1, 810 end: 1 811 }, 812 uOpacity: { 813 value: 1, 814 start: 1, 815 end: 0 816 } 817 } 818 } 819 } 820 } 821 , { 822 173: 173 823 }], 824 170: [function () { 825 "use strict"; 826 827 return { 828 material: { 829 fragmentShader: [e(173, el).bind(this)().frag, "\n\t\tvoid main() {\n\t\t\tfloat N = uDotCount;\n\t\t\tvec2 center = vec2(0.5);\n\t\t\tvec2 dxy = vec2(1.0 / N);\n\t\t\tvec2 textureUv = (dxy * floor(vUv / dxy)) + (dxy * 0.5);\n\t\t\tvec2 pt = fract(vUv / dxy) - center;\n\n\t\t\tvec2 ipos = floor(textureUv);\n\t\t\tvec2 fpos = fract(textureUv);\n\t\t\tvec2 tile = randomSize(fpos, random(ipos));\n\t\t\tfloat variance = clamp(random(tile), 0.0, uVariance);\n\n\t\t\tvec4 color = texture2DGradEXT(uTexture, textureUv, dFdx(textureUv), dFdy(textureUv));\n\t\t\tcolor *= circle(vec2(pt), uDotSize, uDotBlend, variance);\n\n\t\t\tgl_FragColor = color * uOpacity;\n\t\t}\n\t"].join("\n"), 830 uniforms: { 831 uTexture: { 832 value: el.textureOptions.POSTERFRAME_TEXTURE 833 }, 834 uDotCount: { 835 value: 460 * el.dotMultiple 836 }, 837 uDotSize: { 838 value: .34 839 }, 840 uDotBlend: { 841 value: .1 842 }, 843 uVariance: { 844 value: .08 845 }, 846 uZPosition: { 847 value: 900, 848 start: 900, 849 end: 1 850 }, 851 uOpacity: { 852 value: 1, 853 start: 1, 854 end: 0 855 } 856 } 857 } 858 } 859 } 860 , { 861 173: 173 862 }], 863 171: [function () { 864 "use strict"; 865 866 return { 867 material: { 868 fragmentShader: [e(173, el).bind(this)().frag, "\n\t\tvoid main() {\n\t\t\tfloat N = uDotCount;\n\t\t\tvec2 center = vec2(0.5);\n\t\t\tvec2 dxy = vec2(1.0 / N);\n\t\t\tvec2 textureUv = (dxy * floor(vUv / dxy)) + (dxy * 0.5);\n\t\t\tvec2 pt = fract(vUv / dxy) - center;\n\n\t\t\tvec2 ipos = floor(textureUv);\n\t\t\tvec2 fpos = fract(textureUv);\n\t\t\tvec2 tile = randomSize(fpos, random(ipos));\n\t\t\tfloat variance = clamp(random(tile), 0.0, uVariance);\n\n\t\t\tvec4 color = texture2DGradEXT(uTexture, textureUv, dFdx(textureUv), dFdy(textureUv));\n\t\t\tcolor *= circle(vec2(pt), uDotSize, uDotBlend, variance);\n\n\t\t\tgl_FragColor = color * uOpacity;\n\t\t}\n\t"].join("\n"), 869 uniforms: { 870 uTexture: { 871 value: el.textureOptions.POSTERFRAME_TEXTURE 872 }, 873 uDotCount: { 874 value: 311 * el.dotMultiple 875 }, 876 uDotSize: { 877 value: .35 878 }, 879 uDotBlend: { 880 value: .08 881 }, 882 uVariance: { 883 value: .03 884 }, 885 uZPosition: { 886 value: 700, 887 start: 700, 888 end: 1 889 }, 890 uOpacity: { 891 value: 1, 892 start: 1, 893 end: 0 894 } 895 } 896 } 897 } 898 } 899 , { 900 173: 173 901 }], 902 172: [function () { 903 "use strict"; 904 905 return { 906 material: { 907 fragmentShader: [e(173, el).bind(this)().frag, "\n\t\tvoid main() {\n\t\t\tfloat N = uDotCount;\n\t\t\tvec2 center = vec2(0.5);\n\t\t\tvec2 dxy = vec2(1.0 / N);\n\t\t\tvec2 textureUv = (dxy * floor(vUv / dxy)) + (dxy * 0.5);\n\t\t\tvec2 pt = fract(vUv / dxy) - center;\n\n\t\t\tvec2 ipos = floor(textureUv);\n\t\t\tvec2 fpos = fract(textureUv);\n\t\t\tvec2 tile = randomSize(fpos, random(ipos));\n\t\t\tfloat variance = clamp(random(tile), 0.0, uVariance);\n\n\t\t\tvec4 color = texture2DGradEXT(uTexture, textureUv, dFdx(textureUv), dFdy(textureUv));\n\t\t\tcolor *= circle(vec2(pt), uDotSize, uDotBlend, variance);\n\n\t\t\tgl_FragColor = color * uOpacity;\n\t\t}\n\t"].join("\n"), 908 uniforms: { 909 uTexture: { 910 value: el.textureOptions.POSTERFRAME_TEXTURE 911 }, 912 uDotCount: { 913 value: 210 * el.dotMultiple 914 }, 915 uDotSize: { 916 value: .54 917 }, 918 uDotBlend: { 919 value: .49 920 }, 921 uVariance: { 922 value: 0 923 }, 924 uZPosition: { 925 value: 500, 926 start: 500, 927 end: 1 928 }, 929 uOpacity: { 930 value: 1, 931 start: 1, 932 end: 0 933 } 934 } 935 } 936 } 937 } 938 , { 939 173: 173 940 }], 941 173: [function () { 942 "use strict"; 943 return { 944 vert: "\n\t\tvarying vec2 vUv;\n\t\tvoid main() {\n\t\t\tvUv = uv;\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\t\t}\n\t", 945 frag: "\n\t\tuniform sampler2D uTexture;\n\t\tuniform vec3 uStartColor;
945\n\t\tuniform float uDotCount;\n\t\tuniform float uDotBlend;\n\t\tuniform float uDotSize;\n\t\tuniform float uOpacity;\n\t\tuniform float uVariance;\n\t\tuniform float uDotRadius;\n\t\tuniform float uDotThickness;\n\t\tuniform float uGlowSize;\n\t\tuniform float uGlowRadius;\n\t\tuniform float uGlowThickness;\n\t\tuniform float uGlowBlend;\n\n\t\tvarying vec2 vUv;\n\n\t\tfloat borderedSquircle(vec2 pos, vec2 size, float radius, float thickness, float blend) {\n\t\t\tfloat d = length(max(abs(pos), size) - size) - radius;\n\t\t\treturn smoothstep(0.55, 0.51 - blend, abs(d / thickness));\n\t\t}\n\n\t\tfloat random(in vec2 pt) {\n\t\t\treturn fract(sin(dot(pt.xy,vec2(12.9898,78.233)))*43758.5453123);\n\t\t}\n\n\t\tvec2 randomSize(in vec2 pt, in float i) {\n\t\t\ti = fract(i * 2.0);\n\n\t\t\tif (i > 0.5) { pt = vec2(1.0) - pt; }\n\t\t\telse { pt = vec2(1.0 - pt.x, pt.y); }\n\n\t\t\treturn pt;\n\t\t}\n\n\t\tfloat circle(vec2 pt, float size, float blend, float variance) {\n\t\t\tfloat len = length(pt);\n\t\t\tfloat result = 1.0 - smoothstep((size - variance) - blend, (size - variance), len);\n\n\t\t\treturn result;\n\t\t}\n\t" 946 } 947 } 948 , {}], 949 950 28: [function(e, t, i) { 951 return t in e ? Object.defineProperty(e, t, { 952 value: i, 953 enumerable: !0, 954 configurable: !0, 955 writable: !0 956 }) : e[t] = i, 957 e 958 } 959 , {}], 960 29: [function(e, t, i) { 961 return e && e.__esModule ? e : { 962 default: e 963 } 964 } 965 , {}], 966 } 967 968 return functions[id][0]; 969} 970 971 972 973var s = e(29)(e(28)); 974function n(e, t) { 975 // var s = []; 976 var i = Object.keys(e); 977 if (Object.getOwnPropertySymbols) { 978 var s = Object.getOwnPropertySymbols(e); 979 t && (s = s.filter((function(t) { 980 return Object.getOwnPropertyDescriptor(e, t).enumerable 981 } 982 ))), 983 i.push.apply(i, s) 984 } 985 return i 986} 987 988// what is this? 989function r(e) { 990 for (var t = 1; t < arguments.length; t++) { 991 var i = null != arguments[t] ? arguments[t] : {}; 992 t % 2 ? n(Object(i), !0).forEach((function(t) { 993 (0, 994 s.default)(e, t, i[t]) 995 } 996 )) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(i)) : n(Object(i)).forEach((function(t) { 997 Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(i, t)) 998 } 999 )) 1000 } 1001 return e 1002} 1003class Mesh { 1004 constructor(e) { 1005 this.id = e.id, 1006 this.el = e.el, 1007 this.THREE = e.THREE, 1008 this.material = e.material, 1009 this.stickyWidth = e.stickyWidth, 1010 this.stickyHeight = e.stickyHeight, 1011 this.matrixContainer = this.el.querySelector(".experience-display-matrix"), 1012 this.stickyOverflow = this.el.querySelector(".sticky-overflow"), 1013 // this.screenSize = parseFloat(getComputedStyle(this.matrixContainer).getPropertyValue("--screen-to-hardware-ratio")), 1014 this.screenSize = 1, 1015 // this.screenOffsetX = parseFloat(getComputedStyle(this.matrixContainer).getPropertyValue("--screen-offset-x")), 1016 // this.screenOffsetY = parseFloat(getComputedStyle(this.matrixContainer).getPropertyValue("--screen-offset-y")); 1017 this.screenOffsetX = 0, 1018 this.screenOffsetY = 0; 1019 this.mesh = this._createMesh(); 1020 } 1021 1022 _createMesh() { 1023 let t, i, s = new this.THREE.ShaderMaterial(r(r({}, this.material), {}, { 1024 vertexShader: e(173, this)().vert, 1025 opacity: 0, 1026 transparent: !0, 1027 blending: "hardware" === this.id ? this.THREE.NormalBlending : this.THREE.AdditiveBlending 1028 })); 1029 s.extensions.derivatives = !0, 1030 s.extensions.shaderTextureLOD = !0; 1031 let n = Math.max(this.stickyWidth, this.stickyHeight); 1032 switch (this.id) { 1033 case "hardware": 1034 t = new this.THREE.PlaneGeometry(n,n,1,1), 1035 i = new this.THREE.Mesh(t,s); 1036 break; 1037 case "layer0": 1038 // case "layer2": 1039 // case "layer3": 1040 case "layer4": 1041 // 1920, 1080 1042 // t = new this.THREE.PlaneGeometry(this.stickyWidth,this.stickyHeight,1,1); 1043 var width = this.stickyWidth; 1044 var height = this.stickyWidth / 16 * 9; 1045 t = new this.THREE.PlaneGeometry(width,height,1,1); 1046 i = new this.THREE.Mesh(t,s); 1047 i.position.x = this.screenOffsetX; 1048 i.position.y = this.screenOffsetY; 1049 break; 1050 default: 1051 t = new this.THREE.PlaneGeometry(n * this.screenSize,n * this.screenSize,1,1), 1052 i = new this.THREE.Mesh(t,s), 1053 i.position.x = this.screenOffsetX, 1054 i.position.y = this.screenOffsetY; 1055 break; 1056 } 1057 return i.position.z = s.uniforms.uZPosition.value, 1058 i 1059 } 1060}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.