1Isometric คืออะไร
Isometric projection คือการมองวัตถุจากมุมสูง 30° โดยไม่มี perspective (ไม่ลดขนาดตามระยะ) — ทำให้ทุกด้านมีขนาดเท่ากัน ภาพดู "ลอย" อยู่บนพื้นหลัง
ใน SVG เราทำได้ด้วย transform เพียง 2 คำสั่ง:
| ค่า | คำสั่ง | ผลลัพธ์ |
|---|---|---|
skewY(30) | เอียงแกน Y 30° | ด้านขวาของลูกบาศก์ |
skewY(-30) | เอียงแกน Y -30° | ด้านซ้ายของลูกบาศก์ |
scale(1, 0.5) | ย่อความสูง 50% | ด้านบนของลูกบาศก์ |
💡 หลักการ: Isometric ไม่มี vanishing point — ทุกเส้นขนานกัน ต่างจาก perspective ที่เส้นจะบรรจบกันที่จุดไกล
2สร้างลูกบาศก์ลูกแรก — 3 สี 3 ด้าน
ลูกบาศก์ isometric มี 3 ด้านที่มองเห็น — แต่ละด้านสีต่างกันเพื่อสร้างความลึก:
ลูกบาศก์ Isometric — 3 ด้าน 3 สี
โค้ดลูกบาศก์
<!-- ด้านบน (สว่างสุด) -->
<polygon points="0,50 80,10 160,50 80,90"
fill="#60a5fa" stroke="#93c5fd" stroke-width="1"/>
<!-- ด้านซ้าย (สีกลาง) -->
<polygon points="0,50 0,130 80,170 80,90"
fill="#2563eb" stroke="#60a5fa" stroke-width="1"/>
<!-- ด้านขวา (เข้มสุด) -->
<polygon points="80,90 80,170 160,130 160,50"
fill="#1e40af" stroke="#3b82f6" stroke-width="1"/>
💡 ทำไม 3 สี? ด้านบนรับแสงมากสุด → สว่าง · ด้านซ้ายรับแสงปานกลาง · ด้านขวาไม่รับแสง → เข้มสุด หลักการเดียวกับ lighting ใน 3D
วาดหน้าต่างด้วย polygon
สำคัญ! ห้ามใช้ <rect> + skewY — จะลอยสูงกว่าผนัง ต้องวาดเป็น <polygon> 4 จุดตาม perspective:
<!-- ด้านขวา: shift ลงเมื่อขยับขวา (slope ลง) -->
<polygon points="x,y x+w,y+shift x+w,y+h+shift x,y+h"/>
<!-- ตัวอย่าง: หน้าต่างกว้าง 14 สูง 10 ที่จุด (72,53) -->
<polygon points="72,53 86,61 86,71 72,63"/>
<!-- ด้านซ้าย: shift ขึ้นเมื่อขยับขวา (slope ขึ้น) -->
<polygon points="x,y x+w,y-shift x+w,y+h-shift x,y+h"/>
<!-- ตัวอย่าง: หน้าต่างกว้าง 14 สูง 10 ที่จุด (8,45) -->
<polygon points="8,45 22,37 22,47 8,55"/>
3ตึก isometric — ต่อเติมจากลูกบาศก์
ตึก isometric คือลูกบาศก์ที่ "ยืด" ขึ้น — เปลี่ยนแค่ค่า points ของ polygon:
ตึก Isometric — 3 ขนาด
สูตรคำนวณจุด polygon
// ลูกบาศก์ isometric กว้าง w สูง h ลึก d
// จุดกึ่งกลาง = (cx, cy)
top: (cx, cy-d) → (cx+w/2, cy-d+h/2) → (cx+w, cy-d) → (cx+w/2, cy-d-h/2)
left: (cx, cy-d) → (cx, cy-d+h) → (cx+w/2, cy+h/2) → (cx+w/2, cy-d-h/2)
right: (cx+w/2, cy-d-h/2) → (cx+w/2, cy+h/2) → (cx+w, cy-d+h) → (cx+w, cy-d)
// ตัวอย่าง: w=120, h=60, d=30
top: "60,0 120,30 180,0 120,-30"
left: "60,0 60,60 120,90 120,30"
right: "120,30 120,90 180,60 180,0"
4เมือง isometric — วางตึกหลายหลัง
เมื่อเข้าใจลูกบาศก์เดี่ยวแล้ว การสร้างเมืองแค่วางตึกหลายชุดบน grid เดียวกัน:
Isometric City — เมืองจำลอง
5Isometric Grid — เส้นนำทาง
Grid isometric ช่วยให้วางวัตถุได้ตรงตำแหน่ง — สร้างด้วย <pattern>:
Isometric Grid Pattern
<defs>
<pattern id="isoGrid" width="80" height="46"
patternUnits="userSpaceOnUse">
<!-- ทแยงซ้าย -->
<line x1="0" y1="23" x2="40" y2="0"
stroke="#1e293b" stroke-width="0.8"/>
<line x1="40" y1="46" x2="80" y2="23"
stroke="#1e293b" stroke-width="0.8"/>
<!-- ทแยงขวา -->
<line x1="0" y1="23" x2="40" y2="46"
stroke="#1e293b" stroke-width="0.8"/>
<line x1="40" y1="0" x2="80" y2="23"
stroke="#1e293b" stroke-width="0.8"/>
</pattern>
</defs>
<rect fill="url(#isoGrid)" .../>
6ต้นไม้ & ฉาก — เพิ่มชีวิตให้เมือง
Isometric Objects — ต้นไม้, กล่อง, บันได, น้ำพุ
7แสงเงา isometric — Gradient + Shadow
แสงเงา 3 แบบ — Flat, Gradient, Shadow
สรุปเทคนิคแสงเงา
| เทคนิค | วิธีทำ | เหมาะกับ |
|---|---|---|
| Flat | 3 สีต่างกัน (สว่าง/กลาง/เข้ม) | Minimal, icon |
| Gradient | <linearGradient> ซ้อนบน polygon | แสงจากทิศทางเดียว |
| Drop Shadow | <filter> + feDropShadow | ลอยจากพื้นหลัง |
| Highlight | rect semi-transparent ทับด้านสว่าง | แสงสะท้อน, glow |
8เทคนิคขั้นสูง
8.1 Clipping — ตัดวัตถุให้พอดี grid
<defs>
<clipPath id="tileClip">
<polygon points="350,300 550,200 350,100 150,200"/>
</clipPath>
</defs>
<g clip-path="url(#tileClip)">
<!-- วัตถุทั้งหมดจะถูกตัดให้พอดี tile -->
</g>
8.2 Animation — หมุนวัตถุ
<g>
<animateTransform attributeName="transform"
type="rotate" from="0 100 100" to="360 100 100"
dur="10s" repeatCount="indefinite"/>
<polygon .../>
</g>
8.3 Pattern — พื้นผิวอิฐ/กระเบื้อง
<defs>
<pattern id="brickIso" width="20" height="12"
patternUnits="userSpaceOnUse"
patternTransform="skewY(30)">
<rect width="20" height="12" fill="#991b1b"/>
<rect x="0" y="0" width="9" height="5"
fill="#b91c1c" stroke="#450a0a" stroke-width="0.3"/>
<rect x="11" y="0" width="9" height="5"
fill="#b91c1c" stroke="#450a0a" stroke-width="0.3"/>
<rect x="5" y="6" width="9" height="5"
fill="#b91c1c" stroke="#450a0a" stroke-width="0.3"/>
</pattern>
</defs>
<polygon fill="url(#brickIso)" .../>
9สรุป & Cheat Sheet
🗺️ Isometric SVG Cheat Sheet:
| สิ่งที่ต้องการ | SVG Element / Property |
|---|---|
| ด้านบน (สว่าง) | <polygon> สีสว่างสุด |
| ด้านขวา (กลาง) | <polygon> สีกลาง + skewY(30) |
| ด้านซ้าย (เข้ม) | <polygon> สีเข้ม + skewY(-30) |
| หน้าต่างขวา | <polygon> 4 จุด ตาม perspective |
| หน้าต่างซ้าย | <polygon> 4 จุด ตาม perspective |
| เงา | <filter> + feDropShadow |
| แสง | <linearGradient> ซ้อน polygon |
| Grid | <pattern> เส้นทแยง 30° |
| ตัดขอบ | <clipPath> |
| จัดกลุ่ม | <g transform="translate(x,y)"> |
| หมุน | <animateTransform> |
สูตรสำคัญ
// มุม isometric 标准
// แกน X: skewY(-30) → เอียงซ้าย 30°
// แกน Y: skewY(30) → เอียงขวา 30°
// แกน Z: ไม่ต้องทำอะไร (ตั้งตรง)
// ความสูงของลูกบาศก์ = h
// ด้านบน: y ลดลง h/2 (diamond shape)
// ด้านซ้าย: y เพิ่มขึ้น h
// ด้านขวา: y เพิ่มขึ้น h
// ขนาดไม่เปลี่ยนตามระยะ (ไม่มี perspective)
// ทุกวัตถุขนานกันหมด
⚠️ ข้อควรระวัง:
- อย่าใช้
transform: perspective()ใน SVG — ไม่รองรับ ต้องใช้ skew แทน skewY(30)ไม่ใช่ 30° จริงๆ — เป็นการ shearing ไม่ใช่ rotation- หน้าต่างใช้
<polygon>ห้ามใช้<rect>+ skewY — จะลอยสูงกว่าผนัง! วาดเป็น 4 จุดตาม perspective ของแต่ละด้าน - ด้านขวา: จุดขวาบนลงล่าง + shift ลง · ด้านซ้าย: จุดขวาบนลงล่าง + shift ขึ้น
- ทดสอบทุกครั้งว่า polygon points ตรงกับขนาดที่ต้องการ