ãã®èšäºã§ã¯ãããã€ãã®æ¬¡äžä»£Webãã¯ãããžãŒã䜿çšããŠConnectãèµ·åããæ¹æ³ã説æããããã³ããšã³ãã®æ ã®å°ããªæè¡ç詳现ãããã€ã説æããŸãã
CSSã°ãªããã¬ã€ã¢ãŠã
ä»å¹Žã®åãã3ã€ã®äž»èŠãªãã©ãŠã¶ãŒïŒFirefoxãChromeãããã³SafariïŒããæ°ããCSSã°ãªããã¬ã€ã¢ãŠãã¢ãžã¥ãŒã«ã®å®è£ ãã»ãŒåæã«å±éããŸããã ãããã®ä»æ§ã«ãããéçºè ã¯äœ¿ãããããéåžžã«åŒ·åãª2次å ãã¬ããããŒãã·ã¹ãã ãå©çšã§ããŸãã Connect ã©ã³ãã£ã³ã°ããŒãžã¯ã»ãŒãã¹ãŠã®CSSã°ãªããã«äŸåããŠãããããäžèŠããªãããŒãªèšèšäžã®æ±ºå®ãå®è£ ããã®ã¯ç°¡åã§ãã äŸãšããŠãããããŒã®ã³ã³ãã³ããé衚瀺ã«ããèæ¯ã«æ³šç®ããŸãããã

æŽå²çã«ã¯ã絶察é 眮ã䜿çšããŠãã®ãããªèæ¯ã¹ããªãããäœæããåã¹ãã©ã€ããããŒãžã«æ£ç¢ºã«é 眮ããŸããã ãã®æ¹æ³ã¯æ©èœããŸãããäœçœ®æ±ºããè匱ãªå Žåãå°ããªåé¡ãçºçããããšããããããŸããããšãã°ãäžžã誀差ã«ããããã³ãéã«1ãã¯ã»ã«ã®ã®ã£ãããçããå ŽåããããŸãã ãŸããã¹ã¿ã€ã«ã·ãŒãã¯æ¥éã«èšåŒµããããŸããŸãªç»é¢ãµã€ãºã§ã®èæ¯ã®éããèæ ®ããŠè¡šç€ºã¯ãšãªãããè€éã«ãªããããç¶æãé£ãããªããŸãã
CSSã°ãªããã¯ãããã®åé¡ã®ã»ãŒãã¹ãŠãä¿®æ£ããŸãã æè»ãªã°ãªãããå®çŸ©ããé©åãªã»ã«ã«ã¹ãã©ã€ããé 眮ããã ãã§ãã Firefoxã«ã¯ãã¬ã€ã¢ãŠãã®æ§é ãèŠèŠåãã䟿å©ãªã°ãªããã€ã³ã¹ãã¯ã¿ãŒããããŸãã ãããã©ã®ããã«èŠãããèŠãŠã¿ãŸãããïŒ

æ確ã«ããããã«ã3ã€ã®ã¹ãã©ã€ãã匷調衚瀺ããåŸæå¹æãåé€ããŸããã é©åãªCSSã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
header .stripes { display: grid; grid: repeat(5, 200px) / repeat(10, 1fr); } header .stripes :nth-child(1) { grid-column: span 3; } header .stripes :nth-child(2) { grid-area: 3 / span 3 / auto / -1; } header .stripes :nth-child(3) { grid-row: 4; grid-column: span 5; }
ãã®åŸãåã«
.stripes
ã³ã³ããå šäœãå€æããŠãåŸæå¹æãåŸãããšãã§ããŸãã

