หลังจากที่ผมพยายามศึกษาสคริปต์แก้สระลอยของเฮีย (?) katopz อยู่นานสองนาน
เพื่อจะได้สามารถแก้สระลอยใน sIFR ซึ่งเวอร์ชั่นต่ำสุดของ Flash Player ที่ใช้คือ 6.0 และ ActionScript 1.0
แต่สคริปต์แก้สระลอยของ SleepyDesign นี่ มันเป็น Class ครับ
ซึ่ง Class จะใช้ได้ตั้งแต่ ActionScript 2.0 ขึ้นไปเท่านั้น
ตอนแรกผมค่อนข้างงงกับสคริปต์พอสมควร
ไม่ใช่พอสมควรแหละครับ ไม่รู้เรื่องเลย
แนวคิดในการแก้สระลอยโดยใช้ ActionScript ที่ผมแกะออกมาคร่าวๆ ก็คือ
การทำ Loop พิจารณาตัวอักษรแต่ละตัว ว่าตัวนี้เป็นตัวไหน ตัวต่อไปหรือก่อนหน้าเป็นตัวอันนี้หรือเปล่า บลา บลา บลา
ก่อนอื่นควรจะรู้จักฟังก์ชั่นหลักๆก่อน
String.charAt(index)String คือชื่อ String หรือข้อความครับ
index คือตัวเลขครับ โดยเลข 0 หมายถึงตัวอักษรตัวแรกของ String
โดยจะมีผลลัพธ์คือ ตัวอักษรของ String ตัวที่เรากำหนด โดย 0 คือตัวแรก 1 คือตัวที่สอง ไปเรื่อยๆ...
เช่น
var myString = "Hello World!";
var char = myString.charAt(0);
ผลลัพธ์ที่ได้ออกมา (ในที่นี้คือค่าของตัวแปร char) จะเป็นตัว H ใหญ่ครับ
String.indexOf(character)String คือชื่อ String หรือข้อความเหมือนเดิมครับ
character คือตัวอักษรครับ
โดยจะมีผลลัพธ์ออกมาคือตำแหน่งของตัวอักษรนั้นๆใน String หรือข้อความที่ปรากฏเป็นตัวแรกครับ
เช่น
var myString = "Hello World!";
var charPos = myString.indexOf("o");
ค่าของตัวแปร charPos คือ 4
แต่ถ้าใน String หรือข้อความดังกล่าวไม่มีตัวอักษรที่ต้องการอยู่เลย ค่าที่ออกมาจะเป็น -1 ครับ
String.lengthผลที่ได้คือความยาวของ String หรือข้อความครับ
เช่น
var myString = "123";
var stringLength = myString.length;
ค่าตัวแปร stringLength คือ 3 ครับ
mbchr(index)index คือตัวเลข ซึ่งเป็นรหัส ASCII ของตัวอักษรครับ
อย่างเช่น
var firstVar = mbchr(124);
var secondVar = mbchr(0x0E01);
ค่าของ firstVar จะเป็นตัว | ครับ (| เป็นตัวอักษรที่ 124)
และค่าของ secondVar จะเป็น ก ไก่ครับ (ก มีรหัสยูนิโคดคือ 0E01)
ในที่นี้จะทดลองสร้าง Flash Preview ที่แก้ f กับ i ที่ติดกันให้กลายเป็น fi อัตโนมัติ
ก่อนอื่นก็คือวิธีบัญญัติฟังก์ชั่น
คล้ายๆกับใน php และภาษาทั่วไปนั่นแหละครับ
แต่ใน actionscript จะ Case Sensitive หรือให้ความสำคัญกับตัวพิมพ์เล็กและใหญ่
function ชื่อฟังก์ชั่น(ตัวแปร) {
คำสั่ง
}
โดยการกำหนดเช่นนี้ หมายถึงว่า ถ้าเราใส่ฟังก์ชั่นให้กับตัวแปร ฟังก์ชั่นก็ต้องทำแบบนี้ๆ เช่น
function myFunction(string) {
trace(string);
}
myFunction("สามเป็นเกย์");
แล้วจะมีคำว่า "สามเป็นเกย์" ออกมาทาง Output Panel ครับ
(คำสั่ง trace หมายถึงให้แสดงผลใน Output Panel)
เช่นเดียวกับอันนี้
function toFI(target) {
คำสั่ง
}
ตรงคำสั่งนี้เองเป็นส่วนที่สั่งงานให้แก้ f กับ i เป็น fi
โดยใช้ Loop อย่างที่บอกแต่ตอนแรก
ตัวอย่างการใช้ Loop เช่น
for (var num = 1; num < 18; num++) {
[i]do somethings[/i]
}
หมายถึง ให้ตัวแปร num เท่ากับ 1 (var num = 1)
ถ้าตัวแปร num น้อยกว่า 18 (num < 18)
ให้ทำสิ่งต่อไปนี้ (do somethings)
และบวกเพิ่ม num อีก 1 (num++)
ผลที่ได้ก็คือ มันจะ do somethings 17 ครั้ง
เช่นเดียวกันกับอันนี้นั่นแหละครับ
function toFI(codetarget) {
for (var i = 0; i < target.length; i++) {
[i]do somethings[/i]
}
}
ใช่แล้วครับ ทำ Loop พิจารณาตัวอักษรแต่ละตัว รายตัวเลยทีเดียว
โดย target.length ก็คือ ความยาวของ String ที่ชื่อ target นั่นเองครับ
var i = 0กำหนดให้ i เท่ากับ 0 (กำหนดขึ้นมาใหม่ ไม่ได้อ้างอิงจากไหนครับ)
i < target.lengthถ้า i ยังน้อยกว่าความยาวของข้อความที่พิจารณาอยู่
do somethingsให้ทำสิ่งต่อไปนี้
i++และบวกเพิ่ม i อีกหนึ่ง
ผลลัพธ์ก็คือมันจะ do somethings ทั้งหมดตามความยาวของ String ซึ่งก็หมายถึงจะ do somethings กับทุกตัวอักษรนั่นเอง
แน่นอน ว่าตรง do somethings ระหว่าง for {...} นั่นเองที่จะเป็นตัวทำให้ f กับ i กลายเป็น fi มาดูสคริปต์เต็มๆกันเลยดีกว่า
function toFI(target) {
var resultString = "";
for (var i = 0; i < target.length; i++) {
var char = target.charAt(i);
var fChar = "f";
var iChar = "i";
var fiChar = mbchr(0xFB01); // FB01 คือรหัสยูนิโคดของ fi
if ((char == fChar) && (target.charAt(i+1) == iChar) && (i+1 < target.length)) {
resultString += fiChar;
}
else if ((char == iChar) && (target.charAt(i-1) == fChar) && (i > 0)) {
resultString += "";
}
else {
resultString += char;
}
}
return (resultString);
}
อธิบายคือ
var resultString = "";กำหนดให้ resultString เป็น String ว่างๆ
for (var i = 0; i < target.length; i++) {เปิด for ... (อธิบายแล้ว)
var char = target.charAt(i);กำหนดตัวแปร char ให้เท่ากับตัวอักษรตัวที่ i (เมื่อ i = 0 ตัวแปร char เท่ากับตัวอักษรตัวแรก)
var fChar = "f";กำหนดตัวแปร fChar ให้เท่ากับตัวอักษร f เล็ก
var iChar = "i";กำหนดตัวแปร iChar ให้เท่ากับตัวอักษร i เล็ก
var fiChar = mbchr(0xFB01);กำหนดตัวแปร fiChar ให้เท่ากับตัวอักษร fi ที่ติดกัน (Ligature)
if ((char == fChar) && (target.charAt(i+1) == iChar) && (i+1 < target.length)) {ถ้าตัวอักษรตัวที่ i เป็นตัวอักษร f เล็ก (char == fChar)
และตัวอักษรตัวต่อไป (ตัวที่ i+1) เป็นตัว i เล็ก (target.charAt(i+1) == iChar)
และไม่เป็นตัวสุดท้ายของข้อความ (i+1 < target.length)
ให้
resultString += fiChar;เพิ่ม resultString เข้าด้วยตัวอักษร fi
else if ((char == iChar) && (target.charAt(i-1) == fChar) && (i > 0)) {ถ้าไม่ใช่อย่างข้างต้น แต่ตัวอักษรตัวที่ i เป็นตัวอักษร i เล็ก (char == iChar)
และตัวอักษรตัวก่อนหน้า (ตัวที่ i-1) เป็นตัว f เล็ก ซึ่งถูกแทนที่ด้วย fi ไปแล้ว
และตัวอักษรตัวที่ i นี้ไม่ใช่ตัวอักษรตัวแรก
resultString += "";ก็ไม่ต้องเพิ่มตัวอะไรเข้าไปใน resultString
else {และถ้านอกเหนือจากนี้
resultString += char;ก็ให้เพิ่มตัวอักษรตัวที่ i นั้นแหละ เข้าใน resultString
ดังนั้นเมื่อประมวลผลจน i >= target.length แล้ว resultString จะประกอบไปด้วยตัวอักษรที่ผ่านการกรั่นกรองแล้วทุกตัว
ตัวอย่างเช่น ข้อความ "fifa cup"
ตัวอักษรแรกเป็นตัว f และตัวอักษรต่อไปเป็นตัว i และไม่ได้เป็นตัวสุดท้าย
เพิ่ม fi เข้าใน resultString
จะได้ resultString ตอนนี้เป็น "fi"
ตัวอักษรตัวที่สองเป็นตัว i และก่อนหน้าเป็นตัว f และไม่ได้เป็นตัวแรก
ไม่ต้องเพิ่มอะไร (หรือเพิ่ม "") เข้าใน resultString
จะได้ resultString เป็น "fi" ดังเดิม
ตัวต่อไปอีก เป็นตัว f แต่ตัวต่อไปไม่ใช่ตัว i ดังนั้นเพิ่มตัว f เข้าไปใน resultString ดื้อๆ
และต่อไปเรื่อยๆ
สุดท้ายสั่งให้ return
ก็คือสั่งให้ส่งกลับค่านี้ออกมานั่นเอง
(return ตรงข้ามกับ trace คือต้องดึงกลับมาใช้ต่อ)
บางคนอาจเถียงว่า มันก็มีฟังก์ชั่นสำหรับ replace ใน ActionScript ไม่ใช่หรือ
ใช่ครับ แต่อันข้างบนนี่สาธิตเพื่อให้เข้าใจง่าย
แต่มันค่อนข้างประยุกต์ใช้ได้ดีกับการที่อักษรต้องมาเจอกันหลายตัว ไม่ใช่แค่สองตัวอย่าง fi
วิธีแรกที่สาธิตนี้ เหมือนตรวจสอบว่า A = B หรือเปล่า
ส่วนวิธีที่สองนี้ จะตรวจสอบว่า A เป็นสมาชิกของเซต B หรือเปล่า
เช่น
function fixFloat(target) {
var resultString = "";
for (var i = 0; i > target.length; i++) {
var char = target.charAt(i);
// สระปกติ อิอีอึอือัอํอ็
var vowel = mbchr(0x0E34)+mbchr(0x0E35)+mbchr(0x0E36)+mbchr(0x0E37)+mbchr(0x0E31)+mbchr(0x0E4D)+mbchr(0x0E47);
// สระหลบหาง ปิปีปึปืปัปํป็
var vowelAlt = mbchr(0xF701)+mbchr(0xF702)+mbchr(0xF703)+mbchr(0xF704)+mbchr(0xF710)+mbchr(0xF711)+mbchr(0xF712);
// ตัวอักษรหางยาว ปฟฝ
var longTail = mbchr(0x0E1B)+mbchr(0x0E1D)+mbchr(0x0E1F);
var vowelPos = vowel.indexOf(char);
// ถ้ามากกว่า -1 แสดงว่าเป็นสระ และสระอะไรต้องดูที่ค่า ถ้าเท่ากับ 0 จะเท่ากับสระอิหรือ mbchr(0x0E34) เป็นต้น
var afterLongTail = (longTail.indexOf(target.charAt(i-1)) > -1) && (i > 0);
// String.indexOf(character) ถ้าไม่มีตัวอักษรหรือ character อยู่ใน String จะตีกลับมาเป็น -1
if ((vowelPos > -1) && afterLongTail) {
var myVar = vowelAlt.charAt(vowelPos);
// เนื่องจากตัวอักษรตัวที่ 1 ของ vowel คือสระอิธรรมดา และตัวอักษรตัวที่ 1 ของ vowelAlt คือสระอิหลบหาง ปฟฝ
resultString += myVar;
}
else {
resultString += char;
}
}
return (resultString);
}
จะสั่งให้สระที่อยู่ด้านบนหลบหาง ปฝฟ เสีย
ยกตัวอย่างการนำไปใช้
สร้าง Dynamic TextField ขึ้นมาอันหนึ่ง
เสร็จแล้วตั้ง Instant Name ให้ สมมุติคือ ex
ใส่ ActionScript ประมาณนี้ลงไป
var myTxt = fixFloat("ปิิปีปึปืปัปํป็"); // กำหนดตัวแปร myTxt ซึ่งมีค่าเป็น ปิิปีปึปืปัปํป็ ที่ปรับให้หลบหาง ปฝฟ แล้ว
ex.text = myTxt; // กำหนดให้ข้อความใน ex เป็นตัวแปร myTxt
สรุปแนวคิดคือ พิจารณาตัวอักษรแต่ละตัวและถ้าจำเป็น ตัวก่อนหน้าและตัวหลัง กำหนดตัวแปรใหม่มาหนึ่งตัว แล้วถ้าเป็นไปตามเงื่อนไขที่กำหนด ให้เพิ่มตัวอักษรที่ต้องการให้เปลี่ยนไปเป็นหากเป็นไปตามเงื่อนไขเข้าในตัวแปรที่กำหนดขึ้นมาใหม่นั้น ถ้าไม่เป็นไปตามเงื่อนไข ให้เพิ่มตัวอักษรตัวนั้นแหละเข้าในตัวแปรที่กำหนดขึ้นมาใหม่
ครับ
