1(() => { 2 'use strict'; 3 4 const root = document.querySelector('.kw-heritage'); 5 const gsap = window.gsap; 6 const ScrollTrigger = window.ScrollTrigger; 7 if (!root || !gsap || !ScrollTrigger) return; 8 9 const frame = root.querySelector('.kw-heritage__frame'); 10 const topLine = root.querySelector('.js-heritage-line-top'); 11 const bottomLine = root.querySelector('.js-heritage-line-bottom'); 12 const label = root.querySelector('.kw-heritage__label'); 13 const image = frame.querySelector('img'); 14 const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; 15 const scrollLength = reduceMotion ? 1.2 : 3.6; 16 17 const measure = () => { 18 const viewportWidth = window.innerWidth; 19 const viewportHeight = window.innerHeight; 20 const imageRatio = image.naturalWidth && image.naturalHeight 21 ? image.naturalWidth / image.naturalHeight 22 : 1400 / 780; 23 // SPã¯ç»åæ¬æ¥ã®æ¨ªé·æ¯çã§ã¯ãªãã2:3ã®ç¸¦é·ãã¬ã¼ã ã§åãæãã 24 // æ¡å¤§ä¸ãåããã¬ã¼ã æ¯çãä¿ã¤ãããè¨æ¸¬å¤èªä½ãåãæ¿ããã 25 const frameRatio = viewportWidth <= 768 ? 2 / 3 : imageRatio; 26 const baseHeight = viewportWidth / frameRatio; 27 const endScale = Math.max(1, viewportHeight / baseHeight); 28 const lineHeight = parseFloat(window.getComputedStyle(topLine).fontSize) * 0.5; 29 const startScale = lineHeight / baseHeight; 30 frame.style.width = `${viewportWidth}px`; 31 frame.style.height = `${baseHeight}px`; 32 return { baseHeight, endScale, startScale, lineHeight }; 33 }; 34 35 const render = (progress) => { 36 const { baseHeight, endScale, startScale, lineHeight } = measure(); 37 const clamp = (value, start, end) => Math.min(1, Math.max(0, (value - start) / (end - start))); 38 const zoomProgress = gsap.parseEase('power2.inOut')(clamp(progress, 0.10, 0.68)); 39 const scale = startScale * Math.pow(endScale / startScale, zoomProgress); 40 const imageHeight = baseHeight * scale; 41 // ç»åãæ¡å¤§ããéããä¸ä¸ã³ãã¼ã¨ã®éã«å¸¸æ20pxã®å¼å¸ãæ®ãã 42 const offset = Math.max(0, (imageHeight - lineHeight) / 2) + 20; 43 const lineOpacity = 1 - clamp(progress, 0.50, 0.66); 44 const labelOpacity = clamp(progress, 0.72, 0.85); 45 46 frame.style.transform = `translate(-50%, -50%) scale(${scale})`; 47 frame.style.opacity = String(clamp(progress, 0.10, 0.21)); 48 topLine.style.transform = `translateY(${-offset}px)`; 49 bottomLine.style.transform = `translateY(${offset}px)`; 50 topLine.style.opacity = String(lineOpacity); 51 bottomLine.style.opacity = String(lineOpacity); 52 label.style.opacity = String(labelOpacity); 53 label.style.transform = `translateY(${(1 - labelOpacity) * 14}px)`; 54 }; 55 56 root.style.height = `${(scrollLength + 1) * 100}svh`; 57 const trigger = ScrollTrigger.create({ 58 trigger: root, 59 start: 'top top', 60 end: () => `+=${window.innerHeight * scrollLength}`, 61 scrub: reduceMotion ? true : 0.6, 62 invalidateOnRefresh: true, 63 onUpdate: (self) => render(self.progress), 64 onRefresh: (self) => render(self.progress), 65 }); 66 67 image.addEventListener('load', () => ScrollTrigger.refresh(), { once: true }); 68 window.addEventListener('resize', () => ScrollTrigger.refresh(), { passive: true }); 69 render(0); 70})();
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.