"use strict"; var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; window.requestAnimationFrame = requestAnimationFrame; var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame; // 鑾峰彇鍏冪礌鍒版牴鍏冪礌鐨刼ffsetLeft/offsetTop function getElementTop(element) { var actualTop = element.offsetTop; var current = element.offsetParent; while (current !== null) { actualTop += current.offsetTop; current = current.offsetParent; } return actualTop; } function getElementLeft(element) { var actualLeft = element.offsetLeft; var current = element.offsetParent; while (current !== null) { actualLeft += current.offsetLeft; current = current.offsetParent; } return actualLeft; } var als = { init: false, bodyScroll: 0, calcScroll: 0, intScroll: 0, Ratio: 0.05, windowsHeight: 0, windowsWidth: 0, wrapper: "", // parallax data elements: [], elements_data: [], // sticky data sticky_elm: [], sticky_elm_data: [], // mouse data page_x: 0, page_y: 0, mouse_elm: [], mouse_elm_data: [], }; // wrapper function alsWrapper(elm, ratio) { als.wrapper = document.querySelector(elm); als.wrapper.classList.add("fixed-wrapper"); //add wrapper class if (ratio !== undefined) { als.Ratio = ratio; } als.init = true; setWrapper(); als_animation(); watchsize(); } // parallax function alsElments(elm, x, y, z, r, rx, ry, limit, friction) { als.elements.push({ elm: elm, x: x ? x : 0, y: y ? y : 0, z: z ? z : 0, r: r ? r : 0, rx: rx ? rx : 0, ry: ry ? ry : 0, limit: limit ? limit : 0, friction: friction ? friction : 1, }); set_elements(); } // sticky function alsSticky(elm, x, y, z, r, rx, ry, limit, friction) { als.sticky_elm.push({ elm: elm, x: x ? x : 0, y: y ? y : 0, z: z ? z : 0, r: r ? r : 0, rx: rx ? rx : 0, ry: ry ? ry : 0, limit: limit ? limit : 0, // limit: 0:no limit , 1:contain , 2:top , 3:bottom friction: friction ? friction : 1, }); set_sticky(); } // mouse function alsMouse(elm, x, y, z, r, rx, ry, limit, friction) { als.mouse_elm.push({ elm: elm, x: x ? x : 0, y: y ? y : 0, z: z ? z : 0, r: r ? r : 0, rx: rx ? rx : 0, ry: ry ? ry : 0, limit: limit ? limit : 0, // limit: 0:no limit , 1:parent , '50':suck by distence friction: friction ? friction : 0, }); set_mouse(); } // scroll wrapper function setWrapper() { var wrapperHeight = als.wrapper.clientHeight; document.body.style.height = wrapperHeight + "px"; als.windowsHeight = window.innerHeight; als.windowsWidth = window.innerWidth; } function getScroll() { als.bodyScroll = document.documentElement.scrollTop || document.body.scrollTop; } function wrapper_scroll() { als.calcScroll = als.calcScroll + (als.bodyScroll - als.calcScroll) * als.Ratio; als.intScroll = Math.round(als.calcScroll * 100) / 100; als.wrapper.style.transform = `translate3d(0px, ${-als.intScroll}px, 0px)`; } // parallax elements function set_elements() { als.elements_data.length = 0; for (let i = 0; i < als.elements.length; i++) { set_elements_data(als.elements[i]); } } function set_elements_data(elms) { let the_elms = document.querySelectorAll(elms.elm); for (let i = 0; i < the_elms.length; i++) { let offset_top = getElementTop(the_elms[i]); let the_elms_height = the_elms[i].clientHeight; let the_elms_width = the_elms[i].clientWidth; als.elements_data.push({ elm: the_elms[i], x: elms.x, y: elms.y, z: elms.z, r: elms.r, rx: elms.rx, ry: elms.ry, limit: elms.limit, friction: elms.friction, top: offset_top, height: the_elms_height, width: the_elms_width, center: 0, }); } } function scroll_parallax() { for (let i = 0; i < als.elements_data.length; i++) { let center_init = als.elements_data[i].top - als.windowsHeight / 2 + als.elements_data[i].height / 2 - als.intScroll; als.elements_data[i].center = als.elements_data[i].center + (center_init - als.elements_data[i].center) * als.elements_data[i].friction; let center = als.elements_data[i].center; // if no limit if (als.elements_data[i].limit == 0) { als.elements_data[i].elm.style.transform = `perspective(1000px) translate3d(${center * als.elements_data[i].x}px, ${center * als.elements_data[i].y}px, ${center * als.elements_data[i].z}px) rotate(${center * als.elements_data[i].r}deg) rotateX(${center * als.elements_data[i].rx}deg) rotateY(${center * als.elements_data[i].ry}deg)`; //set var als.elements_data[i].elm.style.setProperty("--center", center); } // if Stop at center point else if (als.elements_data[i].limit == 1) { if (center > 0) { als.elements_data[i].elm.style.transform = `perspective(1000px) translate3d(${center * als.elements_data[i].x}px, ${center * als.elements_data[i].y}px, ${center * als.elements_data[i].z}px) rotate(${center * als.elements_data[i].r}deg) rotateX(${center * als.elements_data[i].rx}deg) rotateY(${center * als.elements_data[i].ry}deg)`; //set var als.elements_data[i].elm.style.setProperty("--center", center); } else { als.elements_data[i].elm.style.transform = `perspective(1000px) translate3d(0px,0px,0px) rotate(0deg) rotateX(0deg) rotateY(0deg)`; //set var als.elements_data[i].elm.style.setProperty("--center", "0"); } } } } // sticky parallax function set_sticky() { als.sticky_elm_data.length = 0; for (let i = 0; i < als.sticky_elm.length; i++) { set_sticky_data(als.sticky_elm[i]); } } function set_sticky_data(elms) { let the_elms = document.querySelectorAll(elms.elm); for (let i = 0; i < the_elms.length; i++) { // let offset_top = the_elms[i].offsetTop; let offset_top = getElementTop(the_elms[i]); let parent_height = the_elms[i].parentElement.clientHeight; let parent_width = the_elms[i].parentElement.clientWidth; // let parent_offset_top = the_elms[i].parentElement.offsetTop; let parent_offset_top = getElementTop(the_elms[i].parentElement); let the_elms_height = the_elms[i].clientHeight; let the_elms_width = the_elms[i].clientWidth; als.sticky_elm_data.push({ elm: the_elms[i], x: elms.x, y: elms.y, z: elms.z, r: elms.r, rx: elms.rx, ry: elms.ry, limit: elms.limit, friction: elms.friction, top: offset_top, parent_top: parent_offset_top, parent_height: parent_height, parent_width: parent_width, height: the_elms_height, width: the_elms_width, progress: 0, progress_friction: 0, }); } } function sticky_parallax() { for (let i = 0; i < als.sticky_elm_data.length; i++) { // if no limit if (als.sticky_elm_data[i].limit == 0) { als.sticky_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(${als.intScroll * als.sticky_elm_data[i].x}px,${als.intScroll * als.sticky_elm_data[i].y}px,${als.intScroll * als.sticky_elm_data[i].z}px) rotate(${als.intScroll * als.sticky_elm_data[i].r}deg) rotateX(${als.intScroll * als.sticky_elm_data[i].rx}deg) rotateY(${als.intScroll * als.sticky_elm_data[i].ry}deg)`; //set var als.sticky_elm_data[i].progress = als.intScroll / (document.body.clientHeight - window.innerHeight); als.sticky_elm_data[i].progress_friction = als.sticky_elm_data[i].progress_friction + (als.sticky_elm_data[i].progress - als.sticky_elm_data[i].progress_friction) * als.sticky_elm_data[i].friction; als.sticky_elm_data[i].elm.style.setProperty("--progress", als.sticky_elm_data[i].progress_friction); } // if parent contain limit // progress : 琛岀▼鐨勭櫨鍒嗘瘮 // x杞村钩绉昏窛绂讳互鍏冪礌鍜岀埗鍏冪礌瀹藉害姣斿喅瀹 else if (als.sticky_elm_data[i].limit == 1) { let sticky_top = als.sticky_elm_data[i].parent_top - als.intScroll; let sticky_bottom = als.sticky_elm_data[i].parent_top + als.sticky_elm_data[i].parent_height - als.intScroll; let sticky_x = ((als.sticky_elm_data[i].parent_top - als.intScroll) / (als.sticky_elm_data[i].parent_height - als.sticky_elm_data[i].height)) * (als.sticky_elm_data[i].width - als.sticky_elm_data[i].parent_width); if (sticky_top < 0 && sticky_bottom > als.sticky_elm_data[i].height) { als.sticky_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(${sticky_x * als.sticky_elm_data[i].x}px,${sticky_top * als.sticky_elm_data[i].y}px,${sticky_top * als.sticky_elm_data[i].z}px) rotate(${sticky_top * als.sticky_elm_data[i].r}deg) rotateX(${sticky_top * als.sticky_elm_data[i].rx}deg) rotateY(${sticky_top * als.sticky_elm_data[i].ry}deg)`; als.sticky_elm_data[i].progress = -(als.sticky_elm_data[i].parent_top - als.intScroll) / (als.sticky_elm_data[i].parent_height - als.sticky_elm_data[i].height); } else if (sticky_top > 0) { als.sticky_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(0px,0px,0px) rotate(0deg) rotateX(0deg) rotateY(0deg)`; als.sticky_elm_data[i].progress = 0; } else { let bottom = -(als.sticky_elm_data[i].parent_height - als.sticky_elm_data[i].height); let left = -(als.sticky_elm_data[i].width - als.sticky_elm_data[i].parent_width); als.sticky_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(${left * als.sticky_elm_data[i].x}px,${bottom * als.sticky_elm_data[i].y}px,${bottom * als.sticky_elm_data[i].z}px) rotate(${bottom * als.sticky_elm_data[i].r}deg) rotateX(${bottom * als.sticky_elm_data[i].rx}deg) rotateY(${bottom * als.sticky_elm_data[i].ry}deg)`; als.sticky_elm_data[i].progress = 1; } //set var als.sticky_elm_data[i].progress_friction = als.sticky_elm_data[i].progress_friction + (als.sticky_elm_data[i].progress - als.sticky_elm_data[i].progress_friction) * als.sticky_elm_data[i].friction; als.sticky_elm_data[i].elm.style.setProperty("--progress", als.sticky_elm_data[i].progress_friction); } } } // mouse parallax function set_mouse() { als.mouse_elm_data.length = 0; for (let i = 0; i < als.mouse_elm.length; i++) { set_mouse_data(als.mouse_elm[i]); } } function set_mouse_data(elms) { let the_elms = document.querySelectorAll(elms.elm); for (let i = 0; i < the_elms.length; i++) { // let offset_top = the_elms[i].offsetTop; let offset_top = getElementTop(the_elms[i]); // let offset_left = the_elms[i].offsetLeft; let offset_left = getElementLeft(the_elms[i]); let parent_height = the_elms[i].parentElement.clientHeight; let parent_width = the_elms[i].parentElement.clientWidth; // let parent_offset_top = the_elms[i].parentElement.offsetTop; let parent_offset_top = getElementTop(the_elms[i].parentElement); // let parent_offset_left = the_elms[i].parentElement.offsetLeft; let parent_offset_left = getElementLeft(the_elms[i].parentElement); let the_elms_height = the_elms[i].clientHeight; let the_elms_width = the_elms[i].clientWidth; als.mouse_elm_data.push({ elm: the_elms[i], x: elms.x, y: elms.y, z: elms.z, r: elms.r, rx: elms.rx, ry: elms.ry, limit: elms.limit, top: offset_top, left: offset_left, parent_top: parent_offset_top, parent_left: parent_offset_left, parent_height: parent_height, parent_width: parent_width, height: the_elms_height, width: the_elms_width, trX: 0, trY: 0, friction: elms.friction, }); } } document.addEventListener("mousemove", function (e) { als.page_x = e.pageX; als.page_y = e.pageY; }); function mouse_parallax() { for (let i = 0; i < als.mouse_elm_data.length; i++) { // if no limit if (als.mouse_elm_data[i].limit == 0) { let center_x = als.page_x - (als.mouse_elm_data[i].left + als.mouse_elm_data[i].width / 2); let center_y = als.page_y - (als.mouse_elm_data[i].top + als.mouse_elm_data[i].height / 2); als.mouse_elm_data[i].trX = als.mouse_elm_data[i].trX + (center_x - als.mouse_elm_data[i].trX) * als.mouse_elm_data[i].friction; als.mouse_elm_data[i].trY = als.mouse_elm_data[i].trY + (center_y - als.mouse_elm_data[i].trY) * als.mouse_elm_data[i].friction; let math_X = Math.round(als.mouse_elm_data[i].trX * 100) / 100; let math_Y = Math.round(als.mouse_elm_data[i].trY * 100) / 100; als.mouse_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(${math_X * als.mouse_elm_data[i].x}px,${math_Y * als.mouse_elm_data[i].y}px,0px) rotate(${(math_X + math_Y) * als.mouse_elm_data[i].r}deg) rotateX(${math_X * als.mouse_elm_data[i].rx}deg) rotateY(${math_Y * als.mouse_elm_data[i].ry}deg)`; // set var als.mouse_elm_data[i].elm.style.setProperty("--mouseX", math_X); als.mouse_elm_data[i].elm.style.setProperty("--mouseY", math_Y); } // if parent contain limit else if (als.mouse_elm_data[i].limit == 1) { if (als.page_x > als.mouse_elm_data[i].parent_left && als.page_x < als.mouse_elm_data[i].parent_left + als.mouse_elm_data[i].parent_width && als.page_y > als.mouse_elm_data[i].parent_top && als.page_y < als.mouse_elm_data[i].parent_top + als.mouse_elm_data[i].parent_height) { let center_x = als.page_x - (als.mouse_elm_data[i].left + als.mouse_elm_data[i].width / 2); let center_y = als.page_y - (als.mouse_elm_data[i].top + als.mouse_elm_data[i].height / 2); als.mouse_elm_data[i].trX = als.mouse_elm_data[i].trX + (center_x - als.mouse_elm_data[i].trX) * als.mouse_elm_data[i].friction; als.mouse_elm_data[i].trY = als.mouse_elm_data[i].trY + (center_y - als.mouse_elm_data[i].trY) * als.mouse_elm_data[i].friction; let math_X = Math.round(als.mouse_elm_data[i].trX * 100) / 100; let math_Y = Math.round(als.mouse_elm_data[i].trY * 100) / 100; als.mouse_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(${math_X * als.mouse_elm_data[i].x}px,${math_Y * als.mouse_elm_data[i].y}px,0px) rotate(${(math_X + math_Y) * als.mouse_elm_data[i].r}deg) rotateX(${math_X * als.mouse_elm_data[i].rx}deg) rotateY(${math_Y * als.mouse_elm_data[i].ry}deg)`; // set var als.mouse_elm_data[i].elm.style.setProperty("--mouseX", math_X); als.mouse_elm_data[i].elm.style.setProperty("--mouseY", math_Y); } else { let center_x = 0; let center_y = 0; als.mouse_elm_data[i].trX = als.mouse_elm_data[i].trX + (center_x - als.mouse_elm_data[i].trX) * als.mouse_elm_data[i].friction; als.mouse_elm_data[i].trY = als.mouse_elm_data[i].trY + (center_y - als.mouse_elm_data[i].trY) * als.mouse_elm_data[i].friction; let math_X = Math.round(als.mouse_elm_data[i].trX * 100) / 100; let math_Y = Math.round(als.mouse_elm_data[i].trY * 100) / 100; als.mouse_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(${math_X * als.mouse_elm_data[i].x}px,${math_Y * als.mouse_elm_data[i].y}px,0px) rotate(${(math_X + math_Y) * als.mouse_elm_data[i].r}deg) rotateX(${math_X * als.mouse_elm_data[i].rx}deg) rotateY(${math_Y * als.mouse_elm_data[i].ry}deg)`; // set var als.mouse_elm_data[i].elm.style.setProperty("--mouseX", math_X); als.mouse_elm_data[i].elm.style.setProperty("--mouseY", math_Y); } } // if limited by Value 'px' else if (parseFloat(als.mouse_elm_data[i].limit) !== NaN) { let center_x = als.page_x - (als.mouse_elm_data[i].left + als.mouse_elm_data[i].width / 2); let center_y = als.page_y - (als.mouse_elm_data[i].top + als.mouse_elm_data[i].height / 2); if (Math.abs(center_x) < parseFloat(als.mouse_elm_data[i].limit) && Math.abs(center_y) < parseFloat(als.mouse_elm_data[i].limit)) { als.mouse_elm_data[i].trX = als.mouse_elm_data[i].trX + (center_x - als.mouse_elm_data[i].trX) * als.mouse_elm_data[i].friction; als.mouse_elm_data[i].trY = als.mouse_elm_data[i].trY + (center_y - als.mouse_elm_data[i].trY) * als.mouse_elm_data[i].friction; let math_X = Math.round(als.mouse_elm_data[i].trX * 100) / 100; let math_Y = Math.round(als.mouse_elm_data[i].trY * 100) / 100; als.mouse_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(${math_X * als.mouse_elm_data[i].x}px,${math_Y * als.mouse_elm_data[i].y}px,0px) rotate(${(math_X + math_Y) * als.mouse_elm_data[i].r}deg) rotateX(${math_X * als.mouse_elm_data[i].rx}deg) rotateY(${math_Y * als.mouse_elm_data[i].ry}deg)`; // set var als.mouse_elm_data[i].elm.style.setProperty("--mouseX", math_X); als.mouse_elm_data[i].elm.style.setProperty("--mouseY", math_Y); } else { als.mouse_elm_data[i].trX = als.mouse_elm_data[i].trX + (0 - als.mouse_elm_data[i].trX) * als.mouse_elm_data[i].friction; als.mouse_elm_data[i].trY = als.mouse_elm_data[i].trY + (0 - als.mouse_elm_data[i].trY) * als.mouse_elm_data[i].friction; let math_X = Math.round(als.mouse_elm_data[i].trX * 100) / 100; let math_Y = Math.round(als.mouse_elm_data[i].trY * 100) / 100; als.mouse_elm_data[i].elm.style.transform = `perspective(1000px) translate3d(${math_X * als.mouse_elm_data[i].x}px,${math_Y * als.mouse_elm_data[i].y}px,0px) rotate(${(math_X + math_Y) * als.mouse_elm_data[i].r}deg) rotateX(${math_X * als.mouse_elm_data[i].rx}deg) rotateY(${math_Y * als.mouse_elm_data[i].ry}deg)`; // set var als.mouse_elm_data[i].elm.style.setProperty("--mouseX", math_X); als.mouse_elm_data[i].elm.style.setProperty("--mouseY", math_Y); } } } } // run Animation function als_animation() { getScroll(); wrapper_scroll(); if (als.elements.length > 0) { scroll_parallax(); } if (als.sticky_elm_data.length > 0) { sticky_parallax(); } if (als.mouse_elm_data.length > 0) { mouse_parallax(); } requestAnimationFrame(als_animation); } function watchsize() { if (als.init) { setInterval(function () { if (document.body.clientHeight !== als.wrapper.clientHeight || als.windowsWidth !== window.innerWidth) { setWrapper(); set_elements(); set_sticky(); set_mouse(); console.log("Window Resized"); } }, 800); } }