4 ก.ย. 2554

บทเรียนที่ 28 Animation

บทเรียนที่ 28 Animation



                    ตัวอย่างนี้ใช้จาวาสคริปเพื่อที่จะสร้างภาพเคลื่อนไหว(Animation) ซึ่งจำเป็นอย่างยิ่ง ที่ต้องโหลดภาพมาล่วงหน้าก่อน(เปิดหน้าปุ๊บ โหลดปั๊บ) เรียนบทที่แล้วมา คงจำได้นะครับว่าทำอย่างไร ? ...คือ...ที่นอกชุดคำสั่ง ให้กำหนดชื่อให้เป็น new Images() และใช้คำสั่ง ชื่อที่กำหนด.src เท่ากับที่อยู่ภาพที่ต้องการโหลดภาพล่วงหน้า

                    หากภาพไม่โหลดมาก่อนล่วงหน้า เมื่อชุดคำสั่งทำงาน ผู้ใช้ต้องรอโหลดภาพจากเซิร์ฟเวอร์ ในครั้งแรกที่ผู้ใช้กด link ...ซึ่งจะทำให้ภาพเคลื่อนไหวชะงักชะงันครับ   ในตัวอย่างอาจเรียกไม่ได้ว่าเป็นภาพเคลื่อนไหวอะไรนักนะครับ เพราะใช้รูปแค่ 3 รูป ก็แสดงได้แค่นี้ล่ะครับ แต่หากคุณทำเอง จะเพิ่มรูปเข้าไปมากๆ เพื่อให้เป็นหนังหรือการ์ตูนสั้นๆก็ได้ครับ

สคริป...
<HTML>
<HEAD>
<SCRIPT language="javascript">
 var num=1
 img1 = new Image (150,150)
 img1.src = "http://www.htmlgoodies.com/primers/jsp/pic1.gif"
 img2 = new Image (150,150)
 img2.src = "http://www.htmlgoodies.com/primers/jsp/pic2.gif"
 img3 = new Image (150,150)
 img3.src = "http://www.htmlgoodies.com/primers/jsp/pic3.gif"  
  function startshow()
  {
   for (i=1; i<=21; i=i+1)
{document.mypic.src=eval("img"+num+".src")
    for(x=1; x<800; x=x+1)
  {}
    num=num+1
    if(num==4)
    {num=1}
   }
   document.mypic.src=img1.src
   }
</SCRIPT>
</HEAD>
<BODY>
<CENTER>
<IMG SRC="http://www.htmlgoodies.com/primers/jsp/pic1.gif" NAME="mypic" BORDER=0 >
<p>
<A HREF="javaScript:startshow()">
<h2>แสดงภาพเคลื่อนไหว</h2></a> 
</CENTER>
</BODY>
</HTML>


ผลของสคริปนี้

แสดงภาพเคลื่อนไหว

มาแยกโครงสร้างสคริปกันครับ
·         เราจะเริ่มจากส่วนที่ทำให้โหลดภาพล่วงหน้า ให้สังเกตว่าส่วนนี้อยู่นอกชุดคำสั่งใดๆ และมีการกำหนดตัวแปรชื่อ num ให้มีค่าเท่ากับ 1   ส่วนในตัวเลขในวงเล็บของ new Images() เป็นการกำหนดความกว้างและสูงของภาพครับ ซึ่งช่วยให้ภาพโหลดเร็วขึ้น หากกำหนดให้ภาพเล็กๆเข้าไว้(ผมเดานะครับ ไม่เคยลองง่ะ)
·  <SCRIPT language="javascript">
·   var num=1
·   img1 = new Image (150,150)
·   img1.src = "http://www.htmlgoodies.com/primers/jsp/pic1.gif"
·   img2 = new Image (150,150)
·   img2.src = "http://www.htmlgoodies.com/primers/jsp/pic2.gif"
·   img3 = new Image (150,150)
 img3.src = "http://www.htmlgoodies.com/primers/jsp/pic3.gif"
