{"__browser":{"device":"unknown_device","mobile":false,"name":"unknown browser","platform":"unknown_platform","version":"0"},"__constants":{},"__CPDATA":{"domain_iframe":"https://cdpn.io","environment":"production","host":"codepen.io","iframe_allow":"accelerometer; ambient-light-sensor; camera; display-capture; encrypted-media; geolocation; gyroscope; microphone; midi; payment; web-share; vr","iframe_sandbox":"allow-forms allow-modals allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation-by-user-activation allow-downloads allow-presentation"},"__cpedata":{"action":"show","controller":"live_fullpage"},"__user":{"anon":true,"base_url":"/anon/","current_team_id":0,"current_team_hashid":null,"hashid":"VoDkNZ","id":1,"itemType":"user","name":"Captain Anonymous","paid":false,"tier":0,"username":"anon","created_at":null,"email_verified":null,"collections_count":0,"collections_private_count":0,"followers_count":0,"followings_count":0,"pens_count":0,"pens_private_count":0,"projects_count":0,"projects_private_count":0},"__firebase":{"config":{"apiKey":"AIzaSyBgLAe7N_MdFpuVofMkcQLGwwhUu5tuxls","authDomain":"codepen-store-production.firebaseapp.com","databaseURL":"https://codepen-store-production.firebaseio.com","disabled":false,"projectId":"codepen-store-production"},"token":"eyJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJodHRwczovL2lkZW50aXR5dG9vbGtpdC5nb29nbGVhcGlzLmNvbS9nb29nbGUuaWRlbnRpdHkuaWRlbnRpdHl0b29sa2l0LnYxLklkZW50aXR5VG9vbGtpdCIsImNsYWltcyI6eyJvd25lcklkIjoiVm9Ea05aIiwiYWRtaW4iOmZhbHNlfSwiZXhwIjoxNjU2NTY4MDg5LCJpYXQiOjE2NTY1NjQ0ODksImlzcyI6ImZpcmViYXNlLWFkbWluc2RrLThva3lsQGNvZGVwZW4tc3RvcmUtcHJvZHVjdGlvbi5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInN1YiI6ImZpcmViYXNlLWFkbWluc2RrLThva3lsQGNvZGVwZW4tc3RvcmUtcHJvZHVjdGlvbi5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInVpZCI6IlZvRGtOWiJ9.xGKWMESCzOY5gGGcn8Q5WwUXBXOAaU1pPRKZlP-rSKfHduqqOdJmYCuYwGAdzaWP7SZgmDnwLgxIY4Kjdk4ytfY7KbFrMIt4N0xpIGQJNmg_fTqHTY_whSlpaFKFzvSRf1fVDS2Rr2LKSPH3R562qI62ELPL5s6rCp6ztUxtig0xJpM6LfKrvmYgICSSOF2uPiUtv2Oyi4mo42bMkvj4RtljQv_q8a7_vax0gdeRqd2D011vF3A9dCHZffIiyxn_cxSOi_BUxaUas38R4ehMkmkC16DZ-fqWuVBul1nC0U7wSWIx9h5wN5cc8sIFxTLaLDtS_31rhYn4JCd2tIdGQw"},"__graphql":{"data":{"sessionUser":{"id":"VoDkNZ","name":"Captain Anonymous","title":"Captain Anonymous","avatar80":"https://assets.codepen.io/t-1/user-default-avatar.jpg?fit=crop&format=auto&height=80&version=0&width=80","avatar512":"https://assets.codepen.io/t-1/user-default-avatar.jpg?fit=crop&format=auto&height=512&version=0&width=512","currentContext":{"id":"VoDkNZ","baseUrl":"/anon","title":"Captain Anonymous","name":"Captain Anonymous","avatar80":"https://assets.codepen.io/t-1/user-default-avatar.jpg?fit=crop&format=auto&height=80&version=0&width=80","avatar512":"https://assets.codepen.io/t-1/user-default-avatar.jpg?fit=crop&format=auto&height=512&version=0&width=512","username":"anon","contextType":"User","__typename":"User"},"currentTeamId":null,"baseUrl":"/anon","username":"anon","admin":false,"anon":true,"pro":false,"verified":false,"teams":[],"__typename":"User"}}},"__pay_stripe_public_key":"pk_live_2GndomDfiklqpSNQn8FrGuwZSMIMzha7DkLJqlYe7IR0ihKAlKdiHg68JJc5eVPt68rzAjzAAVXcUwjySHRCsgjQQ00gtRBUFNH","__pay_braintree_env":"production","__item":"{\"id\":41674664,\"user_id\":58281,\"html\":\"<header class=\\\"head\\\">\\n <a href=\\\"https:\\/\\/codepen.io\\/ReGGae\\/live\\/povjKxV\\\" target=\\\"_blank\\\" data-txt=\\\"fullscreen is best\\\">\\n <div>fullscreen is best<\\/div>\\n <\\/a>\\n <div>\\n <a href=\\\"https:\\/\\/twitter.com\\/Jesper_Landberg\\\" target=\\\"_blank\\\" data-txt=\\\"about\\\">\\n <div>about<\\/div>\\n <\\/a>\\n <a href=\\\"https:\\/\\/twitter.com\\/Jesper_Landberg\\\" target=\\\"_blank\\\" data-txt=\\\"contact\\\"> <div>contact<\\/div>\\n <\\/a>\\n <\\/div>\\n<\\/header>\\n\\n<div class=\\\"slider | js-drag-area\\\">\\n <div class=\\\"slider__inner | js-slider\\\">\\n <div class=\\\"slide | js-slide\\\">\\n <div class=\\\"slide__inner | js-slide__inner\\\">\\n <img class=\\\"js-slide__img\\\" src=\\\"http:\\/\\/s3-us-west-2.amazonaws.com\\/s.cdpn.io\\/58281\\/tex1.jpg\\\" alt=\\\"\\\" crossorigin=\\\"anonymous\\\" draggable=\\\"false\\\">\\n <\\/div>\\n <\\/div>\\n <div class=\\\"slide | js-slide\\\" style=\\\"left: 120%;\\\">\\n <div class=\\\"slide__inner | js-slide__inner\\\">\\n <img class=\\\"js-slide__img\\\" src=\\\"http:\\/\\/s3-us-west-2.amazonaws.com\\/s.cdpn.io\\/58281\\/tex2.jpg\\\" alt=\\\"\\\" crossorigin=\\\"anonymous\\\" draggable=\\\"false\\\">\\n <\\/div>\\n <\\/div>\\n <div class=\\\"slide | js-slide\\\" style=\\\"left: 240%;\\\">\\n <div class=\\\"slide__inner | js-slide__inner\\\">\\n <img class=\\\"js-slide__img\\\" src=\\\"http:\\/\\/s3-us-west-2.amazonaws.com\\/s.cdpn.io\\/58281\\/tex1.jpg\\\" alt=\\\"\\\" crossorigin=\\\"anonymous\\\" draggable=\\\"false\\\">\\n <\\/div>\\n <\\/div>\\n <div class=\\\"slide | js-slide\\\" style=\\\"left: 360%;\\\">\\n <div class=\\\"slide__inner | js-slide__inner\\\">\\n <img class=\\\"js-slide__img\\\" src=\\\"http:\\/\\/s3-us-west-2.amazonaws.com\\/s.cdpn.io\\/58281\\/tex2.jpg\\\" alt=\\\"\\\" crossorigin=\\\"anonymous\\\" draggable=\\\"false\\\">\\n <\\/div>\\n <\\/div>\\n <div class=\\\"slide | js-slide\\\" style=\\\"left: 480%;\\\">\\n <div class=\\\"slide__inner | js-slide__inner\\\">\\n <img class=\\\"js-slide__img\\\" src=\\\"http:\\/\\/s3-us-west-2.amazonaws.com\\/s.cdpn.io\\/58281\\/tex1.jpg\\\" alt=\\\"\\\"crossorigin=\\\"anonymous\\\" draggable=\\\"false\\\">\\n <\\/div>\\n <\\/div>\\n <div class=\\\"slide | js-slide\\\" style=\\\"left: 600%;\\\">\\n <div class=\\\"slide__inner | js-slide__inner\\\">\\n <img class=\\\"js-slide__img\\\" src=\\\"http:\\/\\/s3-us-west-2.amazonaws.com\\/s.cdpn.io\\/58281\\/tex2.jpg\\\" alt=\\\"\\\" crossorigin=\\\"anonymous\\\" draggable=\\\"false\\\">\\n <\\/div>\\n <\\/div>\\n <div class=\\\"slide | js-slide\\\" style=\\\"left: 720%;\\\">\\n <div class=\\\"slide__inner | js-slide__inner\\\">\\n <img class=\\\"js-slide__img\\\" src=\\\"https:\\/\\/s3-us-west-2.amazonaws.com\\/s.cdpn.io\\/58281\\/tex1.jpg\\\" alt=\\\"\\\" crossorigin=\\\"anonymous\\\" draggable=\\\"false\\\">\\n <\\/div>\\n <\\/div>\\n <div class=\\\"slide | js-slide\\\" style=\\\"left: 840%;\\\">\\n <div class=\\\"slide__inner | js-slide__inner\\\">\\n <img class=\\\"js-slide__img\\\" src=\\\"https:\\/\\/s3-us-west-2.amazonaws.com\\/s.cdpn.io\\/58281\\/tex2.jpg\\\" alt=\\\"\\\" crossorigin=\\\"anonymous\\\" draggable=\\\"false\\\">\\n <\\/div>\\n <\\/div>\\n <\\/div>\\n<\\/div>\\n\\n<div class=\\\"titles\\\">\\n <div class=\\\"titles__title titles__title--proxy\\\">Lorem ipsum<\\/div>\\n <div class=\\\"titles__list | js-titles\\\">\\n <div class=\\\"titles__title | js-title\\\">Moonrocket<\\/div>\\n <div class=\\\"titles__title | js-title\\\">Spaceman<\\/div>\\n <div class=\\\"titles__title | js-title\\\">Moonrocket<\\/div>\\n <div class=\\\"titles__title | js-title\\\">Spaceman<\\/div>\\n <div class=\\\"titles__title | js-title\\\">Moonrocket<\\/div>\\n <div class=\\\"titles__title | js-title\\\">Spaceman<\\/div>\\n <div class=\\\"titles__title | js-title\\\">Moonrocket<\\/div>\\n <div class=\\\"titles__title | js-title\\\">Spaceman<\\/div>\\n <div class=\\\"titles__title | js-title\\\">Moonrocket<\\/div>\\n <\\/div>\\n<\\/div>\\n \\n<div class=\\\"progress\\\">\\n <div class=\\\"progress__line | js-progress-line\\\"><\\/div>\\n <div class=\\\"progress__line | js-progress-line-2\\\"><\\/div>\\n<\\/div>\",\"css\":\"$easeOutExpo: cubic-bezier(0.190, 1.000, 0.220, 1.000);\\n\\nhtml, body{\\n height: 100%;\\n}\\n\\nbody{\\n position: relative;\\n overflow: hidden;\\n background-color: #111;\\n font-family: 'helvetica neue', sans-serif;\\n}\\n\\n* {\\n box-sizing: border-box;\\n padding: 0;\\n margin: 0;\\n}\\n\\n.head{\\n position: fixed;\\n top: 0;\\n left: 0;\\n width: 100%;\\n display: flex;\\n justify-content: space-between;\\n padding: 2vw 2.5vw;\\n pointer-events: none;\\n z-index: 1000;\\n \\n > div {\\n display: flex;\\n }\\n \\n a{\\n position: relative;\\n color: #fff;\\n text-decoration: none;\\n font-size: 1rem;\\n pointer-events: all;\\n overflow: hidden;\\n \\n div,\\n &:after{\\n transition: transform .85s $easeOutExpo;\\n }\\n \\n &:after{\\n content: attr(data-txt);\\n position: absolute;\\n top: 100%;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n color: pink;\\n }\\n \\n &:nth-child(2) {\\n margin-left: 2vw;\\n }\\n \\n &:hover{\\n \\n div,\\n &:after{\\n transform: translateY(-100%);\\n }\\n }\\n }\\n}\\n\\n.dom-gl{\\n position: fixed;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n pointer-events: none;\\n z-index: 1;\\n}\\n\\n.slider{\\n position: relative; \\n padding: 0 22.5vw;\\n display: flex;\\n align-items: center;\\n height: 100%;\\n user-select: none;\\n cursor: grab;\\n z-index: 2;\\n \\n &__inner{\\n display: flex;\\n position: relative;\\n }\\n}\\n\\n.slide{\\n overflow: hidden;\\n \\n &:first-child{\\n position: relative;\\n }\\n \\n &:not(:first-child) {\\n position: absolute;\\n top: 0;\\n height: 100%;\\n }\\n \\n &__inner{\\n position: relative;\\n overflow: hidden;\\n width: 55vw;\\n padding-top: 56.5%;\\n }\\n \\n img{\\n display: none;\\n \\n \\/*\\n height: 100%;\\n width: 140%;\\n position: absolute;\\n top: 0;\\n left: -20%;\\n object-fit: cover;\\n will-change: transform;\\n *\\/\\n }\\n}\\n\\n\\n.titles{\\n position: fixed;\\n top: 50%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n overflow: hidden;\\n pointer-events: none;\\n z-index: 3;\\n \\n &__list{\\n position: absolute;\\n top: 0;\\n left: 0;\\n }\\n \\n &__title{\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n font-size: 6vw;\\n font-weight: bold;\\n letter-spacing: -0.1vw;\\n color: #fff;\\n \\n &--proxy{\\n visibility: hidden;\\n }\\n }\\n}\\n\\n.progress{\\n position: fixed;\\n bottom: 0;\\n left: 0;\\n width: 100%;\\n height: 0.25rem;\\n overflow: hidden;\\n pointer-events: none;\\n \\n &__line{\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n transform: scaleX(0);\\n transform-origin: left;\\n background-color: #fff;\\n \\n &:nth-child(2) {\\n transform-origin: right;\\n }\\n }\\n}\",\"parent\":0,\"js\":\"const store = {\\n ww: window.innerWidth,\\n wh: window.innerHeight,\\n isDevice: navigator.userAgent.match(\\/Android\\/i)\\n || navigator.userAgent.match(\\/webOS\\/i)\\n || navigator.userAgent.match(\\/iPhone\\/i)\\n || navigator.userAgent.match(\\/iPad\\/i)\\n || navigator.userAgent.match(\\/iPod\\/i)\\n || navigator.userAgent.match(\\/BlackBerry\\/i)\\n || navigator.userAgent.match(\\/Windows Phone\\/i)\\n}\\n\\nclass Slider {\\n\\n constructor(el, opts = {}) {\\n this.bindAll()\\n\\n this.el = el\\n\\n this.opts = Object.assign({\\n speed: 2,\\n threshold: 50,\\n ease: 0.075\\n }, opts)\\n\\n this.ui = {\\n items: this.el.querySelectorAll('.js-slide'),\\n titles: document.querySelectorAll('.js-title'),\\n lines: document.querySelectorAll('.js-progress-line')\\n }\\n\\n this.state = {\\n target: 0,\\n current: 0,\\n currentRounded: 0,\\n y: 0,\\n on: {\\n x: 0,\\n y: 0\\n },\\n off: 0,\\n progress: 0,\\n diff: 0,\\n max: 0,\\n min: 0,\\n snap: {\\n points: []\\n },\\n flags: {\\n dragging: false\\n }\\n }\\n\\n this.items = []\\n \\n this.events = {\\n move: store.isDevice ? 'touchmove' : 'mousemove',\\n up: store.isDevice ? 'touchend' : 'mouseup',\\n down: store.isDevice ? 'touchstart' : 'mousedown'\\n }\\n \\n this.init()\\n }\\n \\n bindAll() {\\n ['onDown', 'onMove', 'onUp']\\n .forEach(fn => this[fn] = this[fn].bind(this))\\n }\\n\\n init() {\\n return gsap.utils.pipe(\\n this.setup(), \\n this.on()\\n )\\n }\\n\\n destroy() {\\n this.off()\\n this.state = null\\n this.items = null\\n this.opts = null\\n this.ui = null\\n }\\n\\n on() {\\n const { move, up, down } = this.events\\n \\n window.addEventListener(down, this.onDown)\\n window.addEventListener(move, this.onMove)\\n window.addEventListener(up, this.onUp)\\n }\\n\\n off() {\\n const { move, up, down } = this.events\\n \\n window.removeEventListener(down, this.onDown)\\n window.removeEventListener(move, this.onMove)\\n window.removeEventListener(up, this.onUp)\\n }\\n \\n setup() {\\n const { ww } = store\\n const state = this.state\\n const { items, titles } = this.ui\\n \\n const { \\n width: wrapWidth, \\n left: wrapDiff \\n } = this.el.getBoundingClientRect()\\n \\n \\/\\/ Set bounding\\n state.max = -(items[items.length - 1].getBoundingClientRect().right - wrapWidth - wrapDiff)\\n state.min = 0\\n \\n \\/\\/ Global timeline\\n this.tl = gsap.timeline({ \\n paused: true,\\n defaults: {\\n duration: 1,\\n ease: 'linear'\\n }\\n })\\n .fromTo('.js-progress-line-2', {\\n scaleX: 1\\n }, {\\n scaleX: 0,\\n duration: 0.5,\\n ease: 'power3'\\n }, 0)\\n .fromTo('.js-titles', {\\n yPercent: 0\\n }, {\\n yPercent: -(100 - (100 \\/ titles.length)),\\n }, 0)\\n .fromTo('.js-progress-line', {\\n scaleX: 0\\n }, {\\n scaleX: 1\\n }, 0)\\n \\n \\/\\/ Cache stuff\\n for (let i = 0; i < items.length; i++) {\\n const el = items[i]\\n const { left, right, width } = el.getBoundingClientRect()\\n \\n \\/\\/ Create webgl plane\\n const plane = new Plane()\\n plane.init(el)\\n \\n \\/\\/ Timeline that plays when visible\\n const tl = gsap.timeline({ paused: true })\\n .fromTo(plane.mat.uniforms.uScale, {\\n value: 0.65\\n }, {\\n value: 1,\\n duration: 1,\\n ease: 'linear'\\n })\\n\\n \\/\\/ Push to cache\\n this.items.push({\\n el, plane,\\n left, right, width,\\n min: left < ww ? (ww * 0.775) : -(ww * 0.225 - wrapWidth * 0.2),\\n max: left > ww ? state.max - (ww * 0.775) : state.max + (ww * 0.225 - wrapWidth * 0.2),\\n tl,\\n out: false\\n })\\n }\\n }\\n\\n calc() {\\n const state = this.state\\n state.current += (state.target - state.current) * this.opts.ease\\n state.currentRounded = Math.round(state.current * 100) \\/ 100\\n state.diff = (state.target - state.current) * 0.0005\\n state.progress = gsap.utils.wrap(0, 1, state.currentRounded \\/ state.max)\\n\\n this.tl && this.tl.progress(state.progress)\\n }\\n\\n render() {\\n this.calc()\\n this.transformItems()\\n }\\n\\n transformItems() {\\n const { flags } = this.state\\n\\n for (let i = 0; i < this.items.length; i++) {\\n const item = this.items[i]\\n const { translate, isVisible, progress } = this.isVisible(item)\\n \\n item.plane.updateX(translate)\\n item.plane.mat.uniforms.uVelo.value = this.state.diff\\n \\n if (!item.out && item.tl) {\\n item.tl.progress(progress)\\n }\\n\\n if (isVisible || flags.resize) {\\n item.out = false\\n } else if (!item.out) {\\n item.out = true\\n }\\n } \\n }\\n\\n isVisible({ left, right, width, min, max }) {\\n const { ww } = store\\n const { currentRounded } = this.state\\n const translate = gsap.utils.wrap(min, max, currentRounded) \\n const threshold = this.opts.threshold\\n const start = left + translate\\n const end = right + translate\\n const isVisible = start < (threshold + ww) && end > -threshold\\n const progress = gsap.utils.clamp(0, 1, 1 - (translate + left + width) \\/ (ww + width))\\n\\n return {\\n translate,\\n isVisible,\\n progress\\n }\\n }\\n\\n clampTarget() {\\n const state = this.state\\n \\n state.target = gsap.utils.clamp(state.max, 0, state.target)\\n }\\n \\n getPos({ changedTouches, clientX, clientY, target }) {\\n const x = changedTouches ? changedTouches[0].clientX : clientX\\n const y = changedTouches ? changedTouches[0].clientY : clientY\\n\\n return {\\n x, y, target\\n }\\n }\\n\\n onDown(e) {\\n const { x, y } = this.getPos(e)\\n const { flags, on } = this.state\\n \\n flags.dragging = true\\n on.x = x\\n on.y = y\\n }\\n\\n onUp() {\\n const state = this.state\\n \\n state.flags.dragging = false\\n state.off = state.target\\n }\\n\\n onMove(e) {\\n const { x, y } = this.getPos(e)\\n const state = this.state\\n \\n if (!state.flags.dragging) return\\n\\n const { off, on } = state\\n const moveX = x - on.x\\n const moveY = y - on.y\\n\\n if ((Math.abs(moveX) > Math.abs(moveY)) && e.cancelable) {\\n e.preventDefault()\\n e.stopPropagation()\\n }\\n\\n state.target = off + (moveX * this.opts.speed)\\n }\\n}\\n\\n\\/***\\/\\n\\/*** GL STUFF ****\\/\\n\\/***\\/\\n\\nconst backgroundCoverUv = `\\nvec2 backgroundCoverUv(vec2 screenSize, vec2 imageSize, vec2 uv) {\\n float screenRatio = screenSize.x \\/ screenSize.y;\\n float imageRatio = imageSize.x \\/ imageSize.y;\\n\\n vec2 newSize = screenRatio < imageRatio \\n ? vec2(imageSize.x * screenSize.y \\/ imageSize.y, screenSize.y)\\n : vec2(screenSize.x, imageSize.y * screenSize.x \\/ imageSize.x);\\n\\n vec2 newOffset = (screenRatio < imageRatio \\n ? vec2((newSize.x - screenSize.x) \\/ 2.0, 0.0) \\n : vec2(0.0, (newSize.y - screenSize.y) \\/ 2.0)) \\/ newSize;\\n\\n return uv * screenSize \\/ newSize + newOffset;\\n}\\n`\\n\\nconst vertexShader = `\\nprecision mediump float;\\n\\nuniform float uVelo;\\n\\nvarying vec2 vUv;\\n\\n#define M_PI 3.1415926535897932384626433832795\\n\\nvoid main(){\\n vec3 pos = position;\\n pos.x = pos.x + ((sin(uv.y * M_PI) * uVelo) * 0.125);\\n\\n vUv = uv;\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(pos,1.);\\n}\\n`\\n\\nconst fragmentShader = `\\nprecision mediump float;\\n\\n${backgroundCoverUv}\\n\\nuniform sampler2D uTexture;\\n\\nuniform vec2 uMeshSize;\\nuniform vec2 uImageSize;\\n\\nuniform float uVelo;\\nuniform float uScale;\\n\\nvarying vec2 vUv;\\n\\nvoid main() {\\n vec2 uv = vUv;\\n\\n vec2 texCenter = vec2(0.5);\\n vec2 texUv = backgroundCoverUv(uMeshSize, uImageSize, uv);\\n vec2 texScale = (texUv - texCenter) * uScale + texCenter;\\n vec4 texture = texture2D(uTexture, texScale);\\n\\n texScale.x += 0.15 * uVelo;\\n if(uv.x < 1.) texture.g = texture2D(uTexture, texScale).g;\\n\\n texScale.x += 0.10 * uVelo;\\n if(uv.x < 1.) texture.b = texture2D(uTexture, texScale).b;\\n\\n gl_FragColor = texture;\\n}\\n`\\n\\nconst loader = new THREE.TextureLoader()\\nloader.crossOrigin = 'anonymous'\\n\\nclass Gl {\\n \\n constructor() {\\n this.scene = new THREE.Scene()\\n \\n this.camera = new THREE.OrthographicCamera(\\n store.ww \\/ - 2, \\n store.ww \\/ 2, \\n store.wh \\/ 2, \\n store.wh \\/ - 2, \\n 1, \\n 10 \\n )\\n this.camera.lookAt(this.scene.position)\\n this.camera.position.z = 1\\n \\n this.renderer = new THREE.WebGLRenderer({\\n alpha: true,\\n antialias: true\\n })\\n this.renderer.setPixelRatio(1.5)\\n this.renderer.setSize(store.ww, store.wh)\\n this.renderer.setClearColor(0xffffff, 0)\\n \\n this.init()\\n }\\n \\n render() {\\n this.renderer.render(this.scene, this.camera)\\n }\\n \\n init() {\\n const domEl = this.renderer.domElement\\n domEl.classList.add('dom-gl') \\n document.body.appendChild(domEl)\\n }\\n}\\n\\nclass GlObject extends THREE.Object3D {\\n \\n init(el) {\\n this.el = el\\n \\n this.resize()\\n }\\n \\n resize() {\\n this.rect = this.el.getBoundingClientRect()\\n const { left, top, width, height } = this.rect\\n\\n this.pos = {\\n x: (left + (width \\/ 2)) - (store.ww \\/ 2),\\n y: (top + (height \\/ 2)) - (store.wh \\/ 2)\\n }\\n \\n this.position.y = this.pos.y\\n this.position.x = this.pos.x\\n \\n this.updateX()\\n }\\n \\n updateX(current) {\\n current && (this.position.x = current + this.pos.x)\\n }\\n}\\n\\nconst planeGeo = new THREE.PlaneBufferGeometry(1, 1, 32, 32)\\nconst planeMat = new THREE.ShaderMaterial({\\n transparent: true,\\n fragmentShader,\\n vertexShader\\n})\\n\\nclass Plane extends GlObject {\\n \\n init(el) {\\n super.init(el)\\n\\n this.geo = planeGeo\\n this.mat = planeMat.clone()\\n \\n this.mat.uniforms = {\\n uTime: { value: 0 },\\n uTexture: { value: 0 },\\n uMeshSize: { value: new THREE.Vector2(this.rect.width, this.rect.height) },\\n uImageSize: { value: new THREE.Vector2(0, 0) },\\n uScale: { value: 0.75 },\\n uVelo: { value: 0 }\\n }\\n\\n this.img = this.el.querySelector('img')\\n this.texture = loader.load(this.img.src, (texture) => {\\n texture.minFilter = THREE.LinearFilter\\n texture.generateMipmaps = false\\n \\n this.mat.uniforms.uTexture.value = texture\\n this.mat.uniforms.uImageSize.value = [this.img.naturalWidth, this.img.naturalHeight]\\n })\\n\\n this.mesh = new THREE.Mesh(this.geo, this.mat)\\n this.mesh.scale.set(this.rect.width, this.rect.height, 1)\\n this.add(this.mesh) \\n gl.scene.add(this)\\n }\\n}\\n\\n\\/***\\/\\n\\/*** INIT STUFF ****\\/\\n\\/***\\/\\n\\nconst gl = new Gl()\\nconst slider = new Slider(document.querySelector('.js-slider'))\\n\\nconst tick = () => {\\n gl.render()\\n slider.render()\\n}\\n\\ngsap.ticker.add(tick)\",\"html_pre_processor\":\"none\",\"css_pre_processor\":\"scss\",\"js_pre_processor\":\"babel\",\"html_classes\":\"\",\"css_starter\":\"normalize\",\"css_prefix_free\":null,\"css_external\":null,\"js_library\":null,\"js_modernizr\":null,\"js_external\":null,\"created_at\":\"2019-12-07T15:38:24.000Z\",\"updated_at\":\"2020-03-03T18:54:20.000Z\",\"session_hash\":\"c13451285d10e839f4c347a4ac853ac9\",\"title\":\"Infinite draggable webgl slider.\",\"description\":\"\",\"slug_hash\":\"povjKxV\",\"head\":\"\",\"private\":false,\"slug_hash_private\":\"e168b5fc416f464a8289946cb7669687\",\"has_animation\":true,\"css_pre_processor_lib\":\"\",\"checksum\":0,\"screenshot_uuid\":\"082e82b0-5f9b-4971-9215-c8c1b13fbd04\",\"team_id\":0,\"css_prefix\":\"autoprefixer\",\"template\":false,\"js_module\":null,\"deleted_at\":null,\"deleted_by_user_id\":null,\"hard_delete_at\":null,\"pen_hash\":null,\"hashid\":\"povjKxV\"}"}