CSSã¢ãŒã·ã§ã³ãã¹ã®åº§æšç³»å€æãšãã¹åº§æšå€æã®å æ¬çã¬ã€ãã§ããã®èœåãæå€§éã«åŒãåºããŸããããã¢ãã¡ãŒã·ã§ã³ã粟å¯ã«å¶åŸ¡ããé åçãªèŠèŠå¹æãçã¿åºãæ¹æ³ãåŠã³ãŸãã
CSSã¢ãŒã·ã§ã³ãã¹ã®åº§æšç³»å€æïŒãã¹åº§æšå€æã®è©³çŽ°è§£èª¬
CSSã¢ãŒã·ã§ã³ãã¹ã䜿çšãããšãæå®ãããã¹ã«æ²¿ã£ãŠHTMLèŠçŽ ãã¢ãã¡ãŒã·ã§ã³åã§ããwebã¢ãã¡ãŒã·ã§ã³ã®åµé çãªå¯èœæ§ãåºãããŸããããããã¢ãŒã·ã§ã³ãã¹ãçã«ãã¹ã¿ãŒããã«ã¯ããã®åºç€ãšãªã座æšç³»ãšãæã广ãåŸãããã«ãããã©ã®ããã«å€æããããçè§£ããå¿ èŠããããŸãããã®èšäºã§ã¯ããã¹åº§æšç³»å€æãšãã¹åº§æšå€æã«ã€ããŠå æ¬çã«è§£èª¬ããèŠäºã§ç²Ÿå¯ãªã¢ãã¡ãŒã·ã§ã³ãäœæããããã®ç¥èãæäŸããŸãã
CSSã¢ãŒã·ã§ã³ãã¹ããããã£ã®çè§£
座æšç³»å€æã«èžã¿èŸŒãåã«ãCSSã¢ãŒã·ã§ã³ãã¹ãå®çŸ©ããäž»èŠãªããããã£ãç°¡åã«èŠãŠã¿ãŸãããïŒ
motion-path: ãã®ããããã£ã¯ãèŠçŽ ãç§»åãããã¹ãå®çŸ©ããŸãã以äžã®ãããªæ§ã ãªå€ãåãå ¥ããŸãïŒurl(): ããã¥ã¡ã³ãå ãŸãã¯å€éšãã¡ã€ã«ã§å®çŸ©ãããSVGãã¹ãåç §ããŸãããããæãäžè¬çã§æè»ãªã¢ãããŒãã§ããpath(): ãã¹ããŒã¿ã³ãã³ãïŒäŸïŒM10 10 L 100 100ïŒã䜿çšããŠã€ã³ã©ã€ã³SVGãã¹ãå®çŸ©ããŸããgeometry-box: åºæ¬çãªå³åœ¢ïŒé·æ¹åœ¢ãåãæ¥åïŒãã¢ãŒã·ã§ã³ãã¹ãšããŠæå®ããŸããmotion-offset: ãã®ããããã£ã¯ãã¢ãŒã·ã§ã³ãã¹äžã®èŠçŽ ã®äœçœ®ã決å®ããŸããå€0%ã¯èŠçŽ ããã¹ã®å§ç¹ã«ã100%ã¯çµç¹ã«é 眮ããŸãã0%ãã100%ã®éã®å€ã¯ããã¹ã«æ²¿ã£ãŠèŠçŽ ãæ¯äŸçã«é 眮ããŸããmotion-rotation: ãã¹ã«æ²¿ã£ãŠç§»åããéã®èŠçŽ ã®å転ãå¶åŸ¡ããŸããautoïŒèŠçŽ ã®åãããã¹ã®æ¥ç·ã«åãããïŒãauto reverseïŒèŠçŽ ã®åããå察æ¹åã®æ¥ç·ã«åãããïŒããŸãã¯ç¹å®ã®è§åºŠå€ïŒäŸïŒ45degïŒãªã©ã®å€ãåãå ¥ããŸãã
ãã¹åº§æšç³»ïŒå¶åŸ¡ã®åºç€
é«åºŠãªã¢ãŒã·ã§ã³ãã¹æè¡ãè§£ãæŸã€éµã¯ããã¹èªäœã®åº§æšç³»ãçè§£ããããšã«ãããŸããSVGãã¹ããŒã¿ã䜿çšããããå€éšSVGãåç §ãããããŠãã¹ãå®çŸ©ãããšããã®ãã¹ã¯ç¬èªã®åº§æšç³»å ã§å®çŸ©ãããŸãããã®åº§æšç³»ã¯ãã¢ãã¡ãŒã·ã§ã³åãããHTMLèŠçŽ ãšã¯ç¬ç«ããŠããŸãã
次ã®ããã«å®çŸ©ãããSVGã®<path>èŠçŽ ãæ³åããŠã¿ãŠãã ããïŒ
<svg width="200" height="200">
<path id="myPath" d="M10 10 C 90 10, 90 90, 10 90" fill="none" stroke="black"/>
</svg>
ãã®äŸã§ã¯ããã¹ã¯200x200ã®SVGãã¥ãŒããŒãå
ã§å®çŸ©ãããŠããŸãã座æšM10 10ããã³C 90 10, 90 90, 10 90ã¯ããã®SVG座æšç³»ã«çžå¯Ÿçã§ãããã®ãã¹ã«æ²¿ã£ãŠã¢ãã¡ãŒã·ã§ã³åãããèŠçŽ ã¯ãæ¬è³ªçã«ãã®åº§æšç³»ã«ã€ããŠäœãç¥ããŸããã
課é¡ïŒèŠçŽ ã®åãããã¹ã«åããã
ã¢ãŒã·ã§ã³ãã¹ã§æãäžè¬çãªèª²é¡ã®1ã€ã¯ãèŠçŽ ã®åãããã¹ã®æ¥ç·ã«åãããããšã§ããããã©ã«ãã§ã¯ãèŠçŽ ãæ£ããå転ãããäžèªç¶ãŸãã¯æãŸãããªãã¢ãã¡ãŒã·ã§ã³å¹æã«ã€ãªããããšããããŸããããã§ã座æšç³»å€æã®çè§£ãéåžžã«éèŠã«ãªããŸãã
ãã¹åº§æšå€æïŒã®ã£ãããåãã
ãã¹åº§æšå€æã¯ãèŠçŽ ã®åº§æšç³»ããã¹ã®åº§æšç³»ã«äžèŽãããããã«å€æããããšãå«ã¿ãŸããããã«ãããèŠçŽ ã®åãããã¹ã®æ¹åãšæ£ããäžèŽããããšãä¿èšŒãããŸãã
ãã¹åº§æšå€æã«ã¯ãããã€ãã®ãã¯ããã¯ããããŸãã以äžã«ãã®äžéšã玹ä»ããŸãïŒ
1. `motion-rotation: auto`ãŸãã¯`motion-rotation: auto reverse`ã䜿çšãã
ããã¯æãç°¡åãªã¢ãããŒãã§ãããåºæ¬çãªã·ããªãªã§ã¯å€ãã®å Žåååã§ããautoå€ã¯ãèŠçŽ ã®åãããã¹ã®æ¥ç·ã«èªåçã«åããããããã©ãŠã¶ã«æç€ºããŸããauto reverseã¯èŠçŽ ãå察æ¹åã«åãããŸããããã¯ãèŠçŽ ã®èªç¶ãªåãããã¹ã«é©ããŠããå Žåã«ããŸãæ©èœããŸãã
äŸïŒ
.element {
motion-path: url(#myPath);
motion-rotation: auto;
animation: move 5s linear infinite;
}
@keyframes move {
to { motion-offset: 100%; }
}
èæ ®äºé ïŒ
- ãã®ã¢ãããŒãã¯ãèŠçŽ ã®ããã©ã«ãã®åããé©åã§ããããšãåæãšããŠããŸããèŠçŽ ãããã«å転ãããå¿ èŠãããå Žåã¯ã远å ã®transformã䜿çšããå¿ èŠããããŸãã
- ãã©ãŠã¶ã¯åº§æšå€æãæé»çã«åŠçããŸãã
2. CSSã®`transform`ããããã£ãé©çšãã
ãã粟å¯ãªå¶åŸ¡ã®ããã«ãCSSã®`transform`ããããã£ã䜿çšããŠèŠçŽ ã®å転ãæåã§èª¿æŽã§ããŸããããã«ãããèŠçŽ ã®èªç¶ãªåããšç®çã®ãã¹ã®é 眮ãšã®éã®ãªãã»ãããè£æ£ã§ããŸãã
äŸïŒ
.element {
motion-path: url(#myPath);
motion-rotation: auto;
transform: rotate(90deg); /* èŠçŽ ã90床å転ããã */
animation: move 5s linear infinite;
}
@keyframes move {
to { motion-offset: 100%; }
}
ãã®äŸã§ã¯ã`transform: rotate(90deg)`ã䜿çšããŠèŠçŽ ã90床å転ãããŸãããããã«ãããèŠçŽ ãç§»åããéã«ãã¹ãšæ£ããæŽåããããšãä¿èšŒãããŸãã
èæ ®äºé ïŒ
- `transform`ããããã£ã¯ã`motion-rotation: auto`ã«ãã£ãŠæäŸãããèªåå転ã«å ããŠé©çšãããŸãã
- ç®çã®é 眮ãå®çŸããããã«ãããŸããŸãªå転è§åºŠã詊ããŠã¿ãŠãã ããã
3. é«åºŠãªåº§æšå€æã«JavaScriptã䜿çšãã
è€éãªã·ããªãªããèŠçŽ ã®åããéåžžã«ç²Ÿå¯ã«å¶åŸ¡ããå¿ èŠãããå Žåã¯ãJavaScriptã䜿çšããŠåº§æšå€æãå®è¡ã§ããŸããããã«ã¯ãåç¹ã§ã®ãã¹ã®æ¥ç·ãããã°ã©ã ã§èšç®ããèŠçŽ ã«é©åãªå転transformãé©çšããããšãå«ãŸããŸãã
é¢é£ããã¹ãããïŒ
- ãã¹ã®é·ããååŸããïŒ SVGãã¹èŠçŽ ã®`getTotalLength()`ã¡ãœããã䜿çšããŠããã¹ã®å šé·ã決å®ããŸãã
- ãã¹äžã®ç¹ãèšç®ããïŒ `getPointAtLength()`ã¡ãœããã䜿çšããŠããã¹äžã®ç¹å®ã®è·é¢ã«ããç¹ã®åº§æšãååŸããŸãã
- æ¥ç·ãèšç®ããïŒ ãã¹äžã®2ã€ã®é£æ¥ããç¹ã®å·®ãèŠã€ããããšã§ãåç¹ã§ã®æ¥ç·ãã¯ãã«ãèšç®ããŸãã
- è§åºŠãèšç®ããïŒ `Math.atan2()`ã䜿çšããŠãæ¥ç·ãã¯ãã«ã®è§åºŠãã©ãžã¢ã³ã§èšç®ããŸãã
- å転transformãé©çšããïŒ èšç®ãããè§åºŠã䜿çšããŠãèŠçŽ ã«`rotate()` transformãé©çšããŸãã
äŸïŒåèïŒïŒ
const path = document.getElementById('myPath');
const element = document.querySelector('.element');
const pathLength = path.getTotalLength();
function updateElementPosition(progress) {
const point = path.getPointAtLength(progress * pathLength);
const tangentPoint = path.getPointAtLength(Math.min((progress + 0.01) * pathLength, pathLength)); // å°ãå
ã®ç¹ãååŸ
const angle = Math.atan2(tangentPoint.y - point.y, tangentPoint.x - point.x) * 180 / Math.PI;
element.style.transform = `translate(${point.x}px, ${point.y}px) rotate(${angle}deg)`;
}
// requestAnimationFrameã䜿çšããŠèŠçŽ ã®äœçœ®ãã¹ã ãŒãºã«æŽæ°
let animationProgress = 0;
function animate() {
animationProgress += 0.01; // ã¢ãã¡ãŒã·ã§ã³é床ã調æŽ
if (animationProgress > 1) animationProgress = 0;
updateElementPosition(animationProgress);
requestAnimationFrame(animate);
}
animate();
èæ ®äºé ïŒ
- ãã®ã¢ãããŒãã¯æã粟å¯ãªå¶åŸ¡ãæäŸããŸãããJavaScriptããã°ã©ãã³ã°ãå¿ èŠã§ãã
- CSSã®`motion-rotation: auto`ã`transform`ã䜿çšãããããèšç®ã³ã¹ããé«ããªããŸãã
- ç¹ã«è€éãªãã¹ãã¢ãã¡ãŒã·ã§ã³ã®å Žåãããã©ãŒãã³ã¹ãžã®åœ±é¿ãæå°éã«æããããã«ã³ãŒããæé©åããŠãã ããã
å®è·µäŸïŒã¢ãŒã·ã§ã³ãã¹ã®ã°ããŒãã«ãªå¿çš
CSSã¢ãŒã·ã§ã³ãã¹ã¯ãèŠèŠçã«é åçã§åŒã蟌ãŸããæ§ã ãªã¢ãã¡ãŒã·ã§ã³ãäœæããããã«äœ¿çšã§ããŸãã以äžã«ããã€ãã®äŸãæããŸãïŒ
- ã€ã³ã¿ã©ã¯ãã£ããªè£œåãã¢ãŒïŒ ã¢ãã¡ãŒã·ã§ã³åãããèŠçŽ ã§äž»èŠãªé åã匷調ãããŠãŒã¶ãŒã補åã®æ©èœå šäœã«ããã£ãŠæ¡å ããŸããããã¯ãäžçäžã®eã³ããŒã¹ãµã€ãã§è£œåã玹ä»ããããã«äœ¿çšã§ããŸãã
- ã¢ãã¡ãŒã·ã§ã³åãããã€ã³ãã©ã°ã©ãã£ãã¯ïŒ ã¢ãã¡ãŒã·ã§ã³åããããã£ãŒããã°ã©ãã§ãããŒã¿ãé åçãã€èŠèŠçã«åŒãèŸŒãæ¹æ³ã§æç€ºããŸããæé·ãè¡°éã瀺ãã¢ãã¡ãŒã·ã§ã³åãããç·ã§äžçã®çµæžååã瀺ãã€ã³ãã©ã°ã©ãã£ãã¯ãæ³åããŠã¿ãŠãã ããã
- ãã€ãããã¯ãªããŽïŒ ãŠãŒã¶ãŒã®æäœã«å¿çããããæéãšãšãã«å€åãããããã¢ãã¡ãŒã·ã§ã³ããŽãäœæããŸããäŒæ¥ã®æé·æŠç¥ã衚ããã¹ã«æ²¿ã£ãŠå€åœ¢ããäŒæ¥ããŽã¯ãåœéçãªèŠèŽè ã«ã¢ããŒã«ããŸãã
- ã¹ã¯ããŒã«ã¢ãã¡ãŒã·ã§ã³ïŒ ãŠãŒã¶ãŒãããŒãžãäžã«ã¹ã¯ããŒã«ããã«ã€ããŠã¢ãã¡ãŒã·ã§ã³ãããªã¬ãŒããããæ²¡å ¥æã®ããã€ã³ã¿ã©ã¯ãã£ããªäœéšãåµåºããŸããäŸãã°ãäžçäžã®ããŸããŸãªéœåžã玹ä»ãããŠã§ããµã€ãã§ããŠãŒã¶ãŒãã¹ã¯ããŒã«ããããšã«åéœåžã®æ å ±ãã¹ã©ã€ãã€ã³ããããã«ã§ããŸãã
- ã²ãŒã éçºïŒ ã¢ãŒã·ã§ã³ãã¹ã䜿çšããŠã²ãŒã ã®ãã£ã©ã¯ã¿ãŒããªããžã§ã¯ãã®åããå¶åŸ¡ãããããã€ãããã¯ã§é åçãªã²ãŒã ãã¬ã€ãäœæããŸããããã¯äžçäžã®ã²ãŒã éçºè ã«é©çšãããŸãã
ããã©ãŒãã³ã¹ã«é¢ããèæ ®äºé
CSSã¢ãŒã·ã§ã³ãã¹ã¯å€ãã®å©ç¹ãæäŸããŸããããã®ããã©ãŒãã³ã¹ãžã®åœ±é¿ãèæ ®ããããšãéèŠã§ããè€éãªãã¹ãé »ç¹ãªæŽæ°ã¯ãç¹ã«ã¢ãã€ã«ããã€ã¹ã«ãããŠãã©ãŠã¶ã®ã¬ã³ããªã³ã°ããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã
ã¢ãŒã·ã§ã³ãã¹ã®ããã©ãŒãã³ã¹ãæé©åããããã®ãã³ããããã€ã玹ä»ããŸãïŒ
- ãã¹ãåçŽåããïŒ ç®çã®èŠèŠå¹æãéæããæãåçŽãªãã¹ããŒã¿ã䜿çšããŸããããžã§æ²ç·ã®å¶åŸ¡ç¹ã®æ°ãæžãããŸãã
- ããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ã䜿çšããïŒ ã¢ãã¡ãŒã·ã§ã³åãããèŠçŽ ã«`transform: translateZ(0);`ã¹ã¿ã€ã«ãé©çšããŠãããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ãæå¹ã«ãªã£ãŠããããšã確èªããŸããããã«ããããã©ãŠã¶ã¯ã¬ã³ããªã³ã°ã«GPUã䜿çšããããã«ãªããããã©ãŒãã³ã¹ãåäžããå¯èœæ§ããããŸãã
- æŽæ°ããããŠã³ã¹ãŸãã¯ã¹ãããã«ããïŒ JavaScriptã䜿çšããŠèŠçŽ ã®äœçœ®ãæŽæ°ããŠããå Žåã¯ãæŽæ°ããããŠã³ã¹ãŸãã¯ã¹ãããã«ããŠãèšç®ãšã¬ã³ããªã³ã°ã®é »åºŠãæžãããŸãã
- ç°ãªãããã€ã¹ã§ãã¹ãããïŒ æé©ãªããã©ãŒãã³ã¹ã確ä¿ããããã«ãããŸããŸãªããã€ã¹ããã©ãŠã¶ã§ã¢ãã¡ãŒã·ã§ã³ã培åºçã«ãã¹ãããŸãã
ã¢ã¯ã»ã·ããªãã£ã«é¢ããèæ ®äºé
CSSã¢ãŒã·ã§ã³ãã¹ã䜿çšããéã¯ãéãããæã€ãŠãŒã¶ãŒãå«ãã誰ããã¢ãã¡ãŒã·ã§ã³ãå©çšã§ããããã«ã¢ã¯ã»ã·ããªãã£ãèæ ®ããããšãäžå¯æ¬ ã§ãã
以äžã«ãã¢ã¯ã»ã·ããªãã£ã«é¢ãããã¹ããã©ã¯ãã£ã¹ãããã€ã玹ä»ããŸãïŒ
- ä»£æ¿ææ®µãæäŸããïŒ ã¢ãã¡ãŒã·ã§ã³ã§æç€ºãããæ å ±ã«ã¢ã¯ã»ã¹ããããã®ä»£æ¿æ¹æ³ãæäŸããŸããäŸãã°ãã¢ãã¡ãŒã·ã§ã³ã®å 容ãããã¹ãã§èª¬æããŸãã
- é床ãªã¢ãã¡ãŒã·ã§ã³ãé¿ããïŒ é床ãªã¢ãã¡ãŒã·ã§ã³ã¯äžéšã®ãŠãŒã¶ãŒã«ãšã£ãŠæ³šææ£æŒ«ã«ãªã£ãããæ¹åæèŠã倱ããããããå¯èœæ§ããããããããŒãžäžã®ã¢ãã¡ãŒã·ã§ã³ã®éãå¶éããŸãã
- ãŠãŒã¶ãŒã®å¥œã¿ãå°éããïŒ åãã®äœæžã«é¢ãããŠãŒã¶ãŒã®å¥œã¿ãå°éããŸãã`prefers-reduced-motion`ã¡ãã£ã¢ã¯ãšãªã䜿çšããŠããŠãŒã¶ãŒãåãã®äœæžãèŠæ±ããŠãããã©ãããæ€åºããããã«å¿ããŠã¢ãã¡ãŒã·ã§ã³ã調æŽããŸãã
- ããŒããŒãã¢ã¯ã»ã·ããªãã£ã確ä¿ããïŒ ãã¹ãŠã®ã€ã³ã¿ã©ã¯ãã£ããªèŠçŽ ãããŒããŒãã§ã¢ã¯ã»ã¹ã§ããããšã確èªããŸãã
çµè«ïŒé åçãªWebäœéšã®ããã®ã¢ãŒã·ã§ã³ãã¹ã®ç¿åŸ
CSSã¢ãŒã·ã§ã³ãã¹ã¯ãé åçã§èŠèŠçã«èŠäºãªwebã¢ãã¡ãŒã·ã§ã³ãäœæããããã®åŒ·åãªæ¹æ³ãæäŸããŸãããã¹åº§æšç³»ãçè§£ãããã¹åº§æšå€æã®ãã¯ããã¯ãç¿åŸããããšã§ããã®æè¡ã®å¯èœæ§ãæå€§éã«åŒãåºããçã«æ³šç®ãã¹ãwebäœéšãåµåºã§ããŸãããã€ãããã¯ãªè£œåãã¢ãŒãã¢ãã¡ãŒã·ã§ã³åãããã€ã³ãã©ã°ã©ãã£ãã¯ããŸãã¯é åçãªã²ãŒã ãæ§ç¯ããŠããå Žåã§ããCSSã¢ãŒã·ã§ã³ãã¹ã¯ããªãã®åµé çãªããžã§ã³ãå®çŸããããã®ããŒã«ãæäŸããŸãã
äžçäžã®ãã¹ãŠã®ãŠãŒã¶ãŒã«ãšã£ãŠãããªãã®ã¢ãã¡ãŒã·ã§ã³ãçŸããããã€å©çšãããããã®ã§ããããã«ãããã©ãŒãã³ã¹ãšã¢ã¯ã»ã·ããªãã£ãåªå ããããšãå¿ããªãã§ãã ãããWebæè¡ãé²åãç¶ããäžã§ãCSSã¢ãŒã·ã§ã³ãã¹ã®ãããªãã¯ããã¯ãç¿åŸããããšã¯ãäžçäžã®èŠèŽè ã®æ³šç®ãéãã驿°çã§é åçãªwebäœéšãåµåºããããã«äžå¯æ¬ ãšãªãã§ãããã