·         และต่อมาในส่วนของชุดคำสั่ง...
·  function startshow()
·    {
·     for (i=1; i<=21; i=i+1)
·  {document.mypic.src=eval("img"+num+".src")
·      for(x=1; x<800; x=x+1)
·    {}
·      num=num+1
·      if(num==4)
·      {num=1}
·     }
·     document.mypic.src=img1.src
·     }
</SCRIPT>
·         ในชุดคำสั่ง startshow() มีสิ่งใหม่สำหรับคุณ คือ..การวาง for ซ้อนใน for (ฝรั่งเขาเรียก nest loops หมายถึงการวนคำสั่งซ้อนกัน ประมาณนั้นครับ) มี for อันที่อยู่ข้างนอก และ for ที่อยู่ข้างในอันนอก แบบ..... for(....) { for(....) { } } เข้าใจส่วนนี้มั้ยครับ ?   for อันข้างในมีหน้าที่ถ่วงเวลาในการแสดงภาพต่อไป ทำให้แต่ละภาพค้างอยู่ชั่วขณะก่อนจะแสดงภาพถัดไปให้ผู้ใช้เห็น
·         สังเกตว่าไม่มีคำสั่งอยู่ใน for อันใน (มีแต่ปีกกาเปิดแล้วปิดเลย) ซึ่งจะเป็นการนับ 1 ถึง 800 โดยจะใช้เวลานับ(หน่วงภาพ)เท่ากับ 800/1000 ของวินาที (หรือ 0.8 วินาที)
·         คอมฯจะนับหนึ่งถึงแปดร้อย ทุกครั้งหลังจากแต่ละภาพถูกแสดงออกมา
·         for อันนอก จะทำให้โปรแกรมวนชุดคำสั่ง 21 รอบ (จากการกำหนด i=1;i<=21;i=i+1) เพราะว่าภาพเคลื่อนไหวนี้ใช้ 3 ภาพ   ภาพเคลื่อนไหวจึงเกิดขึ้นทั้งหมดเท่ากับ 21 หาร 3 เท่ากับ 7 ซ้ำ
·         สังเกตว่าพอวนครบหมดทุกรอบ ภาพจะกลับมาเป็นภาพเริ่มต้นเหมือนเดิม
·         และนี่เป็นคำสั่งแสดงภาพเริ่มต้นในหน้าจอ...
<IMG SRC="http://www.htmlgoodies.com/primers/jsp/pic1.gif" NAME="mypic" BORDER=0 >
ชื่อของรูปถูกใช้ว่า mypic ซึ่งจะนำชื่อนี้ไปใช้ในคำสั่งเปลี่ยนรูป โดยวางไว้ระหว่าง document และ src ซึ่งเป็นไปตามกฏลำดับชั้น(hierarchy)
·         และสุดท้าย link ที่ทำให้เกิดภาพเคลื่อนไหว...
<A HREF="javaScript:startshow()"> <h2>แสดงภาพเคลื่อนไหว</h2></a>
อย่าลืมว่าหากใช้ link href เพื่อให้ชุดคำสั่งทำงาน ให้ใส่ javascript: นำหน้าชื่อชุดคำสั่งทุกครั้งครับ ไม่งั้นเจ๊ง

แบบฝึกหัด (สำหรับผู้ใช้ที่สคริปตัวอย่างทำงานได้)
                    ให้เขียนโปรแกรมข้างบนใหม่ โดยเพิ่มแบบฟอร์มที่เป็นกล่องข้อความ(text box) ซึ่งเมื่อผู้ใช้สามารถพิมพ์คำว่า... ช้า , ปานกลาง และ เร็ว   ซึ่งจะเป็นตัวกำหนดความเร็วของภาพเคลื่อนไหว โดย ช้า จะหน่วงเวลา 2.4 วินาที(2400/1000) ปานกลาง จะหน่วงเวลา 1.6 วินาที(1600/1000) และ เร็ว จะหน่วงเวลา 0.8 วินาที(800/1000) และทำ link เหมือนตัวอย่าง จะใช้รูปในเว็บนี้หรือรูปของคุณเองก็ได้ครับ  (ผมทำเฉลยไม่ได้นะครับ เพราะผมทดสอบวิธีนี้ไม่ได้)

