พาธการเคลื่อนไหว SVG: ย้ายไอคอนที่ออกแบบเองไปตามเส้นโค้ง
ย้ายงาน SVG ไปตามเส้นโค้งด้วย animateMotion และ mpath แก้ไอคอนที่เยื้องศูนย์ เลือกการหมุนอัตโนมัติ และเตรียมภาพนิ่งสำหรับผู้ที่ต้องการลดการเคลื่อนไหว
ในหน้านี้
ใช้ animateMotion เพื่อย้ายองค์ประกอบ SVG ไปตามเส้นทาง และใส่ mpath ไว้ภายในเพื่ออ้างอิงพาธที่มีอยู่ rotate="auto" หมุนงานภาพที่เคลื่อนไหวให้หันตามทิศทางของเส้นทาง จุดกำเนิดพิกัดเฉพาะของงานภาพคือจุดที่เดินทางไปตามพาธ ดังนั้นไอคอนที่นำเข้าจึงต้องกำหนดจุดยึดอย่างตั้งใจ
วิธีนี้มีประโยชน์เมื่อต้องการให้ลูกศร ตราสัญลักษณ์ หรือภาพประกอบเล็ก ๆ ที่ออกแบบเองเคลื่อนที่โดยไม่เปลี่ยนรูปทรง สำหรับเส้นที่ดูเหมือนกำลังวาดตัวเอง ให้ใช้ แอนิเมชันเส้นขอบ สำหรับรูปเงาที่เปลี่ยนเป็นอีกรูป ให้ใช้ การแปรรูปร่างพาธ เทคนิคเหล่านี้ตอบโจทย์ภาพที่ต่างกัน
แยกเส้นทางออกจากงานภาพ
เส้นทางกำหนดว่าไอคอนจะไปที่ไหน งานภาพกำหนดสิ่งที่ผู้อ่านเห็น เอกสารอ้างอิง animateMotion ของ MDN อธิบายองค์ประกอบการเคลื่อนไหว ส่วน เอกสารอ้างอิง mpath แสดงวิธีนำพาธมาใช้ซ้ำด้วยการอ้างอิง
ตัวอย่างที่เราสร้างด้านล่างมีลูกศรสีเขียวอมฟ้าและจุดสีทอง ลูกศรชี้ไปทางแกน X บวก ซึ่งช่วยให้ตรวจผลของการหมุนอัตโนมัติได้ง่าย งานภาพวาดอยู่รอบ (0, 0) แทนที่จะอยู่ห่างออกไปบนผืนภาพส่งออกขนาดใหญ่
บันทึกเป็น motion.html แล้วเปิดในเบราว์เซอร์ ตราสัญลักษณ์แบบนิ่งจะปรากฏก่อน กด Play เพื่อเล่นหนึ่งรอบนานสี่วินาที ส่วน Show static จะคืนภาพประกอบไปยังจุดเริ่มต้น
<!doctype html>
<meta charset="utf-8">
<title>Arrow following a curve</title>
<style>
svg { display: block; width: min(100%, 800px); }
.moving { display: none; }
.playing .moving { display: inline; }
.playing .still { display: none; }
</style>
<svg id="scene" viewBox="0 0 480 240"
xmlns="http://www.w3.org/2000/svg"
role="img" aria-label="An arrow emblem follows a curved route">
<defs>
<path id="route" d="M60 180 C160 20 300 20 420 180" />
<g id="emblem">
<path fill="#147d78"
d="M-18-12 H4 V-22 L30 0 L4 22 V12 H-18 Z" />
<circle cx="-7" cy="0" r="4" fill="#e5a340" />
</g>
</defs>
<use href="#route" fill="none" stroke="#a9bab6" stroke-width="2" />
<use class="still" href="#emblem" transform="translate(60 180)" />
<g class="moving">
<use href="#emblem" />
<animateMotion id="motion" dur="4s" begin="indefinite"
fill="freeze" rotate="auto">
<mpath href="#route" />
</animateMotion>
</g>
</svg>
<button id="play" type="button">Play</button>
<button id="stop" type="button">Show static</button>
<script>
const scene = document.querySelector("#scene");
const motion = document.querySelector("#motion");
const preference = matchMedia("(prefers-reduced-motion: reduce)");
function showStatic() {
scene.pauseAnimations();
scene.classList.remove("playing");
}
document.querySelector("#play").addEventListener("click", () => {
if (preference.matches) return;
scene.pauseAnimations();
scene.setCurrentTime(0);
scene.classList.add("playing");
motion.beginElement();
scene.unpauseAnimations();
});
document.querySelector("#stop").addEventListener("click", showStatic);
preference.addEventListener("change", showStatic);
showStatic();
</script>เส้นโค้งสีเทาที่มองเห็นเป็น use ของเส้นทางที่แยกต่างหาก ลบ use นั้นหากไม่ต้องการให้เห็นพาธ แต่เก็บคำจำกัดความใน defs ไว้เพื่อให้แอนิเมชันยังอ้างอิงได้ องค์ประกอบการเคลื่อนไหวต้องอยู่ภายในกลุ่มที่ต้องการให้ลูกศรและจุดเคลื่อนที่ไปด้วยกัน
fill="freeze" คงสถานะสุดท้ายของแอนิเมชันไว้ ไม่เกี่ยวกับสีเขียวอมฟ้าที่ระบายบนลูกศร ตัวอย่างนี้เล่นเพียงครั้งเดียว จึงตรวจตำแหน่งสุดท้ายได้ง่ายกว่าการเล่นวนไม่สิ้นสุด

