ทดลองทำเว็บวาดรูปเป็น pixel art ด้วย Svelte แบบง่าย ๆ กันเถอะ

Programming Mar 24, 2023

จริงๆก็ดองมาสักพักใหญ่ๆแล้วหล่ะ ตอนนั้นพี่นาตรไลฟ์สตรีมสอนทำเว็บ r/place ที่ให้ช่องแชทพิมพ์ command เพื่อวาดรูปบนสตรีมได้ ทางเราเลยจดมานิดหน่อยแล้วลองทำดูจ้า

อันนี้จะเป็น flow การทำงานของ r/place และ streamie เนอะ ซึ่งในที่นี้ เราจะทำแค่หน้าเว็บที่เป็น r/place เท่านั้น เป็นเว็บที่วาด pixel art ก็แล้วกันเนอะ

อันนี้คือโพยที่มี

ขั้นตอนการทำ

ปล. เนื่องจากบล็อกนี้ร่างไว้นานแล้ว ไม่แน่ใจว่าจุดที่พังจาก svelte เขาแก้ไปหรือยัง

สร้างหน้าเว็บสำหรับ pixel board

ขั้นตอนแรกของพี่นาตร คือ การสร้าง place.svelte ซึ่งอยู่ใน src/route แหละ แต่ด้วยความที่ตอนนี้เราทำอยู่ในหน้าเว็บเดียว และไม่รู้ว่าจะมีอะไรยัดไปอีกไหม ก็เลยไปไว้ที่ index.svelte ไปก่อนแล้วกันเนอะ (หรือทำอันใหม่แล้วแยกโปรเจกดีไหมนะ แบบแยกเรื่องไป)

จริงๆใช้ Tailwind CSS ในการจัด style ของเว็บนี้ แต่เรายังไม่ค่อยคล่องเท่าไหร่ เลยอาจจะจัดให้สวยงามทีหลัง

เอาฤกษ์เอาชัยด้วยการ สร้าง text header ของเว็บไว้ด้านบนก่อน ชื่อว่า Pixel Art Board!

<h1 class="text-center">Pixel Art Board!</h1>

แต่ตอนทำติดปัญหาที่ตัว Svelte Kit เอง ที่ด๊านนน ไม่ดึง %svelte.assets และผองเพื่อนมาให้ พอนำ error ที่ได้ไป search พบว่าเป็นบัคหรืออัพเดตสักอย่างของเขาเอง

Error: %svelte.assets% in src/app.html should be replaced with %sveltekit.assets%

ดังนั้นจะต้องเปลี่ยนเป็น %sveltekit.assets พร้อมกับแก้ผองเพื่อนทั้งหมด ถึงจะรันได้ เฮ้อออออ

Creating a SvelteKit app is broken with recent changes to SvelteKit · Issue #206 · svelte-add/svelte-add
I just wanted to create a new svelte app with svelte-add, but when I typed npm run dev, my browser tells me Error: %svelte.assets% in src/app.html should be replaced with %sveltekit.assets% at load...
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="description" content="" />
		<link rel="icon" href="%sveltekit.assets%/favicon.png" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		%sveltekit.head%
	</head>
	<body>
		<div>%sveltekit.body%</div>
	</body>
</html>

เมื่อแก้ได้แล้วจะได้หน้าเว็บที่มีคำอยู่ตรงกลางหล่ะ

ส่วนประกอบที่จะทำในหน้าเว็บนี้

เราทำ UI หน้าเว็บนี้ในกระดาษคร่าวๆ แบ่งเป็น 3 ส่วน คือ

  • color picker เอาไว้เปลี่ยนสี กับ clear board ทิ้ง
  • ตัว pixel board
  • button ที่เอาไว้ import, export, save รูป และอาจจะมิ้นรูปตรงนี้ ;P

ทำตัว pixel board ก่อน

ต่อมาทำตัว pixel board กัน อันนี้เอาโพยพี่นาตรที่ได้ตอนดูสตรีมวันโน้น มาลองทำดู พร้อมพลังของ Github Copilot