ภาพเคลื่อนไหวด้วยคำสั่ง setInterval (Netscape Navigator น่าจะใช้ได้นะครับ ช่วยทดสอบด้วย)
สคริป...
<HTML><HEAD><SCRIPT language="javascript">
nu = 1
c = 0
im1 = new Image (150,150)
im1.src = "http://www.htmlgoodies.com/primers/jsp/pic1.gif"
im2 = new Image (150,150)
im2.src = "http://www.htmlgoodies.com/primers/jsp/pic2.gif"
im3 = new Image (150,150)
im3.src = "http://www.htmlgoodies.com/primers/jsp/pic3.gif"
function startshow2()
{
c++; status=c; if(c>=21) {c=0; clearInterval(s) }
nu=nu+1; if(nu==4) {nu=1}
document.m.src=eval("img"+num+".src")
}
function settime()
{
if(c==0) {s=setInterval("startshow2()",200)}
}
</SCRIPT></HEAD><BODY><CENTER>
<IMG SRC="http://www.htmlgoodies.com/primers/jsp/pic1.gif" NAME="m" BORDER=0 >
<p><A HREF="javascript:settime()">
<h2>แสดงภาพเคลื่อนไหว</h2></a> 
</CENTER></BODY></HTML>
ผลของสคริปนี้

แสดงภาพเคลื่อนไหว




มาแยกโครงสร้างของสคริปนี้กันครับ
·         คุณจะพบว่าสคริปนี้แก้ไขชื่อตัวแปรและชุดคำสั่งต่างๆ เพื่อไม่ให้ซ้ำกับตัวอย่างข้างบน ไม่งั้น Error หรือแสดงผลเพี้ยนได้ครับ   และสังเกตว่า คราวนี้ไม่ใช้ for เหมือนตัวอย่างข้างบน แต่มีคำสั่งใหม่เข้ามาแทน
SCRIPT language="javascript">
nu = 1
c = 0
im1 = new Image (150,150)
im1.src = "http://www.htmlgoodies.com/primers/jsp/pic1.gif"
im2 = new Image (150,150)
im2.src = "http://www.htmlgoodies.com/primers/jsp/pic2.gif"
im3 = new Image (150,150)
im3.src = "http://www.htmlgoodies.com/primers/jsp/pic3.gif"
การกำหนดตัวแปรที่เพิ่มเข้ามาคือ c = 0 ซึ่งเป็นตัวแปรที่ใช้กำหนดจุดสิ้นสุดของภาพเคลื่อนไหว คล้ายๆกับการกำหนดเงื่อนไขใน for
·         ผมขอข้ามมาที่ link ก่อนนะครับ...
<A HREF="javascript:settime()">
เมื่อผู้ใช้คลิ๊กที่ link นี้ ชุดคำสั่ง settime() จะเริ่มทำงาน เราตามมาดูกันครับ ว่าทำงานอย่างไร...
function settime()
{
if(c==0) {s=setInterval("startshow2()",200)}
}
                    if จะตรวจสอบว่า c เท่ากับศูนย์หรือไม่(อย่าเพิ่งสนใจว่าตรวจสอบไปทำไม) ซึ่งเริ่มต้น c เท่ากับศูนย์ใช่มั้ยครับ ?   ดังนั้นเงื่อนไขเป็นจริง ชุดคำสั่งในปีกกาก็จะทำงาน...