แก้ไอคอนที่ลอยห่างจากเส้นทาง
การเคลื่อนไหวใช้กับระบบพิกัดขององค์ประกอบ ไม่ได้ค้นหาศูนย์กลางที่มองเห็นของโลโก้ให้อัตโนมัติ หากพาธที่นำเข้าของคุณอยู่รอบพิกัด (200, 120) การย้ายกลุ่มที่ครอบมันไปตามเส้นทางจะยังเก็บระยะเยื้องนั้นไว้ภายในกลุ่ม
เลือกจุดบนงานภาพที่ต้องการให้สัมผัสเส้นทาง แล้วเลื่อนจุดนั้นไปที่ (0, 0) ภายในกลุ่มที่เคลื่อนไหว สำหรับจุดยึดที่ (200, 120) โครงสร้างคือ:
<g class="moving">
<g transform="translate(-200 -120)">
<!-- Place the original artwork paths here. -->
</g>
<animateMotion dur="4s" rotate="auto">
<mpath href="#route" />
</animateMotion>
</g>การเลื่อนภายในเตรียมงานภาพ ส่วนกลุ่มด้านนอกรับการเคลื่อนไหว แยกหน้าที่เหล่านี้ไว้เมื่อเพิ่มมาตราส่วนหรือการหมุนเพื่อปรับทิศทาง ข้อกำหนดแอนิเมชัน SVG นิยามการเคลื่อนไหวเป็นการแปลงเพิ่มเติม ดังนั้นการแปลงที่มีอยู่ยังส่งผลต่อการวางตำแหน่งสุดท้าย
สำหรับตราสัญลักษณ์ จุดกึ่งกลางอาจเป็นจุดยึดที่เหมาะสม สำหรับยานพาหนะ คุณอาจต้องการจุดที่ล้อสัมผัสพื้น ส่วนตัวชี้อาจต้องการใช้ปลายของมัน จุดกึ่งกลางกรอบครอบวัตถุเป็นเพียงค่าคาดเดาเริ่มต้น ตรวจจุดสัมผัสที่ตั้งใจไว้มากกว่าหนึ่งตำแหน่งบนเส้นทาง
การหมุนอยู่กับที่มีปัญหาเรื่องจุดหมุนของตัวเอง คู่มือ transform-origin ของ SVG อธิบายกรณีนั้นโดยไม่เพิ่มเส้นทางการเดินทาง
เลือกว่าจะให้งานภาพหมุนหรือไม่
| ผลลัพธ์ที่ต้องการ | การตั้งค่าการเคลื่อนไหว | การเตรียมงานภาพ |
|---|---|---|
| ลูกศรหันตามทิศทางเส้นโค้ง | rotate="auto" | ให้ทิศด้านหน้าชี้ไปทางแกน X บวก |
| ตราสัญลักษณ์ตั้งตรงระหว่างเคลื่อนที่ | rotate="0" | กำหนดทิศทางคงที่ที่ต้องการไว้ในงานภาพเฉพาะของมัน |
| งานภาพหันตรงข้ามทิศทางเส้นทาง | rotate="auto-reverse" | ตรวจทิศด้านหน้าของต้นฉบับก่อนใช้ |
ค่าเหล่านี้มีเอกสารใน เอกสารอ้างอิงการหมุนขณะเคลื่อนไหวของ MDN auto-reverse เปลี่ยนด้านที่หัน แต่ไม่ได้ย้อนลำดับการเดินทางตามเส้นทาง
หากต้นฉบับของคุณชี้ขึ้นด้านบน auto ไม่รู้ว่าด้านบนหมายถึงด้านหน้า ให้หมุนกลุ่มงานภาพด้านในจนชี้ไปทางแกน X บวก แล้วใช้การเคลื่อนไหวกับกลุ่มด้านนอก อย่าหมุนเส้นทางเพียงเพื่อแก้ทิศทางเฉพาะของไอคอน
มุมแหลมบนเส้นทางอาจทำให้เปลี่ยนทิศฉับพลัน เส้นทางโค้งเป็นจุดเริ่มต้นที่ดีกว่าเมื่อคุณต้องการให้การเลี้ยวดูนุ่มนวล เว้นพื้นที่รอบเส้นทางด้วย: ไอคอนอาจยื่นเลยแนวกึ่งกลางพาธและถูกตัดเมื่อเข้าใกล้ขอบวิวพอร์ต SVG
ตรวจจุดเริ่มต้น กลางทาง และจุดสิ้นสุด
เราเปิดเส้นทางและตราสัญลักษณ์เดียวกันใน Chrome และใช้ชุดทดสอบขนาดเล็กเพื่อหยุดไทม์ไลน์ SVG ที่ 0, 2 และ 4 วินาที ไอคอนเริ่มที่ด้านล่างซ้าย ผ่านใกล้ยอดโค้ง และสิ้นสุดที่ด้านล่างขวา เมื่อใช้ auto ด้านที่หันจะเปลี่ยนไปตามเส้นโค้ง เมื่อกำหนดการหมุนเป็น 0 ตำแหน่งกลางทางไม่เปลี่ยน แต่ลูกศรยังคงอยู่ในแนวนอน
การตรวจนี้ครอบคลุมตัวอย่างนี้ในเบราว์เซอร์เดียว ไม่ใช่การทดสอบนำเข้าแอนิเมชันในเครื่องมือออกแบบ หรือคำรับประกันสำหรับการฝังภาพทุกแบบในเบราว์เซอร์
สำหรับงานภาพของคุณเอง:
- ตรวจจุดสัมผัสที่จุดเริ่มต้นของเส้นทาง แก้ระยะเยื้องในต้นฉบับก่อนปรับเวลา
- หยุดใกล้ส่วนโค้งและยืนยันว่าส่วนที่ตั้งใจไว้ของตราสัญลักษณ์เคลื่อนตามเส้น
- เปรียบเทียบการหมุนอัตโนมัติกับการหมุนคงที่ เลือกตามงานภาพ โดยเฉพาะเมื่อมีข้อความอยู่ด้วย
- ตรวจตำแหน่งสุดท้ายว่าถูกตัดหรือไม่ และยืนยันว่าการเล่นซ้ำเริ่มต้นถูกต้อง
- ทดสอบบริบทส่งมอบจริง ตัวอย่างนี้ใช้ SVG แบบอินไลน์ภายในหน้า HTML พร้อมตัวควบคุม JavaScript
animateMotion ใช้การเคลื่อนไหวตามระยะทางอย่างสม่ำเสมอเป็นค่าปริยายตามเอกสาร MDN ดังนั้นครึ่งหนึ่งของระยะเวลาจึงหมายถึงประมาณครึ่งหนึ่งของระยะทางที่เคลื่อน ไม่จำเป็นต้องเป็นค่าพารามิเตอร์เส้นโค้งกึ่งกลางระหว่างจุดควบคุม ตำแหน่งเมื่อสองวินาทีบนเส้นทางเบซิเยร์ดีกรีสามที่ไม่สมมาตรของเราอยู่ทางขวาของยอดโค้งทางเรขาคณิตเล็กน้อย
เตรียมภาพนิ่งที่ใช้งานได้
ตัวอย่างเริ่มด้วย use ของตราสัญลักษณ์แบบนิ่ง และเริ่มเคลื่อนไหวหลังจากกดปุ่ม Play เท่านั้น หาก JavaScript ไม่ทำงาน งานภาพแบบนิ่งยังมองเห็นได้ เมื่อผู้ใช้ตั้งค่าลดการเคลื่อนไหว ตัวจัดการจะคงสถานะนี้ไว้
ฟีเจอร์สื่อ prefers-reduced-motion ทำให้หน้าตอบสนองต่อความต้องการด้านการเคลื่อนไหวของผู้ใช้ได้ ในที่นี้ JavaScript อ่านค่านั้นก่อนเริ่มการเคลื่อนไหว SVG และคืนภาพนิ่งหากความต้องการเปลี่ยนไป
เราทดสอบส่วนภาพนิ่งด้วยสวิตช์พรีวิวการลดการเคลื่อนไหวที่กำหนดไว้โดยตรงในชุดทดสอบด้วย: มันซ่อนกลุ่มแอนิเมชันและแสดงตราสัญลักษณ์ ณ ตำแหน่งเริ่มต้น สวิตช์นั้นทดสอบตรรกะทางเลือกสำรองของเรา ไม่ได้เปลี่ยนการตั้งค่าการช่วยการเข้าถึงของคอมพิวเตอร์
ถ้าเป็นไปได้ ให้สื่อความหมายไว้นอกแอนิเมชัน ผู้ใช้ไม่ควรต้องดูตราสัญลักษณ์ที่เคลื่อนไหวเพื่อรับรู้สถานะหรืออ่านคำแนะนำสำคัญ สำหรับไอคอนตกแต่งข้างข้อความที่อธิบายชัดเจนอยู่แล้ว ให้ปรับป้ายกำกับเพื่อการช่วยการเข้าถึงเพื่อเลี่ยงการประกาศเนื้อหาเดียวกันซ้ำ
เตรียมลวดลายของคุณก่อนทำแอนิเมชัน
หากลวดลายที่ออกแบบเองมีเพียง PNG หรือ JPG PerfectVector สามารถช่วยกู้คืนงานภาพ SVG ที่แก้ไขได้ก่อนสร้างการเคลื่อนไหว ตรวจขอบรูปและช่องเปิดเล็ก ๆ ที่กู้คืนมา จัดกลุ่มส่วนที่ควรเดินทางไปด้วยกัน และเลือกจุดยึด PerfectVector ให้รูปทรงต้นทาง ส่วนเส้นทาง เวลา และพฤติกรรมการเคลื่อนไหวต้องสร้างแยกต่างหาก
SVG ที่มีอยู่สามารถเข้าสู่การจัดกลุ่มและเตรียมจุดยึดได้ทันที สำหรับลูกศรเรียบง่ายเช่นตัวอย่างนี้ การวาดรูปทรงโดยตรงก็ทำได้สะดวกเช่นกัน ภาพรวมการแปลงภาพเป็นเวกเตอร์ อธิบายว่าเมื่อใดการลากพาธจากต้นฉบับราสเตอร์จึงมีประโยชน์
สำหรับเครื่องหมายที่ออกแบบเองซึ่งมีเพียงราสเตอร์ ให้ ลองภาพของคุณใน PerfectVector ตรวจเส้นรอบรูปและรายละเอียดเล็ก ๆ แล้วทดสอบ SVG นั้นที่จุดเริ่มต้น กลางทาง และจุดสิ้นสุดของเส้นทาง เก็บภาพนิ่งไว้ควบคู่กับแบบเคลื่อนไหว
คำถามที่พบบ่อย
ทำไมไอคอนจึงเคลื่อนอยู่ข้างพาธแทนที่จะอยู่บนพาธ? งานภาพอาจเยื้องจากจุดกำเนิดพิกัดเฉพาะของมัน เลือกจุดที่ควรเคลื่อนตามเส้นทาง แล้วเลื่อนจุดนั้นไปยังศูนย์ภายในกลุ่มที่เคลื่อนไหว ตรวจผลที่จุดเริ่มต้นและบริเวณโค้ง
การหมุนอัตโนมัติเปลี่ยนรูปทรงไอคอนหรือไม่? ไม่ การเคลื่อนไหวเปลี่ยนตำแหน่งและทิศทางของงานภาพ ไม่ได้แปรรูปทรงพาธ ทิศด้านหน้าของต้นฉบับควรชี้ไปทางแกน X บวกสำหรับการหมุนอัตโนมัติที่ใช้ในตัวอย่างนี้
ลบเส้นนำทางที่มองเห็นได้หรือไม่? ได้ เก็บคำจำกัดความเส้นทางและ ID ของมันไว้ แต่ลบองค์ประกอบแยกที่วาดเส้นนำทางออก การเคลื่อนไหวยังอ้างอิงพาธผ่าน mpath ได้
แหล่งอ้างอิง
- MDN animateMotion — อธิบายพาธการเคลื่อนไหว ค่าการหมุน และการเคลื่อนไหวตามระยะทางอย่างสม่ำเสมอที่เป็นค่าปริยาย
- MDN mpath — อธิบายการอ้างอิงเส้นทางที่มีอยู่ภายในองค์ประกอบการเคลื่อนไหว
- ข้อกำหนดแอนิเมชัน SVG — นิยามการแปลงจากการเคลื่อนไหวและความสัมพันธ์กับพิกัดงานภาพ
- MDN แอตทริบิวต์ rotate — อธิบายทิศทางขณะเคลื่อนไหวแบบคงที่ อัตโนมัติ และหันกลับด้าน
- MDN ความต้องการลดการเคลื่อนไหว — อธิบายการตรวจความต้องการด้านการเคลื่อนไหวของผู้ใช้
เพิ่มเติมจากบล็อก

กรอบครอบ SVG: วัดในระบบพิกัดที่ถูกต้อง
เปรียบเทียบ getBBox กับ getBoundingClientRect บนงาน SVG ที่ผ่านการแปลง วางกรอบซ้อนให้ถูกตำแหน่ง ทดสอบขอบเขตเส้นขอบ และปรับ viewBox พร้อมระยะเผื่อที่กำหนดชัดเจน

ภาพ SVG ใน Graphviz: ย้ายภาพในโหนดได้ครบ
เพิ่มภาพ SVG ในโหนด Graphviz ตรวจการอ้างอิงภาพ และทดสอบชุดแอสเซ็ตครบถ้วนเทียบกับแผนภาพที่ย้ายเดี่ยวและสำเนาส่งมอบที่มีข้อมูลครบในตัว