สิ่งที่ต้องทำมี 2 ส่วน คือ ส่วนบน และส่วนล่างนั่นเอง (ห๊ะ งี้ก็ได้ด้วยหรอ?)

ทำส่วน script เพิ่มที่ด้านบน เป็นภาษา TypeScript โดยเราจะทำเป็นตาราง 32 x 32 ดังนั้นจะประกาศตัวแปร width เป็น 32 และ height เป็น 32

จากนั้นสร้างตัวแปร board เป็น array 2 มิติ

จบด้วยการสร้าง functioon ที่ชื่อว่า paint มี 3 parameter ก็คือ x y และสี เอามาใช้ตอนกดในแต่ละช่องเนอะ

<script lang="ts">
    const width = 32
    const height = 32

    const board: string[][] = Array(height)
        .fill(0)
        .map(() => Array(width).fill(""))

    function paint(x: number, y: number, color: string) {
        board[y][x] = color
    }
</script>

ด้านล่างเป็น html ที่มี text title รอเพื่อนอยู่อันนึง เราก็เอาไปต่อท้ายก่อนแล้วกัน

ตรงนี้เราจะใช้ for-loop วน 2 ชั้น ชั้นนนอกวน row ชั้นในวน column จนวาดตารางครบ 32 x 32 เนอะ ตัวช่องของตารางจะเป็น flex

ตัว View สามารถคลิกได้ คลิกแล้วทำอะไรต่อ ก็ทำการเรียก function paint เพื่อใส่สีที่เราต้องการนั่นเอง ในที่นี้ random สีมาก่อน เพื่อดูการทำงานแล้วทำได้ไหม ทำได้หรือเปล่า

<h1 class="text-center my-12">Pixel Art Board!</h1>
        
        <!-- board 32 x 32 -->
        {#each board as row, rowIndex}
            <div class="flex">
            {#each row as column, columnIndex}
                <div 
                    class="flex flex-row border h-4 w-4 border-gray-100" 
                    style={`background-color: #${column}; border-color: #${column}`}
                    on:click={() => 
                        paint(columnIndex, rowIndex, Math.floor(Math.random() * 16777215).toString(16))}
                >
                </div>
            {/each}
            </div>
        {/each}

ผลที่ได้ เมื่อเราจิ้มไปที่ช่อง ช่องนั้นจะถูกถมสีลงไป ถ้ากดซํ้า สีก็จะเปลี่ยน

ในโพยที่มีนั้น เขาจะมีการ check เรื่อง overflow ด้วย เนื่องจากรับ input จากทางช่องแชทอะเนอะ

อันนี้สตรีมย้อนหลังฮับ

https://www.youtube.com/watch?v=b97hntdMzw4

หลังจากนี้จะทำอะไรต่อนะ

ถ้ามีเวลาจะสร้างปุ่ม color picker และ clear board ทิ้ง

จริงๆเรากด F5 มันก็ clear ทิ้งแล้วนะ แต่เราอำนวยความสะดวกให้ user ไง และอาจจะเผื่อทำการ save cache อะไรแบบนี้ในอนาคตได้งี้

แนวคิดในหัว คือ user จะต้องเลือกสีได้ โดยการจิ้มสีใน View ของ color picker หรือใส่รหัสสีเองได้ จากนั้นนำค่าพวกนั้นมาใส่แทนเลขสีที่ random นะ

ตัว color picker เนี่ย เราไม่ได้เขียนเองนะ ไปเจอมาอีกทีนึง

Svelte app
https://efeskucuk.github.io/svelte-color-picker/

ที่ลองทำก็จะประมาณนี้นะทุกคน


ติดตามข่าวสารตามช่องทางต่าง ๆ และทุกช่องทางโดเนทกันไว้ที่นี่เลย

ติดตามข่าวสารแบบไว ๆ มาที่ Twitter เลย บางอย่างไม่มีในบล็อก และหน้าเพจนะ

Tags

Minseo Chayabanjonglerd

I am a full-time Android Developer and part-time contributor with developer community and web3 world, who believe people have hard skills and soft skills to up-skill to da moon.