·         s=setInterval("startshow2()",200)   s เอสเป็นชื่อที่เราตั้งขึ้น   setInterval ( รูปเต็มคือ window.setInterval() ) เป็นวิธีกระทำหรือคำสั่งที่ใช้วนหรือทำซ้ำชุดคำสั่งเช่นเดียวกับ for   แต่ต่างจาก for ตรงที่...
1.     for จะทำงานต่อเนื่องทันที แต่ setInterval สามารถกำหนดจังหวะเวลาในการวนชุดคำสั่ง ในตัวอย่างนี้เราใช้ 200   ซึ่งหมายถึง ทุกๆ 200/1000 วินาที(หรือ 0.2 วินาที) จะเรียกคำสั่งมาทำงาน 1 ครั้ง   แปลว่าใน 1 วินาทีหลังจากกด link  คำสั่งจะทำงาน 4 ครั้ง( ครั้งแรกเริ่มเมื่อถึง 0.2 วินาที ไปจนถึงครั้งที่ 4 ที่ 1 วินาที)
2.     setInterval ไม่มีรูปแบบการกำหนดเงื่อนไขหยุดการวนเหมือน for   แต่มีคำสั่ง clearInterval() (ในวงเล็บเป็น.. ชื่อของ setInterval ซึ่งในที่นี้คือ s ) เพื่อใช้หยุดการวน ดังนั้น setInterval สามารถทำงานไปเรื่อย ไม่มีที่สิ้นสุด หากคุณไม่สร้างเงื่อนไขที่จะหยุดมัน วิธีหนึ่งที่จะหยุดได้คือการกำหนดตัวแปร โดยให้ค่าของตัวแปรเพิ่มขึ้นทุกครั้งที่คำสั่งทำงาน เราจะกำหนดเงื่อนไข(ใช้ if)ว่า.. พอค่าของตัวแปรมากกว่าจุดที่กำหนด เราก็จะหยุดการวน โดยใช้คำสั่ง clearInterval()
·         โปรแกรมเข้าสู่การวนคำสั่งนี้ครับ...
function startshow2()
{
c++; status=c; if(c>=21) {c=0; clearInterval(s) }
nu=nu+1; if(nu==4) {nu=1}
document.m.src=eval("im"+nu+".src")
}
                    ตอนแรก c =0 พอเข้าคำสั่ง c++ (อีกรูปของ c = c+ 1) ค่า c จะบวกเพิ่มอีกหนึ่ง ทำให้ค่า c กลายเป็น 1   แล้วตามด้วย ; เพื่อแยกคำสั่งนี้ออกจากคำสั่งถัดไปในบรรทัดเดียวกัน แล้ว status bar จะแสดงค่า c ตามคำสั่ง status=c; ซึ่งจริงๆไม่จำเป็นต้องแสดงครับ ที่ทำเอาไว้เพื่อตรวจสอบการทำงานของชุดคำสั่งครับว่าวนถึงรอบที่เท่าไรอยู่ และสุดถึงรอบที่เท่าไร แล้วไปเจอ if(c>=21) {c=0; clearInterval(s) } ซึ่งตอนนี้ c เท่ากับ 1 ทำให้เงื่อนไขไม่เป็นจริงเพราะยังไม่มากกว่าหรือเท่ากับ 21 จึงไม่เข้าคำสั่งในปีกกา
                    ต่อมาเจอ nu=nu+1; คำสั่งนี้ทำหน้าที่เช่นเดียวกับ num=num+1ซึ่งจะบวกเพิ่มทีละหนึ่ง ทำให้ภาพเปลี่ยนไปเรื่อยๆ จนกระทั่ง nu = 4 เงื่อนไขของ if จะเป็นจริงและทำให้ nu เป็น 1 เหมือนเดิม เพื่อที่จะวนภาพใหม่อีกครั้ง(ถ้าไม่เข้าใจให้กลับไปดูในบทที่ 27)
                    เมื่อวนคำสั่งไปเรื่อย ค่า c ก็จะเพิ่มขึ้นเรื่อยๆ พร้อมกับภาพที่เปลี่ยนไป จนกระทั่งค่า c เท่ากับ 21 เงื่อนไข if(c>=21) เป็นจริง ทำให้เข้าคำสั่งในปีกกา {c=0; clearInterval(s) } ทำให้ c กลับเป็นศูนย์อีกครั้งเพื่อรองรับการคลิ๊กครั้งถัดไป และ clearInterval(s) จะหยุดการวนคำสั่งทันที แต่ชุดคำสั่ง startshow2() ยังคงทำงานในคำสั่งที่เหลือของรอบสุดท้าย คือคำสั่งที่ทำให้ค่า nu เพิ่มอีกหนึ่ง และเปลี่ยนภาพครั้งสุดท้าย
