φυβλαςのβλογ
บล็อกของ phyblas



manim บทที่ ๕: การทำให้ภาพเคลื่อนไหวเปลี่ยนแปลง
เขียนเมื่อ 2021/03/12 00:05
แก้ไขล่าสุด 2021/09/28 16:42

ต่อจาก บทที่ ๔

ตั้งแต่ในบทแรกได้แสดงตัวอย่างการทำภาพเคลื่อนไหวอย่างง่ายไปแล้ว ทำโดยใช้เมธอด self.play() แต่ยังไม่ได้อธิบายรายละเอียดการใช้

self.play() เป็นเมธอดที่ใช้สำหรับกำหนดความเคลื่อนไหวขอภาพ

สำหรับในบทนี้จะอธิบายถึงวิธีการใช้เมธอดนี้ในรายละเอียดขึ้น

นอกจากนี้เมธอดอื่นๆที่เขียนถึงไปตั้งแต่ในบทที่ บทที่ ๓ เช่น .move_to() .to_edge() .to_corner() .next_to() ฯลฯ ก็ใช้กับ .animate เพื่อแสดงการเคลื่อนไหวได้เช่นกัน




การใช้ self.play() เพื่อทำภาพเคลื่อนไหว

เมธอด self.play() นั้นมีวิธีการใช้งานอยู่หลากหลายรูปแบบ

โดยทั่วไปแล้วให้ใส่ออบเจ็กต์แสดงการเคลื่อนไหวลงใน self.play() และกำหนดเวลาว่าจะให้ใช้เวลาที่คีย์เวิร์ด run_time

หน่วยของ run_time คือวินาที ถ้าหากไม่ใส่จะเป็นค่าตั้งต้นคือ run_time=1 วินาที

ออบเจ็กต์แสดงการเคลื่อนไหวอาจสร้างขึ้นโดยเรียกเมธอดผ่านพรอเพอร์ตี .animate ของตัววัตถุ เช่นเมธอด .shift() ที่ใช้เลื่อนตำแหน่ง ถ้าเรียกผ่าน .animate เป็น .animate.shift() ก็จะได้เป็นออบเจ็กต์แสดงการเคลื่อนไหว ซึ่งเอาไปใส่ใน self.play() ก็จะได้ภาพที่แสดงการเคลื่อนไหวให้เห็น

อนึ่ง วัตถุที่จะใช้ทำภาพเคลื่อนไหวนั้นหากไม่ได้อยู่ในฉากจะถูกทำให้ปรากฏขึ้นทันที ไม่จำเป็นต้องใส่เข้ามาล่วงหน้าก่อนด้วยวิธีการเช่นใช้เมธอด self.add()

ตัวอย่าง
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        text = mnm.Text('แมงมุม\n\nเข้ามุมซ้ายบน',size=2.5)
        # self.add(text) # จะใส่ไว้ก่อนก็ได้ แต่ไม่จำเป็น
        self.play(
            text.animate.shift(mnm.LEFT*2+mnm.UP*1.5),
            run_time=2
        )






การใช้ ApplyMethod

อีกวิธีการสร้างออบเจ็กต์แสดงการเคลื่อนไหวของตัววัตถุเพื่อนำมาใส่ในเมธอด self.play() คือสร้างออบเจ็กต์ของคลาส ApplyMethod ขึ้นมา โดยใส่เมธอดของวัตถุนั้น แล้วตามด้วยอาร์กิวเมนต์ของเมธอดนั้น

ตัวอย่างการใช้
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        text = mnm.Text('แมงมุม\n\nเข้ามุมขวาล่าง',size=2.4)
        self.play(
            mnm.ApplyMethod(text.shift,mnm.DOWN*1.2+mnm.RIGHT*1.5),
            run_time=1.5
        )



วิธีนี้จะได้ผลเช่นเดียวกับวิธีเรียกเมธอดผ่าน .animate แค่เขียนต่างกัน จะใช้แบบไหนก็ได้