header .stripes { transform: skewY(-12deg); transform-origin: 0; }
ãããŠåºæ¥äžããïŒ CSSã°ãªããã¯ãäžé¢šå€ãã£ãæ§æãšå€ãã®æ°ããããããã£ãšå€ã䌎ããããäžèŠæãããå ŽåããããŸãããã¡ã³ã¿ã«ã¢ãã«ã¯å®éã«ã¯éåžžã«åçŽã§ãã Flexboxã«ç²ŸéããŠããå Žåã¯ã Box Alignmentã¢ãžã¥ãŒã«ãæ¢ã«ç¥ã£ãŠããŸããã€ãŸãã
justify-content
ã
align-items
ãªã©ã倧奜ããªäœ¿ãæ £ããããããã£ã䜿çšããããšãã§ã
align-items
ã
CSS 3D
ã©ã³ãã£ã³ã°ããŒãžã®ããããŒã«ã¯ãConnectãæ§æãããã«ãã£ã³ã°ãããã¯ã®èŠèŠçãªã¡ã¿ãã©ãŒã ãšããŠããã€ãã®ãã¥ãŒãã衚瀺ãããŸãã ãããã®ãã©ã€ã³ã°ãã¥ãŒãã¯ãã©ã³ãã ãªé床ïŒç¹å®ã®ç¯å²ïŒã§3Dã«å転ãã察å¿ãããµãŒãã§ã¹ãåçã«ç §ããåäžã®å æºã§ç §ããããŸãããããªïŒ cubes.mp4