·         กลับมาดูตรงนี้อีกครั้งครับ...
function settime()
{
if(c==0) {s=setInterval("startshow2()",200)}
}
ที่ต้องกำหนดให้ c = 0 ถึงจะเกิดภาพเคลื่อนไหวได้ เพื่อป้องกันไม่ให้ภาพเคลื่อนไหวเกิดไม่สิ้นสุดเมื่อผู้ใช้คลิ๊กเมาส์หลายครั้ง เพราะหากไม่กำหนดเช่นนี้ และภาพเคลื่อนไหวกำลังดำเนินอยู่ แล้วผู้ใช้ไปคลิ๊กเมาส์เข้า   โปรแกรมจะทำการวนชุดคำสั่ง startshow2() ซ้ำของเดิม... คราวนี้ก็จะเกิดภาพเคลื่อนไหวไปเรื่อยๆ ไม่สิ้นสุดละครับ   การกำหนดเงื่อนไขให้เช่นนี้ จะทำให้ผู้ใช้ต้องรอให้ภาพเคลื่อนไหวจบก่อน(c = 0) จึงสามารถคลิ๊กเพื่อให้เกิดภาพเคลื่อนไหวครั้งต่อไปได้




อีกรูปแบบของการสร้างภาพเคลื่อนไหวด้วยคำสั่ง setTimeout

สคริป...
<HTML><HEAD><SCRIPT language="javascript">
n = 1
c = 0
i1 = new Image (150,150)
i1.src = "http://www.htmlgoodies.com/primers/jsp/pic1.gif"
i2 = new Image (150,150)
i2.src = "http://www.htmlgoodies.com/primers/jsp/pic2.gif"
i3 = new Image (150,150)
i3.src = "http://www.htmlgoodies.com/primers/jsp/pic3.gif"
function startshow3()
{s2=setTimeout("startshow3()",200)
c++; status=c; if(c>=21) {c=0; clearTimeout(s2) }
n=n+1; if(n==4) {n=1}
document.m.src=eval("i"+n+".src")
}
function settime2()
{
if(c==0) {startshow3()}
}
</SCRIPT></HEAD><BODY><CENTER>
<IMG SRC="http://www.htmlgoodies.com/primers/jsp/pic1.gif" NAME="m" BORDER=0 >
<p><A HREF="javascript:settime2()">
<h2>แสดงภาพเคลื่อนไหว</h2></a> 
</CENTER></BODY></HTML>


ผลของสคริปนี้...เหมือนกับตัวอย่างข้างบนครับ

มาดูส่วนที่เปลี่ยนไปกันครับ (ขออธิบายสั้นๆครับเพราะคล้ายกับข้างบน เพียงแต่เปลี่ยนคำสั่ง)
                    คราวนี้คำสั่ง setInterval และ clearInterval() หายไป...คำสั่งที่มาทำหน้าที่แทนคือ setTimeout กับ clearTimeout() ซึ่งคำสั่ง setTimeout เป็นคำสั่งหน่วงเวลาก่อนจะทำบางอย่างหรือหลายอย่าง ซึ่งมีรูปแบบดังนี้ครับ