ในตัวอย่างต่อๆจากนี้ไปจะใช้ .animate เป็นหลัก เพราะดูแล้วเข้าใจง่ายกว่า




การทำให้วัตถุหลายตัวเคลื่อนไหวในเวลาเดียวกัน

หากมีวัตถุหลายตัวที่ต้องการให้เกิดการเคลื่อนไหวไปพร้อมๆกันก็ให้ใส่ลงไปใน self.play() พร้อมกัน เช่น
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        text1 = mnm.Text('แมงมุมบน',size=3.5)
        text2 = mnm.Text('แมงมุมล่าง',size=3)
        self.play(
            text1.animate.shift(mnm.UP*2),
            text2.animate.shift(mnm.DOWN*2),
            run_time=1.5
        )



กรณีใช้ ApplyMethod ก็เช่นกัน
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        text1 = mnm.Text('แมงมุมขวา',size=3.1)
        text2 = mnm.Text('แมงมุมซ้าย',size=2.6)
        self.play(
            mnm.ApplyMethod(text1.shift,mnm.RIGHT*1.5),
            mnm.ApplyMethod(text2.shift,mnm.LEFT*2.5),
            run_time=1.5
        )



เมธอดของวัตถุตัวเดียวกันจะใส่ลงใน self.play() เดียวกันซ้ำกันไม่ได้ หากใส่ลงไปซ้ำก็จะมีผลแค่ตัวสุดท้ายที่ใส่




การให้หยุดรอด้วยเมธอด self.wait()

หากมีขั้นตอนที่ต้องการให้หยุดนิ่งไม่ต้องทำอะไรสักพักก็อาจใช้เมธอด self.wait() โดยใส่ค่าเวลาที่จะนิ่งรอ (หากไม่ใส่จะเป็นค่าตั้งต้นคือ 1 วินาที)

ตัวอย่าง
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        text = mnm.Text('แมงมุม',size=4)
        self.play(
            text.animate.shift(mnm.LEFT*2.5),
            run_time=0.5
        )
        self.wait(1.5)
        self.play(
            text.animate.shift(mnm.DOWN*2),
            run_time=1
        )






การทำให้แต่ละตัวในกลุ่มวัตถุเคลื่อนไปไม่พร้อมกันด้วย lag_ratio

self.play() นั้นหากใช้กับกลุ่มวัตถุเช่นวัตถุที่รวมกันโดยใช้ VGroup แบบนี้โดยปกติแล้ววัตถุทั้งหมดในกลุ่มจะขยับไปพร้อมๆกันหมด

แต่หากต้องการให้เคลื่อนไปทีละตัวก็ทำได้โดยใส่คีย์เวิร์ด lag_ratio โดยใส่ค่าระหว่าง 0 ถึง 1

lag_ratio=1 จะหมายถึงตัวหนึ่งเคลื่อนเสร็จอีกตัวจึงเคลื่อนตาม เช่น
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        m1 = mnm.Triangle(color='#22bbbb')
        m2 = mnm.Square(color='#cc7777')
        m3 = mnm.Circle(color='#bbee33')
        vg = mnm.VGroup(m1,m2,m3)
        self.play(
            vg.animate.shift(mnm.LEFT*5),
            run_time=3,
            lag_ratio=1
        )



ถ้า lag_ratio น้อยกว่า 1 ก็จะเคลื่อนที่ไล่ๆกันมาด้วยเวลาที่เหลื่อมกัน เช่น
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        m1 = mnm.Triangle(color='#f4b6e8')
        m2 = mnm.Square(color='#b6e5f4')
        m3 = mnm.Circle(color='#f4e2b6')
        vg = mnm.VGroup(m1,m2,m3)
        self.play(
            vg.animate.shift(mnm.LEFT*5),
            run_time=3,
            lag_ratio=0.2
        )



และถ้า lag_ratio=0 จะเคลื่อนไปพร้อมกันทั้งหมด ซึ่งก็คือมีผลเหมืองกับการไม่ใส่ค่า lag_ratio