ãããã®ãã¥ãŒãã¯ãJavaScriptã«ãã£ãŠçæããã³ã¢ãã¡ãŒã·ã§ã³åãããåçŽãªDOMèŠçŽ ã§ãã ãããã¯ãããã1ã€ã®HTML
template
確èªãããŸãïŒ
<!-- HTML --> <template id="cube-template"> <div class="cube"> <div class="shadow"></div> <div class="sides"> <div class="back"></div> <div class="top"></div> <div class="left"></div> <div class="front"></div> <div class="right"></div> <div class="bottom"></div> </div> </div> </template> // JavaScript const createCube = () => { const template = document.getElementById("cube-template"); const fragment = document.importNode(template.content, true); return fragment; };
è€éãªããšã¯äœããããŸããã ããã§ããããã®ããããªèŠçŽ ãšç©ºã®èŠçŽ ã3次å ã®åœ¢ã«ç°¡åã«å€ããããšãã§ããŸãã 3Då€æã®ãããã§ãé è¿æã®è¿œå ãšZ軞ã«æ²¿ã£ãåŽé¢ã®ç§»åãéåžžã«èªç¶ã«å®è¡ãããŸãã
.cube, .cube * { position: absolute; width: 100px; height: 100px } .sides { transform-style: preserve-3d; perspective: 600px } .front { transform: rotateY(0deg) translateZ(50px) } .back { transform: rotateY(-180deg) translateZ(50px) } .left { transform: rotateY(-90deg) translateZ(50px) } .right { transform: rotateY(90deg) translateZ(50px) } .top { transform: rotateX(90deg) translateZ(50px) } .bottom { transform: rotateX(-90deg) translateZ(50px) }
CSSã¯ã¿ã€ã«ãã¥ãŒããç°¡åã«ããŸããããã€ãããã¯ã·ã§ãŒãã£ã³ã°ãªã©ã®é«åºŠãªã¢ãã¡ãŒã·ã§ã³æ©èœãæäŸããŸããã 代ããã«ããã¥ãŒãã¢ãã¡ãŒã·ã§ã³ã¯
requestAnimationFrame
ã«äŸåããŠããããããã€ã³ãã§å蟺ãèšç®ããã³æŽæ°ããŸãã åãã¬ãŒã ã§ã¯ã次ã®3ã€ã®ããšãå®çŸ©ããå¿ èŠããããŸãã
- å¯èŠæ§ æ¯åã3é¢ä»¥äžãã衚瀺ãããªããããäžå¿ èŠãªèšç®ãé ããé¢ã§ã®ãªãœãŒã¹éçŽçãªåæç»ãåé¿ã§ããŸãã
- å€æ ç«æ¹äœã®å蟺ã¯ãåæå転ãã¢ãã¡ãŒã·ã§ã³ã®çŸåšã®ç¶æ ãããã³å軞ã«æ²¿ã£ãé床ã«å¿ããŠå€æããå¿ èŠããããŸãã
- ã·ã§ãŒãã£ã³ã° ã CSSã䜿çšãããšãèŠçŽ ã3次å 空éã«é 眮ã§ããŸããã3Dç°å¢ã®åŸæ¥ã®æŠå¿µïŒå æºãªã©ïŒã¯ãããŸããã 3Dç°å¢ãã·ãã¥ã¬ãŒãããããã«ãå æºãã¬ã³ããªã³ã°ããŠãç¹å®ã®ãã€ã³ãããé¢ããã«ã€ããŠãã¥ãŒãã®åŽé¢ãåŸã ã«æãããããšãã§ããŸãã
èæ ®ããå¿ èŠãããä»ã®èæ ®äºé ããããŸãïŒããšãã°ãJavaScriptã®
requestIdleCallback
ãšCSSã®
backface-visibility
ã䜿çšããŠããã©ãŒãã³ã¹ãæ¹åããïŒãããããã¯ã¢ãã¡ãŒã·ã§ã³ããžãã¯ã®äž»èŠãªåºç€ã§ãã
åãµã€ãã®å¯èŠæ§ãšå€æãèšç®ãããããã®ã¹ããŒã¿ã¹ãç¶ç¶çã«ç£èŠããç°¡åãªæ°åŠæŒç®ã䜿çšããŠæŽæ°ããŸãã çŽç²ãª ES2015æ©èœãšãã³ãã¬ãŒããªãã©ã«ãªã©ã®æ©èœã䜿çšãããšãããã«ç°¡åã«ãªããŸãã çŸåšã®å€æãèšç®ããã³æ±ºå®ããããã®JavaScriptã³ãŒãã®2ã€ã®çãã¹ããããã以äžã«ç€ºããŸãã
const getDistance = (state, rotate) => ["x", "y"].reduce((object, axis) => { object[axis] = Math.abs(state[axis] + rotate[axis]); return object; }, {}); const getRotation = (state, size, rotate) => { const axis = rotate.x ? "Z" : "Y"; const direction = rotate.x > 0 ? -1 : 1; return ` rotateX(${state.x + rotate.x}deg) rotate${axis}(${direction * (state.y + rotate.y)}deg) translateZ(${size / 2}px) `; };
ããºã«ã®æãé£ããéšåã¯ããã¥ãŒãã®åé¢ã®ã·ã§ãŒãã£ã³ã°ãæ£ããèšç®ããæ¹æ³ã§ãã ã¹ããŒãžã®äžå¿ã«ããä»®æ³å æºãã·ãã¥ã¬ãŒãããããã«ããã¹ãŠã®è»žã«æ²¿ã£ãŠãäžå¿ç¹ã«è¿ã¥ãã«ã€ããŠååŽé¢ã®ç §æå¹æãåŸã ã«å¢ããããšãã§ããŸãã å ·äœçã«ã¯ãããã¯ãåé¢ã®æãããšè²ãèšç®ããå¿ èŠãããããšãæå³ããŸãã åãã¬ãŒã ã§ãã®èšç®ãå®è¡ããããŒã¹ã«ã©ãŒãšçŸåšã®ã·ã§ãŒãã£ã³ã°ãã¡ã¯ã¿ãŒãè£éããŸãã
// Linear interpolation between a and b // Example: (100, 200, .5) = 150 const interpolate = (a, b, i) => a * (1 - i) + b * i; const getShading = (tint, rotate, distance) => { const darken = ["x", "y"].reduce((object, axis) => { const delta = distance[axis]; const ratio = delta / 180; object[axis] = delta > 180 ? Math.abs(2 - ratio) : ratio; return object; }, {}); if (rotate.x) darken.y = 0; else { const {x} = distance; if (x > 90 && x < 270) directions.forEach(axis => darken[axis] = 1 - darken[axis]); } const alpha = (darken.x + darken.y) / 2; const blend = (value, index) => Math.round(interpolate(value, tint.shading[index], alpha)); const [r, g, b] = tint.color.map(blend); return `rgb(${r}, ${g}, ${b})`; };
ãµãïŒ å¹žããªããšã«ãæ®ãã®ã³ãŒãã¯ã¯ããã«åçŽã§ãäž»ã«å®åã³ãŒããDOMãã«ããŒããã®ä»ã®åºæ¬çãªæœè±¡åã§æ§æãããŠããŸãã èšåãã䟡å€ã®ããæåŸã®è©³çŽ°ã¯ããŠãŒã¶ãŒã®èšå®ã«å¿ããŠãã¢ãã¡ãŒã·ã§ã³ã®éªéã«ãªããªããã¯ããã¯ã§ãã