กำหนดชื่อ = setTimeout(" เรียกชุดคำสั่งหรือ/และการกำหนดตัวแปร ", เวลาที่ใช้หน่วงในหน่วยมิลลิวินาที )
ยกตัวอย่างเช่น...
t = setTimeout("a() ; z = 1 ",1000)
                    เมื่อโปรแกรมทำงานถึงส่วนข้างบนนี้(ไม่ว่าจะผ่านอะไรมาก่อนก็ตามที) t จะเป็นชื่อของการหน่วงเวลานั้น เมื่อครบเวลา 1000 มิลลิวินาที (หรือ 1 วินาที) นับตั้งแต่โปรแกรมทำงานถึงจุดนี้... ชุดคำสั่ง a() จะเริ่มทำงาน   ค่า z จะเท่ากับ 1   หลักการใช้ setTimeout คร่าวๆ ก็มีแค่นี้ล่ะครับ ภายในเครื่องหมายคำพูดไม่จำกัดจำนวนคำสั่งหรือการกำหนดตัวแปร และระหว่างที่รอให้ถึงเวลาที่กำหนดนั้น โปรแกรมจะเลยไปทำงานส่วนถัดไปเลยครับ ไม่มีรอ แต่ระหว่างนั้นหากไปเจอคำสั่ง clearTimeout(กำหนดชื่อ) การกำหนดเวลาในชื่อนั้นจะยกเลิกไปเลยครับ เช่นในกรณีนี้หากยังไม่ครบ 1 วินาที   แล้วโปรแกรมทำงานถึงคำสั่ง clearTimeout(t) การหน่วยเวลาของ t จะถูกยกเลิกไปเลยครับ   ชุดคำสั่ง a จะไม่ถูกเรียกและค่า z จะไม่ถูกกำหนดให้เท่ากับ 1
{
if(c==0) {startshow3()}
}
ตอนแรกเริ่มเหมือนตัวอย่างที่แล้วครับ ตรวจว่า c = 0 จึงเข้าชุดคำสั่งที่ทำให้เกิดภาพเคลื่อนไหว
function startshow3()
{s2=setTimeout("startshow3()",200)
c++; status=c; if(c>=21) {c=0; clearTimeout(s2) }
n=n+1; if(n==4) {n=1}
document.m.src=eval("i"+n+".src")
}
setTimeout ทำให้เกิดการวนคำสั่งได้โดยหน่วงเวลาแล้วเรียกให้ชุดคำสั่ง startshow3() ทำงานครั้งต่อไป คำสั่งอื่นๆในชุดคำสั่งนี้ทำหน้าที่เหมือนกับที่อธิบายไปแล้วในตัวอย่างข้างบนครับ เมื่อค่า c เพิ่มขึ้นจนเท่ากับ 20 การวนคำสั่งในรอบที่ 21 จะเริ่มขึ้น s2 จะกำหนดการหน่วงเวลาเพื่อจะวนรอบต่อไปอีกครั้ง แต่ค่า c จะเพิ่มอีกหนึ่ง(c++) จะกลายเป็น 21   ทำให้เงื่อนไข if(c>=21) เป็นจริง ค่า c จะเท่ากับ 0 และโปรแกรมจะหยุดการวนรอบต่อไปหรือหยุดแสดงภาพเคลื่อนไหวด้วยคำสั่ง clearTimeout(s2)




แบบฝึกหัด
                    ให้เขียนโปรแกรมข้างบนใหม่ โดยสร้างภาพเคลื่อนไหว ด้วยคำสั่ง setInterval หรือ setTimeout และเพิ่มแบบฟอร์มที่เป็นกล่องข้อความ(text box) ซึ่งเมื่อผู้ใช้สามารถพิมพ์คำว่า... ช้า , ปานกลาง และ เร็ว   ซึ่งจะเป็นตัวกำหนดความเร็วของภาพเคลื่อนไหว โดย ช้า จะหน่วงเวลา 1 วินาที(1000 มิลลิวินาที) ปานกลาง จะหน่วงเวลา 0.5 วินาที(500 มิลลิวินาที) และ เร็ว จะหน่วงเวลา 0.1 วินาที(100 มิลลิวินาที) และทำ link เหมือนตัวอย่าง จะใช้รูปในเว็บนี้หรือรูปของคุณเองก็ได้ครับ
เฉลย
<HTML><HEAD><SCRIPT language="javascript">
num = 1
c = 0
sp = 500
img1 = new Image (150,150)
img1.src = "
ที่อยู่ของรูปแรก"
img2 = new Image (150,150)
img2.src = "
ที่อยู่ของรูปสอง"
img3 = new Image (150,150)
img3.src = "
ที่อยู่ของรูปสาม"
function startshow()
{
s2=setTimeout("startshow()",sp)
c++; status=c; if(c>=21) {c=0; clearTimeout(s2) }
num=num+1; if(num==4) {num=1}
document.mypic.src=eval("img"+num+".src")
}
function settime()
{
if(document.forms[0].elements[0].value=="
ช้า") {sp=1000}
if(document.forms[0].elements[0].value=="
ปานกลาง") {sp=500}
if(document.forms[0].elements[0].value=="
เร็ว") {sp=100}
if(c==0) {startshow()}
}
</SCRIPT></HEAD><BODY><CENTER>
<IMG SRC="
ที่อยู่ของรูปแรก" NAME="mypic" BORDER=0>
<p><h2><A HREF="javaScript:settime()">
แสดงภาพเคลื่อนไหว</a></h2><p>
<h3>
โปรดพิมพ์คำว่า <b>ช้า</b> <b>ปานกลาง</b>หรือ <b>เร็ว</b> ในช่องว่างข้างล่าง เพื่อกำหนดความเร็วของภาพเคลื่อนไหว</h3>
<form><input type="text" size="20"></form>
</CENTER></BODY></HTML>

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

 
;