การทำให้ตัวหนังสือค่อยๆเลื่อนไม่พร้อมกัน

วัตถุข้อความตัวหนังสือ Text นั้นจริงๆแล้วตัวมันเองนั้นเป็นกลุ่มวัตถุซึ่งประกอบด้วยอักษรหลายตัวอยู่แล้ว ดังนั้นเมื่อใส่คีย์เวิร์ด lag_ratio จึงทำให้เกิดเลื่อนไปทีละตัว

ตัวอย่าง
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        text = mnm.Text('เมงุมิ',size=4,color='#aaeebb')
        self.play(
            text.animate.shift(mnm.UP*2.5),
            run_time=3,
            lag_ratio=0.5
        )



หากใช้ VGroup จัดรวมกลุ่ม Text แต่ละตัวอีกทีก็จะคิดรวมเป็นกลุ่มเดียว
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        vgtext = mnm.VGroup(
            mnm.Text('แมง',size=3,color='#88ffbb'),
            mnm.Text('มุม',size=3,color='#ffbb88'),
            mnm.Text('ขอบ',size=3,color='#bb88ff'),
            mnm.Text('ด้าน',size=3,color='#bbff88')
        )
        vgtext.arrange(mnm.RIGHT)
        self.play(
            vgtext.animate.shift(mnm.UP*3),
            run_time=3,
            lag_ratio=0.9
        )






การทำให้เริ่มพร้อมกันแต่ใช้เวลาไม่เท่ากันโดยใช้ AnimationGroup

ปกติถ้าใส่อนิเมชันหลายตัวลงไปใน self.play() ก็จะเริ่มพร้อมกันแล้วจบลงในเวลาเดียวกัน เพราะค่าเวลาที่กำหนดในคีย์เวิร์ด run_time นั้นจะถูกใช้กับทุกตัวพร้อมกันหมด

แต่หากต้องการให้เริ่มพร้อมกันแต่จบไม่พร้อมกันสามารถแยกให้แต่ละอันมี run_time ต่างกันได้โดยใส่ใน AnimationGroup

ตัวอย่างการใช้
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        text1 = mnm.Text('แมงมุม',size=3.2,color='#ffddff')
        text2 = mnm.Text('เมฆ',size=4.2,color='#ffffdd')
        text3 = mnm.Text('คุโมะ',size=3.7,color='#ddffff')
        vg = mnm.VGroup(text1,text2,text3)
        vg.arrange(mnm.DOWN)
        self.play(
            mnm.AnimationGroup(
                text1.animate.shift(mnm.DL*3.5),
                run_time=2
            ),
            mnm.AnimationGroup(
                text2.animate.shift(mnm.UR*1.8),
                run_time=3
            ),
            mnm.AnimationGroup(
                text3.animate.shift(mnm.RIGHT*2.9),
                run_time=1
            ),
        )



หากต้องการใส่ lag_ratio เพื่อทำให้แต่ละตัวในกลุ่มเคลื่อนไม่พร้อมกันก็สามารถแยกใส่ใน AnimationGroup แต่ละตัวได้ด้วย

ตัวอย่าง
import manimlib as mnm

class Manimala(mnm.Scene):
    def construct(self):
        text1 = mnm.Text('๑',size=6)
        text2 = mnm.Text('๒',size=6)
        text3 = mnm.Text('๓',size=6)
        text4 = mnm.Text('๔',size=6)
        vg = mnm.VGroup(text1,text2,text3,text4)
        vg.arrange(mnm.LEFT)
        
        self.play(
            mnm.AnimationGroup(
                text1.animate.shift(mnm.DL*2),
                text2.animate.shift(mnm.UR*2),
                run_time=1.5,
                lag_ratio=0.3
            ),
            mnm.AnimationGroup(
                text3.animate.shift(mnm.UL*2),
                text4.animate.shift(mnm.DR*2),
                run_time=3,
                lag_ratio=0.9
            ),
        )





อ่านบทถัดไป >> บทที่ ๖





-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> manim

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文