[{"data":1,"prerenderedAt":704},["ShallowReactive",2],{"blog-canvas-basics":3},{"id":4,"title":5,"body":6,"description":15,"extension":694,"meta":695,"navigation":102,"path":700,"seo":701,"stem":702,"__hash__":703},"blog\u002Fblog\u002Fcanvas-basics.md","HTML5 Canvas Basics: Getting Started with 2D Games",{"type":7,"value":8,"toc":692},"minimark",[9,688],[10,11,12,371],"i18n-text",{},[13,14,16,20,24,29,32,55,67,76,116,123,130,157,227,231,234,297,311,314],"template",{"v-slot:en":15},"",[17,18,5],"h1",{"id":19},"html5-canvas-basics-getting-started-with-2d-games",[21,22,23],"p",{},"HTML5 Canvas is a powerful tool for rendering 2D graphics in the browser, making it the perfect starting point for web-based game development. Let's explore the fundamental methods you'll use constantly.",[25,26,28],"h2",{"id":27},"_1-setting-up-the-context","1. Setting Up the Context",[21,30,31],{},"Before you can draw anything, you need to get the canvas element and its 2D rendering context:",[33,34,38],"pre",{"className":35,"code":36,"language":37,"meta":15,"style":15},"language-javascript shiki shiki-themes github-light github-dark","const canvas = document.getElementById('myCanvas');\nconst ctx = canvas.getContext('2d');\n","javascript",[39,40,41,49],"code",{"__ignoreMap":15},[42,43,46],"span",{"class":44,"line":45},"line",1,[42,47,48],{},"const canvas = document.getElementById('myCanvas');\n",[42,50,52],{"class":44,"line":51},2,[42,53,54],{},"const ctx = canvas.getContext('2d');\n",[25,56,58,59,62,63,66],{"id":57},"_2-drawing-rectangles-fillrect-strokerect","2. Drawing Rectangles (",[39,60,61],{},"fillRect"," & ",[39,64,65],{},"strokeRect",")",[21,68,69,70,72,73,75],{},"Rectangles are the most basic shape. ",[39,71,61],{}," draws a filled rectangle, while ",[39,74,65],{}," draws its outline.",[33,77,79],{"className":35,"code":78,"language":37,"meta":15,"style":15},"ctx.fillStyle = 'blue'; \u002F\u002F Determine inner color\n\u002F\u002F x, y, width, height\nctx.fillRect(10, 10, 50, 50); \u002F\u002F Draws a 50x50 blue square at x:10, y:10\n\nctx.strokeStyle = 'red'; \u002F\u002F Determine border color\nctx.strokeRect(70, 10, 50, 50); \u002F\u002F Draws a red outline\n",[39,80,81,86,91,97,104,110],{"__ignoreMap":15},[42,82,83],{"class":44,"line":45},[42,84,85],{},"ctx.fillStyle = 'blue'; \u002F\u002F Determine inner color\n",[42,87,88],{"class":44,"line":51},[42,89,90],{},"\u002F\u002F x, y, width, height\n",[42,92,94],{"class":44,"line":93},3,[42,95,96],{},"ctx.fillRect(10, 10, 50, 50); \u002F\u002F Draws a 50x50 blue square at x:10, y:10\n",[42,98,100],{"class":44,"line":99},4,[42,101,103],{"emptyLinePlaceholder":102},true,"\n",[42,105,107],{"class":44,"line":106},5,[42,108,109],{},"ctx.strokeStyle = 'red'; \u002F\u002F Determine border color\n",[42,111,113],{"class":44,"line":112},6,[42,114,115],{},"ctx.strokeRect(70, 10, 50, 50); \u002F\u002F Draws a red outline\n",[25,117,119,120,66],{"id":118},"_3-drawing-circles-and-arcs-arc","3. Drawing Circles and Arcs (",[39,121,122],{},"arc",[21,124,125,126,129],{},"To draw circles or curves, you define a path and use ",[39,127,128],{},"arc(x, y, radius, startAngle, endAngle, counterclockwise)",". Note that angles are measured in radians, not degrees.",[131,132,133,141,147],"ul",{},[134,135,136,140],"li",{},[137,138,139],"strong",{},"x, y:"," the coordinates of the arc's center.",[134,142,143,146],{},[137,144,145],{},"radius:"," the arc's radius.",[134,148,149,152,153,156],{},[137,150,151],{},"startAngle, endAngle:"," starting and ending angle in radians (A full circle is ",[39,154,155],{},"2 * Math.PI",").",[33,158,160],{"className":35,"code":159,"language":37,"meta":15,"style":15},"ctx.beginPath(); \u002F\u002F Start a new path\n\u002F\u002F x: 100, y: 75, radius: 50\n\u002F\u002F startAngle: 0, endAngle: 2 * Math.PI (a full circle)\nctx.arc(100, 75, 50, 0, 2 * Math.PI); \nctx.fillStyle = 'yellow';\nctx.fill();\n\n\u002F\u002F Drawing a half-circle outline (arc)\nctx.beginPath();\nctx.arc(200, 75, 40, 0, Math.PI); \u002F\u002F Half circle (180 degrees)\nctx.strokeStyle = 'green';\nctx.stroke();\n",[39,161,162,167,172,177,182,187,192,197,203,209,215,221],{"__ignoreMap":15},[42,163,164],{"class":44,"line":45},[42,165,166],{},"ctx.beginPath(); \u002F\u002F Start a new path\n",[42,168,169],{"class":44,"line":51},[42,170,171],{},"\u002F\u002F x: 100, y: 75, radius: 50\n",[42,173,174],{"class":44,"line":93},[42,175,176],{},"\u002F\u002F startAngle: 0, endAngle: 2 * Math.PI (a full circle)\n",[42,178,179],{"class":44,"line":99},[42,180,181],{},"ctx.arc(100, 75, 50, 0, 2 * Math.PI); \n",[42,183,184],{"class":44,"line":106},[42,185,186],{},"ctx.fillStyle = 'yellow';\n",[42,188,189],{"class":44,"line":112},[42,190,191],{},"ctx.fill();\n",[42,193,195],{"class":44,"line":194},7,[42,196,103],{"emptyLinePlaceholder":102},[42,198,200],{"class":44,"line":199},8,[42,201,202],{},"\u002F\u002F Drawing a half-circle outline (arc)\n",[42,204,206],{"class":44,"line":205},9,[42,207,208],{},"ctx.beginPath();\n",[42,210,212],{"class":44,"line":211},10,[42,213,214],{},"ctx.arc(200, 75, 40, 0, Math.PI); \u002F\u002F Half circle (180 degrees)\n",[42,216,218],{"class":44,"line":217},11,[42,219,220],{},"ctx.strokeStyle = 'green';\n",[42,222,224],{"class":44,"line":223},12,[42,225,226],{},"ctx.stroke();\n",[25,228,230],{"id":229},"_4-advanced-colors-and-linear-gradients","4. Advanced Colors and Linear Gradients",[21,232,233],{},"You can set colors using standard CSS color names, HEX, RGB, or RGBA for transparency. You can also create gradients!",[33,235,237],{"className":35,"code":236,"language":37,"meta":15,"style":15},"\u002F\u002F Simple color transparency using RGBA\nctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; \u002F\u002F 50% transparent red\n\n\u002F\u002F Creating a Linear Gradient: createLinearGradient(x0, y0, x1, y1)\n\u002F\u002F The parameters represent the start (x0, y0) and end (x1, y1) point\nconst gradient = ctx.createLinearGradient(0, 0, 150, 0); \u002F\u002F Horizontal gradient\ngradient.addColorStop(0, 'red');      \u002F\u002F Start color at offset 0\ngradient.addColorStop(0.5, 'yellow'); \u002F\u002F Middle color at offset 0.5\ngradient.addColorStop(1, 'green');    \u002F\u002F End color at offset 1\n\nctx.fillStyle = gradient; \u002F\u002F Set gradient as the fill style\nctx.fillRect(10, 150, 150, 50);\n",[39,238,239,244,249,253,258,263,268,273,278,283,287,292],{"__ignoreMap":15},[42,240,241],{"class":44,"line":45},[42,242,243],{},"\u002F\u002F Simple color transparency using RGBA\n",[42,245,246],{"class":44,"line":51},[42,247,248],{},"ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; \u002F\u002F 50% transparent red\n",[42,250,251],{"class":44,"line":93},[42,252,103],{"emptyLinePlaceholder":102},[42,254,255],{"class":44,"line":99},[42,256,257],{},"\u002F\u002F Creating a Linear Gradient: createLinearGradient(x0, y0, x1, y1)\n",[42,259,260],{"class":44,"line":106},[42,261,262],{},"\u002F\u002F The parameters represent the start (x0, y0) and end (x1, y1) point\n",[42,264,265],{"class":44,"line":112},[42,266,267],{},"const gradient = ctx.createLinearGradient(0, 0, 150, 0); \u002F\u002F Horizontal gradient\n",[42,269,270],{"class":44,"line":194},[42,271,272],{},"gradient.addColorStop(0, 'red');      \u002F\u002F Start color at offset 0\n",[42,274,275],{"class":44,"line":199},[42,276,277],{},"gradient.addColorStop(0.5, 'yellow'); \u002F\u002F Middle color at offset 0.5\n",[42,279,280],{"class":44,"line":205},[42,281,282],{},"gradient.addColorStop(1, 'green');    \u002F\u002F End color at offset 1\n",[42,284,285],{"class":44,"line":211},[42,286,103],{"emptyLinePlaceholder":102},[42,288,289],{"class":44,"line":217},[42,290,291],{},"ctx.fillStyle = gradient; \u002F\u002F Set gradient as the fill style\n",[42,293,294],{"class":44,"line":223},[42,295,296],{},"ctx.fillRect(10, 150, 150, 50);\n",[25,298,300,301,304,305,304,308,66],{"id":299},"_5-rendering-advanced-text-filltext-textalign-textbaseline","5. Rendering Advanced Text (",[39,302,303],{},"fillText",", ",[39,306,307],{},"textAlign",[39,309,310],{},"textBaseline",[21,312,313],{},"Rendering text on a canvas is straightforward, but you can also control its alignment and baseline (vertical origin point).",[33,315,317],{"className":35,"code":316,"language":37,"meta":15,"style":15},"ctx.font = '24px Arial'; \u002F\u002F Define font family and size\nctx.fillStyle = 'white';\n\n\u002F\u002F Horizontal alignment (left, center, right, start, end)\nctx.textAlign = 'center'; \n\n\u002F\u002F Vertical alignment (top, hanging, middle, alphabetic, ideographic, bottom)\nctx.textBaseline = 'middle'; \n\n\u002F\u002F Drawing the text (text string, x, y)\nctx.fillText('Center Aligned Text', canvas.width \u002F 2, canvas.height \u002F 2);\n",[39,318,319,324,329,333,338,343,347,352,357,361,366],{"__ignoreMap":15},[42,320,321],{"class":44,"line":45},[42,322,323],{},"ctx.font = '24px Arial'; \u002F\u002F Define font family and size\n",[42,325,326],{"class":44,"line":51},[42,327,328],{},"ctx.fillStyle = 'white';\n",[42,330,331],{"class":44,"line":93},[42,332,103],{"emptyLinePlaceholder":102},[42,334,335],{"class":44,"line":99},[42,336,337],{},"\u002F\u002F Horizontal alignment (left, center, right, start, end)\n",[42,339,340],{"class":44,"line":106},[42,341,342],{},"ctx.textAlign = 'center'; \n",[42,344,345],{"class":44,"line":112},[42,346,103],{"emptyLinePlaceholder":102},[42,348,349],{"class":44,"line":194},[42,350,351],{},"\u002F\u002F Vertical alignment (top, hanging, middle, alphabetic, ideographic, bottom)\n",[42,353,354],{"class":44,"line":199},[42,355,356],{},"ctx.textBaseline = 'middle'; \n",[42,358,359],{"class":44,"line":205},[42,360,103],{"emptyLinePlaceholder":102},[42,362,363],{"class":44,"line":211},[42,364,365],{},"\u002F\u002F Drawing the text (text string, x, y)\n",[42,367,368],{"class":44,"line":217},[42,369,370],{},"ctx.fillText('Center Aligned Text', canvas.width \u002F 2, canvas.height \u002F 2);\n",[13,372,373,377,380,384,387,399,407,416,450,456,462,481,539,546,552,620,630,633],{"v-slot:id":15},[17,374,376],{"id":375},"dasar-dasar-html5-canvas-memulai-game-2d","Dasar-Dasar HTML5 Canvas: Memulai Game 2D",[21,378,379],{},"HTML5 Canvas adalah fitur kuat untuk me-render grafis 2D di browser, menjadikannya titik awal yang sempurna untuk pengembangan game berbasis web. Mari kita pelajari metode dasar yang akan sering Anda gunakan.",[25,381,383],{"id":382},"_1-menyiapkan-context-konteks","1. Menyiapkan Context (Konteks)",[21,385,386],{},"Sebelum bisa menggambar, Anda harus mengambil elemen canvas dan konteks rendering 2D-nya:",[33,388,389],{"className":35,"code":36,"language":37,"meta":15,"style":15},[39,390,391,395],{"__ignoreMap":15},[42,392,393],{"class":44,"line":45},[42,394,48],{},[42,396,397],{"class":44,"line":51},[42,398,54],{},[25,400,402,403,62,405,66],{"id":401},"_2-menggambar-persegi-panjang-fillrect-strokerect","2. Menggambar Persegi Panjang (",[39,404,61],{},[39,406,65],{},[21,408,409,410,412,413,415],{},"Persegi panjang adalah bentuk paling dasar. ",[39,411,61],{}," menggambar bentuk berserta isinya, sedangkan ",[39,414,65],{}," hanya menggambar garis luarnya saja.",[33,417,419],{"className":35,"code":418,"language":37,"meta":15,"style":15},"ctx.fillStyle = 'blue'; \u002F\u002F Menentukan warna isian\n\u002F\u002F posis_x, posisi_y, lebar, tinggi\nctx.fillRect(10, 10, 50, 50); \u002F\u002F Kotak biru 50x50 pada posisi x:10, y:10\n\nctx.strokeStyle = 'red'; \u002F\u002F Menentukan warna perbatasan outline\nctx.strokeRect(70, 10, 50, 50); \u002F\u002F Membuat kotak garis merah\n",[39,420,421,426,431,436,440,445],{"__ignoreMap":15},[42,422,423],{"class":44,"line":45},[42,424,425],{},"ctx.fillStyle = 'blue'; \u002F\u002F Menentukan warna isian\n",[42,427,428],{"class":44,"line":51},[42,429,430],{},"\u002F\u002F posis_x, posisi_y, lebar, tinggi\n",[42,432,433],{"class":44,"line":93},[42,434,435],{},"ctx.fillRect(10, 10, 50, 50); \u002F\u002F Kotak biru 50x50 pada posisi x:10, y:10\n",[42,437,438],{"class":44,"line":99},[42,439,103],{"emptyLinePlaceholder":102},[42,441,442],{"class":44,"line":106},[42,443,444],{},"ctx.strokeStyle = 'red'; \u002F\u002F Menentukan warna perbatasan outline\n",[42,446,447],{"class":44,"line":112},[42,448,449],{},"ctx.strokeRect(70, 10, 50, 50); \u002F\u002F Membuat kotak garis merah\n",[25,451,453,454,66],{"id":452},"_3-menggambar-lingkaran-dan-arc-arc","3. Menggambar Lingkaran dan Arc (",[39,455,122],{},[21,457,458,459,461],{},"Untuk menggambar lingkaran, Anda harus membuat lintasan (path) menggunakan metode ",[39,460,128],{},". Perhatikan bahwa perhitungan sudut menggunakan metrik ukur radian, bukan derajat.",[131,463,464,469,474],{},[134,465,466,468],{},[137,467,139],{}," Titik tengah pusat lingkaran.",[134,470,471,473],{},[137,472,145],{}," Jari-jari lingkaran\u002Fkurva.",[134,475,476,478,479,156],{},[137,477,151],{}," Titik awal dan akhir derajat lengkungan dalam hitungan radian (Lingkaran penuh adalah ",[39,480,155],{},[33,482,484],{"className":35,"code":483,"language":37,"meta":15,"style":15},"ctx.beginPath(); \u002F\u002F Memulai lintasan jalur gambar baru\n\u002F\u002F x: 100, y: 75, radius (jari-jari): 50\n\u002F\u002F startAngle: 0, endAngle: 2 * Math.PI (lingkaran penuh \u002F 360 derajat)\nctx.arc(100, 75, 50, 0, 2 * Math.PI); \nctx.fillStyle = 'yellow';\nctx.fill();\n\n\u002F\u002F Menggambar setengah lingkaran (hanya garis lintasan lengkung)\nctx.beginPath();\nctx.arc(200, 75, 40, 0, Math.PI); \u002F\u002F Setengah lingkaran (180 derajat)\nctx.strokeStyle = 'green';\nctx.stroke();\n",[39,485,486,491,496,501,505,509,513,517,522,526,531,535],{"__ignoreMap":15},[42,487,488],{"class":44,"line":45},[42,489,490],{},"ctx.beginPath(); \u002F\u002F Memulai lintasan jalur gambar baru\n",[42,492,493],{"class":44,"line":51},[42,494,495],{},"\u002F\u002F x: 100, y: 75, radius (jari-jari): 50\n",[42,497,498],{"class":44,"line":93},[42,499,500],{},"\u002F\u002F startAngle: 0, endAngle: 2 * Math.PI (lingkaran penuh \u002F 360 derajat)\n",[42,502,503],{"class":44,"line":99},[42,504,181],{},[42,506,507],{"class":44,"line":106},[42,508,186],{},[42,510,511],{"class":44,"line":112},[42,512,191],{},[42,514,515],{"class":44,"line":194},[42,516,103],{"emptyLinePlaceholder":102},[42,518,519],{"class":44,"line":199},[42,520,521],{},"\u002F\u002F Menggambar setengah lingkaran (hanya garis lintasan lengkung)\n",[42,523,524],{"class":44,"line":205},[42,525,208],{},[42,527,528],{"class":44,"line":211},[42,529,530],{},"ctx.arc(200, 75, 40, 0, Math.PI); \u002F\u002F Setengah lingkaran (180 derajat)\n",[42,532,533],{"class":44,"line":217},[42,534,220],{},[42,536,537],{"class":44,"line":223},[42,538,226],{},[25,540,542,543,66],{"id":541},"_4-warna-lanjutan-dan-gradien-linear-createlineargradient","4. Warna Lanjutan dan Gradien Linear (",[39,544,545],{},"createLinearGradient",[21,547,548,549,551],{},"Anda dapat mengatur transparansi dengan nilai RGBA, dan juga membuat transisi gradien warna menggunakan ",[39,550,545],{},".",[33,553,555],{"className":35,"code":554,"language":37,"meta":15,"style":15},"\u002F\u002F Mengatur transparansi warna 50%\nctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; \u002F\u002F Merah yang 50% transparan\n\n\u002F\u002F Membuat Gradien Linear: createLinearGradient(x0, y0, x1, y1)\n\u002F\u002F Parameter menentukan titik mula (x0, y0) sampai selesai (x1, y1)\nconst gradient = ctx.createLinearGradient(0, 0, 150, 0); \u002F\u002F Gradien secara horizontal\ngradient.addColorStop(0, 'red');      \u002F\u002F Warna awal di offset 0\ngradient.addColorStop(0.5, 'yellow'); \u002F\u002F Warna tengah di offset 0.5\ngradient.addColorStop(1, 'green');    \u002F\u002F Warna akhir di offset 1\n\n\u002F\u002F Menerapkan objek gradien kepada style sebelum digambar\nctx.fillStyle = gradient;\nctx.fillRect(10, 150, 150, 50);\n",[39,556,557,562,567,571,576,581,586,591,596,601,605,610,615],{"__ignoreMap":15},[42,558,559],{"class":44,"line":45},[42,560,561],{},"\u002F\u002F Mengatur transparansi warna 50%\n",[42,563,564],{"class":44,"line":51},[42,565,566],{},"ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; \u002F\u002F Merah yang 50% transparan\n",[42,568,569],{"class":44,"line":93},[42,570,103],{"emptyLinePlaceholder":102},[42,572,573],{"class":44,"line":99},[42,574,575],{},"\u002F\u002F Membuat Gradien Linear: createLinearGradient(x0, y0, x1, y1)\n",[42,577,578],{"class":44,"line":106},[42,579,580],{},"\u002F\u002F Parameter menentukan titik mula (x0, y0) sampai selesai (x1, y1)\n",[42,582,583],{"class":44,"line":112},[42,584,585],{},"const gradient = ctx.createLinearGradient(0, 0, 150, 0); \u002F\u002F Gradien secara horizontal\n",[42,587,588],{"class":44,"line":194},[42,589,590],{},"gradient.addColorStop(0, 'red');      \u002F\u002F Warna awal di offset 0\n",[42,592,593],{"class":44,"line":199},[42,594,595],{},"gradient.addColorStop(0.5, 'yellow'); \u002F\u002F Warna tengah di offset 0.5\n",[42,597,598],{"class":44,"line":205},[42,599,600],{},"gradient.addColorStop(1, 'green');    \u002F\u002F Warna akhir di offset 1\n",[42,602,603],{"class":44,"line":211},[42,604,103],{"emptyLinePlaceholder":102},[42,606,607],{"class":44,"line":217},[42,608,609],{},"\u002F\u002F Menerapkan objek gradien kepada style sebelum digambar\n",[42,611,612],{"class":44,"line":223},[42,613,614],{},"ctx.fillStyle = gradient;\n",[42,616,618],{"class":44,"line":617},13,[42,619,296],{},[25,621,623,624,304,626,304,628,66],{"id":622},"_5-menampilkan-teks-lanjutan-filltext-textalign-textbaseline","5. Menampilkan Teks Lanjutan (",[39,625,303],{},[39,627,307],{},[39,629,310],{},[21,631,632],{},"Menulis teks itu mudah, tapi tahukah Anda bisa mengatur perataan horizontal (align) maupun vertikal (baseline)?",[33,634,636],{"className":35,"code":635,"language":37,"meta":15,"style":15},"ctx.font = '24px Arial'; \u002F\u002F Menentukan tipe font dan ukuran\nctx.fillStyle = 'white'; \u002F\u002F Menentukan warna text\n\n\u002F\u002F Perataan Horizontal teks (left, center, right, start, end)\nctx.textAlign = 'center'; \n\n\u002F\u002F Perataan Vertikal \u002F titik pangkal vertikal (top, middle, bottom, alphabetic, dll)\nctx.textBaseline = 'middle'; \n\n\u002F\u002F teks yang ditampilkan, posisi_x, posisi_y\nctx.fillText('Teks Rata Tengah \u002F Center', canvas.width \u002F 2, canvas.height \u002F 2);\n",[39,637,638,643,648,652,657,661,665,670,674,678,683],{"__ignoreMap":15},[42,639,640],{"class":44,"line":45},[42,641,642],{},"ctx.font = '24px Arial'; \u002F\u002F Menentukan tipe font dan ukuran\n",[42,644,645],{"class":44,"line":51},[42,646,647],{},"ctx.fillStyle = 'white'; \u002F\u002F Menentukan warna text\n",[42,649,650],{"class":44,"line":93},[42,651,103],{"emptyLinePlaceholder":102},[42,653,654],{"class":44,"line":99},[42,655,656],{},"\u002F\u002F Perataan Horizontal teks (left, center, right, start, end)\n",[42,658,659],{"class":44,"line":106},[42,660,342],{},[42,662,663],{"class":44,"line":112},[42,664,103],{"emptyLinePlaceholder":102},[42,666,667],{"class":44,"line":194},[42,668,669],{},"\u002F\u002F Perataan Vertikal \u002F titik pangkal vertikal (top, middle, bottom, alphabetic, dll)\n",[42,671,672],{"class":44,"line":199},[42,673,356],{},[42,675,676],{"class":44,"line":205},[42,677,103],{"emptyLinePlaceholder":102},[42,679,680],{"class":44,"line":211},[42,681,682],{},"\u002F\u002F teks yang ditampilkan, posisi_x, posisi_y\n",[42,684,685],{"class":44,"line":217},[42,686,687],{},"ctx.fillText('Teks Rata Tengah \u002F Center', canvas.width \u002F 2, canvas.height \u002F 2);\n",[689,690,691],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":15,"searchDepth":51,"depth":51,"links":693},[],"md",{"title_en":5,"title_id":376,"description_en":696,"description_id":697,"date":698,"readingTime":699},"Learn the fundamentals of HTML5 Canvas for game development, covering context, shapes, colors, gradients, and advanced text rendering.","Pelajari dasar-dasar HTML5 Canvas untuk pengembangan game, meliputi context, bentuk, warna, gradien, dan rendering teks lanjutan.","2026-03-25","8 min read","\u002Fblog\u002Fcanvas-basics",{"title":5,"description":15},"blog\u002Fcanvas-basics","TitJJMKX22Zkx1_gsUPGARhlNS4yFjchYdhcakNQmGQ",1783751391501]