ã¯ãªãã¯ããŠãããªãèŠã
macOSã§ã¯ãèšå®ã§[ ã¢ãŒã·ã§ã³ãæžãã]ã¢ãŒããæå¹ã«ãªã£ãŠããå Žåãæ°ããã¡ãã£ã¢ãªã¯ãšã¹ãã®
prefers-reduced-motion
ïŒãããŸã§ã¯Safariã®ã¿ïŒã®ããªã¬ãŒãããªã¬ãŒãããããŒãžäžã®ãã¹ãŠã®è£ 食ã¢ãã¡ãŒã·ã§ã³ããªãã«ãªããŸãã ãã¥ãŒãã¯ãã·ã§ãŒãã£ã³ã°ã«CSSã¢ãã¡ãŒã·ã§ã³ããå転ã«JavaScriptã¢ãã¡ãŒã·ã§ã³ãåæã«äœ¿çšããŸãã
@media
ããã¯ãš
MediaQueryList Interface
ãçµã¿åãããããšã«ããããããã®ã¢ãã¡ãŒã·ã§ã³ãç¡å¹ã«ã§ããŸãã
/* CSS */ @media (prefers-reduced-motion) { #header-hero * { animation: none } } // JavaScript const reduceMotion = matchMedia("(prefers-reduced-motion)").matches; const tick = () => { cubes.forEach(updateSides); if (reduceMotion) return; requestAnimationFrame(tick); };
ããå€ãã®CSS 3DïŒ
ãµã€ãå šäœã§ãStripeã®ã客æ§ãšæ¢åã®ã¢ããªã±ãŒã·ã§ã³ã®ã·ã§ãŒã±ãŒã¹ãšããŠãã«ã¹ã¿ã 3次å ã³ã³ãã¥ãŒã¿ãŒããã€ã¹ã䜿çšããŠããŸãã ãã¡ã€ã«ãµã€ãºãšããŠã³ããŒãæéãåæžãããšããç¡éã®æ¢æ±ã«ãããŠãå°ããªãã¡ã€ã«ãµã€ãºãšè§£å床ããç¬ç«ãã3次å ã®å€èŠ³ãå®çŸããæ¹æ³ã«ã€ããŠãããã€ãã®ãªãã·ã§ã³ãæ€èšããŸããã CSSã§ããã€ã¹ãçŽæ¥æç»ãããšãèŠä»¶ãæºãããŸããã CSSã©ãããããã¯æ¬¡ã®ãšããã§ãã

CSSã§ãªããžã§ã¯ããå®çŸ©ããããšã¯ãããããããããšã¯ã¹ããŒãããããã確ãã«äŸ¿å©ã§ã¯ãããŸããããããã ãã®äŸ¡å€ã¯ãããŸãã 2éã®ã©ãããããã¯1ãããã€ãæªæºã§æ§æãç°¡åã§ãã ããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ãè¿œå ããä»»æã®ããŒããã¢ãã¡ãŒã·ã§ã³åããç»è³ªãæãªãããšãªãã€ã³ã¿ã©ã¯ãã£ãã«ããã©ããããããã£ã¹ãã¬ã€ã«DOMèŠçŽ ïŒä»ã®ç»åãªã©ïŒãæ£ç¢ºã«é 眮ã§ããŸãã ãã®ãããªæè»æ§ã¯ãã¯ãªãŒã³ãªã³ãŒããæåŠããå¿ èŠãããããšãæå³ãããã®ã§ã¯ãããŸãããããŒã¯ã¢ããã¯ãã¯ãªãŒã³ã§ç°¡æœãã€æ確ãªãŸãŸã§ãã
<div class="laptop"> <span class="shadow"></span> <span class="lid"></span> <span class="camera"></span> <span class="screen"></span> <span class="chassis"> <span class="keyboard"></span> <span class="trackpad"></span> </span> </div>
ã©ãããããã®ã¹ã¿ã€ãªã³ã°ã«ã¯ãã°ã©ããŒã·ã§ã³ã圱ãå€åœ¢ãæ··åšããŠããŸãã å€ãã®ç¹ã§ãããã¯ãã°ã©ãã£ãã¯ããŒã«ã§ç¥ã£ãŠããŠäœ¿çšããŠããã¯ãŒã¯ãããŒãšæŠå¿µã®ç°¡åãªç¿»èš³ã§ãã ããšãã°ãè¡šçŽã®CSSã³ãŒãã¯æ¬¡ã®ãšããã§ãã
.laptop .lid { position: absolute; width: 100%; height: 100%; border-radius: 20px; background: linear-gradient(45deg, #E5EBF2, #F3F8FB); box-shadow: inset 1px -4px 6px rgba(145, 161, 181, .3) }
ä»äºã«é©ããããŒã«ãéžæããããšã¯å¿ ãããæããã§ã¯ãããŸãããCSSãSVGãCanvasãWebGLãç»åã®éžæã¯ãããã»ã©æ確ã§ã¯ãããŸããã CSSãæä»çãªããã¥ã¡ã³ããã¬ãŒã³ããŒã·ã§ã³åœ¢åŒãšããŠæŸæ£ããã®ã¯ç°¡åã§ããããããè¶ ããŠèŠèŠæ©èœã䜿ããããããšãç°¡åã§ãã ã©ã®ãã¯ãããžãŒãéžæããŠãããŠãŒã¶ãŒã«åãããŠæé©åããŠãã ããïŒ ãã®ãããå€ããã©ãŠã¶ã®ã¯ã©ã€ã¢ã³ãåŽã®ããã©ãŒãã³ã¹ãã¢ã¯ã»ã·ããªãã£ãããã³ããŒã«ããã¯ãªãã·ã§ã³ã«çŽ°å¿ã®æ³šæãæã£ãŠãã ããã
Web Animations API

Web Animations APIã¯ãJavaScriptã®
@keyframes
ããã©ãŒãã³ã¹ãšã·ã³ãã«ããæäŸããã¢ãã¡ãŒã·ã§ã³ãã¬ãŒã ã®ã¹ã ãŒãºãªã·ãŒã±ã³ã¹ãç°¡åã«äœæã§ããããã«ããŸãã äœã¬ãã«ã®
requestAnimationFrame
ã€ã³ã¿ãŒãã§ãŒã¹ãšã¯ç°ãªããããã§ã¯ã
cubic-bezier
ãšã¢ãªãšã³ãé¢æ°ã®ãã€ãã£ããµããŒããªã©ãCSSã¢ãã¡ãŒã·ã§ã³ã®ãã¹ãŠã®é åãåŸãããŸãã äŸãšããŠãããŒããŒããã¹ã©ã€ããããããã®ã³ãŒããèŠãŠãã ããã
const toggleKeyboard = (element, callback, action) => { const keyframes = { transform: [100, 0].map(n => `translateY(${n}%)`) }; const options = { duration: 800, fill: "forwards", easing: "cubic-bezier(.2, 1, .2, 1)", direction: action == "hide" ? "reverse" : "normal" }; const animation = element.animate(keyframes, options); animation.addEventListener("finish", callback, {once: true}); };
çŽ æµã§ç°¡åïŒ Webã¢ãã¡ãŒã·ã§ã³APIã¯ããµãŒãããŒãã£ã®äŸåé¢ä¿ãªãã§å¿ èŠãšãªãå¯èœæ§ã®ããå žåçãªãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã¢ãã¡ãŒã·ã§ã³ã®å€§éšåãã«ããŒããŸãïŒãã®çµæãExpressã¢ãã¡ãŒã·ã§ã³å šäœã¯ãã¹ã¯ãªãããç»åãªã©ãå«ãçŽ5 KBããããŸãïŒã ããã¯
requestAnimationFrame
å®å šãªä»£æ¿ã§ã¯ãããŸããããã¢ãã¡ãŒã·ã§ã³ãã¹ããªã³ã°ã«ãŒããç¬ç«ããå€æé¢æ°ãªã©ãä»ã®æ¹æ³ã§ã¯åŸãããªããšãã§ã¯ãããã埮åŠã«å¶åŸ¡ã§ããŸãã ã¢ãã¡ãŒã·ã§ã³ã«ã©ã®ãã¯ãããžãŒãéžæãã¹ããããããªãå Žåã¯ããããã次ã®åªå é äœã§ãªãã·ã§ã³ãé 眮ã§ããŸãã
- CSSãã©ã³ãžã·ã§ã³ ããã¯ãæãéããç°¡åã§ãæãå¹æçãªã¢ãã¡ãŒã·ã§ã³åæ¹æ³ã§ãã
hover
å¹æã®ãããªåçŽãªãã®ã«é©ããŠããŸãã - CSSã¢ãã¡ãŒã·ã§ã³ ã ãããã¯ããã©ã³ãžã·ã§ã³ãšåãããã©ãŒãã³ã¹ç¹æ§ãæã¡ãŸãããããã¯ããã©ãŠã¶ãŒã«ãã£ãŠé«åºŠã«æé©åãããåå¥ã®ã¹ã¬ããã§å®è¡ã§ãã宣èšåã¢ãã¡ãŒã·ã§ã³ã§ãã CSSã¢ãã¡ãŒã·ã§ã³ã¯é·ç§»ãããæ©èœçã§ãããè€æ°ã®ã¹ããããšè€æ°ã®å埩ãå¯èœã§ãã ãŸããååä»ã宣èš
@keyframes
ãšãå€ãã®å Žåæ瀺çãªanimation-fill-mode
ãå¿ èŠãšãããããå®è£ ãããå°é£animation-fill-mode
ã ïŒãããŠãååä»ãã®ãã®ã¯åžžã«ã³ã³ãã¥ãŒã¿ãŒãµã€ãšã³ã¹ã®æãé£ããéšåã§ããïŒïŒ - Webã¢ãã¡ãŒã·ã§ã³API ã ãã®ããã°ã©ãã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãCSSã¢ãã¡ãŒã·ã§ã³ãšã»ãŒåãããã©ãŒãã³ã¹ãæäŸããŸãïŒãããã®ã¢ãã¡ãŒã·ã§ã³ã¯åããšã³ãžã³ãå®è¡ããŸãããJavaScriptã³ãŒãã¯åŒãç¶ãã¡ã€ã³ã¹ã¬ããã§æ©èœããŸãïŒã ã€ã³ã¿ã©ã¯ãã£ãæ§ãã©ã³ãã å¹æãããã°ã©ã å¯èœãªã·ãŒã±ã³ã¹ãããã³çŽç²ã«å®£èšçãªã¢ãã¡ãŒã·ã§ã³ãããæ©èœçãªãã®ãå¿ èŠãšããã¢ãã¡ãŒã·ã§ã³ã®æåã®éžæè¢ã«ãªããŸãã
- requestAnimationFrame ã å®å®ã«ã¯å¢çã¯ãããŸããããå®å®è¹ã建ãŠãå¿ èŠããããŸãã ããã§ã¯å¯èœæ§ã¯ç¡éã§ãããã¬ã³ããªã³ã°æ¹æ³ã¯ç¡å¶éã§ãïŒHTMLãSVGããã£ã³ãã¹-äœã§ãïŒãããã®æè¡ã¯äœ¿çšããã®ãã¯ããã«é£ããã以åã®ãªãã·ã§ã³ãšåæ§ã«æ©èœããªãå¯èœæ§ããããŸãã
䜿çšãããã¯ããã¯ã«é¢ä¿ãªããã¢ãã¡ãŒã·ã§ã³ãããè¯ãèŠããããã«åžžã«äœ¿çšã§ããããã€ãã®ç°¡åãªãã³ãã以äžã«ç€ºããŸãã
- ã«ã¹ã¿ã ã«ãŒã ã
ease-in
ãease-out
ãlinear
ãªã©ã®çµã¿èŸŒã¿ã®timing-function
ã䜿çšããããšã¯ã»ãšãã©ãããŸããã ã«ã¹ã¿ã 3次ããžã§å€æ°ã®æ°ãã°ããŒãã«ã«æ±ºå®ãããšãæéãå€§å¹ ã«ç¯çŽã§ããŸã ã - ããã©ãŒãã³ã¹ ã ã¢ãã¡ãŒã·ã§ã³ã®é床ãèœãšããªãããã«ããŠãã ããã CSSã§ã¯ããã®ããã«ãå®äŸ¡ãªããããã£ïŒ
transform
ããã³opacity
ïŒã®ã¿ãã¢ãã¡ãŒã·ã§ã³åããå¯èœãªå Žåã¯GPUã§ã¢ãã¡ãŒã·ã§ã³ããªã»ããããŸãïŒwill-change
ã䜿çšïŒã - ã¹ããŒã ã ã¢ãã¡ãŒã·ã§ã³ãå¹²æžããããšã¯ãããŸããã ã¢ãã¡ãŒã·ã§ã³ã®äž»ãªã¿ã¹ã¯ã¯ãã€ã³ã¿ãŒãã§ã€ã¹ãã¬ã¹ãã³ã·ãã調åãå¿«é©ã§å®å šãªãã®ã«ããããšã§ãã ã¢ãã¡ãŒã·ã§ã³ã®ç¶ç¶æéã«å³å¯ãªå¶éã¯ãããŸããããšãã§ã¯ããšã«ãŒãã«äŸåããŸãããã»ãšãã©ã®å Žåã500ç§ãè¶ ããŠã¯ãªããŸããã
亀差ç¹ãªãã¶ãŒããŒ
Expressã¢ãã¡ãŒã·ã§ã³ã®åçã¯ããã£ãŒã«ãã«è¡šç€ºããããšããã«èªåçã«éå§ãããŸãïŒ ããŒãžãã¹ã¯ããŒã«ãããšããããäœéšã§ããŸã ïŒã éåžžãããã¯ããªã¬ãŒãšããŠæ©èœããã¹ã¯ããŒã«ã®ç£èŠã䌎ããŸãããæŽå²çã«ã¯ãªãœãŒã¹ãéäžçã«äœ¿çšããã€ãã³ããªã¹ããŒãä»ããŠå®è£ ãããŠãããããåé·ã§éå¹ççãªã³ãŒãã«ãªããŸããã
Connectã©ã³ãã£ã³ã°ããŒãžã¯ãæ°ããIntersection Observer APIã䜿çšããŸã ãããã¯ãèŠçŽ ã®å¯èŠæ§ãå€æããããã®ã¯ããã«ä¿¡é Œæ§ãé«ãçç£çãªæ¹æ³ãæäŸããŸãã Expressã¢ãã¡ãŒã·ã§ã³ã®åçãéå§ããæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
const observeScroll = (element, callback) => { const observer = new IntersectionObserver(([entry]) => { if (entry.intersectionRatio < 1) return; callback(); // Stop watching the element observer.disconnect(); },{ threshold: 1 }); // Start watching the element observer.observe(element); }; const element = document.getElementById("express-animation"); observeScroll(element, startAnimation);
observeScroll
observeScroll
ã¯ãã¡ã€ã³ã¹ã¬ããã§ã³ãŒããå®è¡ããããšãªããæ€åºãåçŽåããŸãïŒããšãã°ãèŠçŽ ãå®å šã«è¡šç€ºãããŠããå Žåãã³ãŒã«ããã¯ã¯1åã ãçæãããŸãïŒã Intersection Observer APIã®ãããã§ãå®å šã«ã¹ã ãŒãºãªWebããŒãžã«äžæ©è¿ã¥ããŸããïŒ
ããªãã£ã«ãšããã¯ããã¯
ãããã®ãŸã£ããæ°ããçŽ æŽããããœãããŠã§ã¢ã€ã³ã¿ãŒãã§ã€ã¹ã¯éåžžã«çŽ æŽããããã®ã§ãããæ®å¿µãªããããŸã ã©ãã§ãå©çšã§ããããã§ã¯ãããŸããã å žåçãªåé¿çã¯ãç¹å®ã®APIã®æ©èœã®ååšããã§ãã¯ãããã®APIãå©çšã§ããªãå Žåã«ã®ã¿å®è¡ãããããªãã£ã«ã®äœ¿çšã§ãã ãã®ã¢ãããŒãã®æãããªæ¬ ç¹ã¯ããã¹ãŠã®ãªãœãŒã¹ãåžžã«äœ¿çšãã䜿çšãããã©ããã«é¢ä¿ãªããå šå¡ãããªãã£ã«ãããŠã³ããŒãããããšã匷å¶ããããšã§ãã å¥ã®ãœãªã¥ãŒã·ã§ã³ãéžæããŸããã
JavaScript APIã®å Žåã Connectã©ã³ãã£ã³ã°ããŒãžã¯ããªãã£ã«ãå¿ èŠãã©ããããã¹ãããããªãã£ã«ãããŒãžã«åçã«ããŒãã§ããŸãã ã¹ã¯ãªããã¯åçã«äœæãããããã¥ã¡ã³ãã«è¿œå ãããŸããããã©ã«ãã§ã¯éåæã§ããã€ãŸããå®è¡é åºã¯ä¿èšŒãããŠããŸããã ãã®ã¹ã¯ãªããã¯äºæ³ãããããªãã£ã«ãããæ©ãå®è¡ãããå¯èœæ§ããããããæããã«ããã¯åé¡ã§ãã 幞ããªããšã«ãããã¯ã¹ã¯ãªãããéåæã§ã¯ãªããããå¿ èŠãªå Žåã«ã®ã¿é 延ããŒããããããšãæ瀺çã«ç€ºãããšã§ä¿®æ£ã§ããŸãã
const insert = name => { const el = document.createElement("script"); el.src = `${name}.js`; el.async = false; // Keep the execution order document.head.appendChild(el); }; const scripts = ["main"]; if (!Element.prototype.animate) scripts.unshift("web-animations-polyfill"); if (!("IntersectionObserver" in window)) scripts.unshift("intersection-observer-polyfill"); scripts.forEach(insert);
CSSã®å Žåãåé¡ãšè§£æ±ºçã¯JavaScriptããªãã£ã«ã®å Žåãšã»ãŒåãã§ãã ææ°ã®CSSæ©èœã䜿çšããäžè¬çãªæ¹æ³ã¯ãæåã«ããŒã«ããã¯ãèšè¿°ããå¯èœãªå Žåã¯ããããªãŒããŒã©ã€ãããããšã§ãã
div { display: flex } @supports (display: grid) { div { display: grid } }
CSSé¢æ°ã®èŠæ±ã¯åçŽã§ä¿¡é Œæ§ãé«ããããããæåã«äœ¿çšããå¿ èŠããããŸãã ãã ãã蚪åè ã®çŽ90ïŒ ãæ¢ã«ã°ãªããäºæãã©ãŠã¶ã䜿çšããŠããããããããã¯èŠèŽè ã«ã¯é©ããŠããŸããã ç§ãã¡ã®å Žåããã©ãŠã¶ã®ã·ã§ã¢ãå°ããããããã«ãæ°çŸã®ããŒã«ããã¯ã«ãŒã«ã䜿çšããŠå€§å€æ°ã®èšªåè ã«çœ°éãç§ãããšã¯æå³ããããŸããã ãããã®çµ±èšãèæ ®ããŠãå¿ èŠã«å¿ããŠãããŒã«ããã¯ä»ãã®ã¹ã¿ã€ã«ã·ãŒããåçã«äœæããã³æ¿å ¥ããããšãéžæããŸããã
// Some browsers not supporting Grid don't support CSS.supports // either, so we need to feature-test it the old-fashioned way: if (!("grid" in document.body.style)) { const fallback = "<link rel=stylesheet href=fallback.css>"; document.head.insertAdjacentHTML("beforeend", fallback); }
ãã£ããã·ã¥ïŒ
ãããã®ããã³ããšã³ãã®ãã³ããã楜ãã¿ãã ããïŒãããŠããã¶ãæ©æµãåããŸãïŒïŒ ææ°ã®ãã©ãŠã¶ã¯ããªããã§é«éã§é åçãªã€ã³ã¿ãŒãã§ã€ã¹ãäœæããããã®åŒ·åãªããŒã«ãæäŸããåµé åãçºæ®ããŸãã ããªããç§ãã¡ãšåãããã«æ©äŒã«é äºãããŠãããªããããããäžç·ã«å®éšãã¹ãã§ãã