φυβλαςのβλογ
บล็อกของ 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)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

ไทย

日本語

中文