Kapag nagsaksak ka ng controller, mash mo ang mga button, ililipat ang mga stick, hilahin ang mga trigger... at bilang isang developer, wala kang makikita sa mga ito. Kinukuha ito ng browser, sigurado, ngunit maliban kung nagla-log ka ng mga numero sa console, hindi ito nakikita. Iyan ang sakit ng ulo sa Gamepad API. Ito ay nasa loob ng maraming taon, at ito ay talagang napakalakas. Maaari mong basahin ang mga pindutan, stick, trigger, ang mga gawa. Ngunit karamihan sa mga tao ay hindi hawakan ito. Bakit? Dahil walang feedback. Walang panel sa mga tool ng developer. Walang malinaw na paraan para malaman kung ginagawa ng controller ang iniisip mo. Parang lumilipad na bulag. Iyon ay sapat na bugged sa akin upang bumuo ng isang maliit na tool: Gamepad Cascade Debugger. Sa halip na tumitig sa output ng console, makakakuha ka ng live, interactive na view ng controller. Pindutin ang isang bagay at nagre-react ito sa screen. At sa CSS Cascade Layers, nananatiling organisado ang mga istilo, kaya mas malinis itong i-debug. Sa post na ito, ipapakita ko sa iyo kung bakit napakasakit ng mga controller sa pag-debug, kung paano nakakatulong ang CSS na linisin ito, at kung paano ka makakabuo ng magagamit muli na visual debugger para sa sarili mong mga proyekto.

Kahit na ma-log mo silang lahat, mabilis kang mapupunta sa hindi nababasang console spam. Halimbawa: [0,0,1,0,0,0.5,0,...] [0,0,0,0,1,0,0,...] [0,0,1,0,0,0,0,...]

Masasabi mo ba kung anong button ang pinindot? Siguro, ngunit pagkatapos lamang na pilitin ang iyong mga mata at nawawala ang ilang mga input. Kaya, hindi, hindi madali ang pag-debug pagdating sa pagbabasa ng mga input. Problema 3: Kakulangan ng Istruktura Kahit na magsama-sama ka ng isang mabilis na visualizer, maaaring mabilis na magulo ang mga istilo. Maaaring mag-overlap ang mga default, aktibo, at debug na estado, at kung walang malinaw na istraktura, nagiging malutong at mahirap i-extend ang iyong CSS. Makakatulong ang CSS Cascade Layers. Pinagpangkat-pangkat nila ang mga istilo sa "mga layer" na inayos ayon sa priyoridad, kaya huminto ka sa pakikipaglaban sa pagiging tiyak at paghula, "Bakit hindi lumalabas ang aking istilo ng pag-debug?" Sa halip, nagpapanatili ka ng magkakahiwalay na alalahanin:

Base: Ang pamantayan ng controller, unang hitsura. Aktibo: Mga highlight para sa pinindot na mga pindutan at inilipat na mga stick. Debug: Mga overlay para sa mga developer (hal., mga numeric readout, gabay, at iba pa).

Kung tutukuyin natin ang mga layer sa CSS ayon dito, magkakaroon tayo ng: /* pinakamababa hanggang sa pinakamataas na priyoridad */ @layer base, aktibo, debug;

@layer base { /* ... */ }

@layer aktibo { /* ... */ }

@layer debug { /* ... */ }

Dahil predictably stack ang bawat layer, palagi mong alam kung aling mga panuntunan ang mananalo. Ang predictability na iyon ay ginagawang hindi lamang mas madali ang pag-debug, ngunit talagang mapapamahalaan. Sinaklaw namin ang problema (invisible, magulo na input) at ang diskarte (isang visual debugger na binuo gamit ang Cascade Layers). Ngayon, lalakad tayo sa hakbang-hakbang na proseso para buuin ang debugger. Ang Konsepto ng Debugger Ang pinakamadaling paraan upang gawing nakikita ang nakatagong input ay ang pagguhit lang nito sa screen. Iyan ang ginagawa ng debugger na ito. Ang mga button, trigger, at joystick ay nakakakuha ng visual.

Pindutin ang A: Lumiliwanag ang isang bilog. I-nudge ang stick: Ang bilog ay dumudulas sa paligid. Hilahin ang gatilyo sa kalahati: Pumupuno ang isang bar sa kalahati.

Ngayon ay hindi ka nakatitig sa 0s at 1s, ngunit aktwal na nanonood ng live na reaksyon ng controller. Siyempre, sa sandaling simulan mo ang pagtambak sa mga estado tulad ng default, pinindot, impormasyon sa pag-debug, marahil kahit isang mode ng pag-record, ang CSS ay nagsisimulang lumaki at mas kumplikado. Na kung saan ang mga cascade layer ay madaling gamitin. Narito ang isang hinubad na halimbawa: @layer base { .button { background: #222; hangganan-radius: 50%; lapad: 40px; taas: 40px; } }

@layer aktibo { .button.pressed { background: #0f0; /* maliwanag na berde */ } }

@layer debug { .button::pagkatapos { nilalaman: attr(data-value); laki ng font: 12px; kulay: #fff; } }

Ang pagkakasunud-sunod ng layer ay mahalaga: base → aktibo → debug.

iginuhit ng base ang controller. aktibong humahawak sa mga nakapindot na estado. debug throws sa mga overlay.

Ang paghiwa-hiwalay dito ay nangangahulugan na hindi ka nakikipaglaban sa mga kakaibang partikular na digmaan. Ang bawat layer ay may sariling lugar, at palagi mong alam kung ano ang mananalo. Pagbuo Ito Kumuha muna tayo ng isang bagay sa screen. Hindi ito kailangang magmukhang maganda — kailangan lang na umiral para magkaroon tayo ng trabaho.

Gamepad Cascade Debugger

A
B
X

Hindi aktibo ang debugger

Iyan ay literal na mga kahon lamang. Hindi pa kapana-panabik, ngunit nagbibigay ito sa amin ng mga hawakan upang makuha sa ibang pagkakataon gamit ang CSS at JavaScript. Okay, gumagamit ako ng mga cascade layer dito dahil pinapanatili nitong maayos ang mga bagay kapag nagdagdag ka ng higit pang mga estado. Narito ang isang magaspang na pass:

/* ================================================== SETUP NG CASCADE LAYERS Mahalaga ang order: base → active → debug ================================================== */

/* Tukuyin ang pagkakasunud-sunod ng layer sa harap */ @layer base, aktibo, debug;

/* Layer 1: Mga base na istilo - default na hitsura */ @layer base { .button { background: #333; hangganan-radius: 50%; lapad: 70px; taas: 70px; display: flex; justify-content: center; align-item: center; }

.pause { lapad: 20px; taas: 70px; background: #333; display: inline-block; } }

/* Layer 2: Mga aktibong estado - pinangangasiwaan ang mga pinindot na pindutan */ @layer aktibo { .button.active { background: #0f0; /* Matingkad na berde kapag pinindot */ pagbabagong-anyo: sukat (1.1); /* Bahagyang pinalaki ang button */ }

.pause.active { background: #0f0; transform: scaleY(1.1); /* Umuunat nang patayo kapag pinindot */ } }

/* Layer 3: Mga overlay sa pag-debug - impormasyon ng developer */ @layer debug { .button::pagkatapos { nilalaman: attr(data-value); /* Ipinapakita ang numerong halaga */ laki ng font: 12px; kulay: #fff; } }

Ang kagandahan ng diskarteng ito ay ang bawat layer ay may malinaw na layunin. Hindi kailanman ma-override ng base layer ang aktibo, at hindi kailanman ma-override ng aktibo ang debug, anuman ang partikularidad. Tinatanggal nito ang mga digmaan sa pagtitiyak ng CSS na kadalasang sumasalot sa mga tool sa pag-debug. Ngayon ay mukhang ilang kumpol ang nakaupo sa isang madilim na background. Sa totoo lang, hindi masyadong masama.

Pagdaragdag ng JavaScript Oras ng JavaScript. Ito ay kung saan ang controller ay talagang gumagawa ng isang bagay. Bubuo kami ng hakbang-hakbang na ito. Hakbang 1: I-set Up ang Pamamahala ng Estado Una, kailangan namin ng mga variable upang masubaybayan ang estado ng debugger: // ================================================== // PAMAMAHALA NG ESTADO // ==================================================

hayaan ang pagtakbo = false; // Sinusubaybayan kung aktibo ang debugger hayaan ang rafId; // Iniimbak ang requestAnimationFrame ID para sa pagkansela

Kinokontrol ng mga variable na ito ang animation loop na patuloy na nagbabasa ng input ng gamepad. Hakbang 2: Kunin ang Mga Sanggunian ng DOM Susunod, nakakakuha kami ng mga sanggunian sa lahat ng elemento ng HTML na aming ia-update: // ================================================== // DOM ELEMENT REFERENCES // ==================================================

const btnA = document.getElementById("btn-a"); const btnB = document.getElementById("btn-b"); const btnX = document.getElementById("btn-x"); const pause1 = document.getElementById("pause1"); const pause2 = document.getElementById("pause2"); const status = document.getElementById("status");

Ang pag-imbak ng mga sangguniang ito sa harap ay mas mahusay kaysa sa paulit-ulit na pagtatanong sa DOM. Hakbang 3: Magdagdag ng Keyboard Fallback Para sa pagsubok nang walang pisikal na controller, imamapa namin ang mga keyboard key sa mga button: // ================================================== // KEYBOARD FALLBACK (para sa pagsubok nang walang controller) // ==================================================

const keyMap = { "a": btnA, "b": btnB, "x": btnX, "p": [pause1, pause2] // Kinokontrol ng 'p' key ang parehong mga pause bar };

Nagbibigay-daan ito sa amin na subukan ang UI sa pamamagitan ng pagpindot sa mga key sa isang keyboard. Hakbang 4: Lumikha ng Pangunahing Update Loop Dito nangyayari ang mahika. Ang function na ito ay patuloy na tumatakbo at nagbabasa ng gamepad state: // ================================================== // PANGUNAHING GAMEPAD UPDATE LOOP // ==================================================

function updateGamepad() { // Kunin ang lahat ng konektadong gamepad const gamepads = navigator.getGamepads(); kung bumalik ang (!gamepads);

// Gamitin ang unang nakakonektang gamepad const gp = gamepads[0];

kung (gp) { // I-update ang mga estado ng button sa pamamagitan ng pag-toggle sa "aktibo" na klase btnA.classList.toggle("aktibo", gp.buttons[0].pindot); btnB.classList.toggle("aktibo", gp.buttons[1].pindot); btnX.classList.toggle("aktibo", gp.buttons[2].pindot);

// Pangasiwaan ang pindutan ng pause (index ng pindutan 9 sa karamihan ng mga controller) const pausePressed = gp.buttons[9].pindot; pause1.classList.toggle("aktibo", pausePressed); pause2.classList.toggle("aktibo", pausePressed);

// Bumuo ng isang listahan ng kasalukuyang pinindot na mga pindutan para sa pagpapakita ng katayuan hayaan ang pinindot = []; gp.buttons.forEach((btn, i) => { kung (btn.pindot)pressed.push("Button " + i); });

// I-update ang text ng katayuan kung pinindot ang anumang mga pindutan kung (pindot.length > 0) { status.textContent = "Pinindot: " + pressed.join(", "); } }

// Ipagpatuloy ang loop kung tumatakbo ang debugger kung (tumatakbo) { rafId = requestAnimationFrame(updateGamepad); } }

Ang classList.toggle() na pamamaraan ay nagdaragdag o nag-aalis ng aktibong klase batay sa kung pinindot ang button, na nagti-trigger sa aming mga estilo ng layer ng CSS. Hakbang 5: Pangasiwaan ang Mga Kaganapan sa Keyboard Ginagawa ng mga tagapakinig ng kaganapang ito na gumana ang keyboard fallback: // ================================================== // KEYBOARD EVENT HANDLERS // ==================================================

document.addEventListener("keydown", (e) => { kung (keyMap[e.key]) { // Pangasiwaan ang isa o maramihang elemento kung (Array.isArray(keyMap[e.key])) { keyMap[e.key].forEach(el => el.classList.add("active")); } iba { keyMap[e.key].classList.add("aktibo"); } status.textContent = "Pinindot ang key: " + e.key.toUpperCase(); } });

document.addEventListener("keyup", (e) => { kung (keyMap[e.key]) { // Alisin ang aktibong estado kapag inilabas ang key kung (Array.isArray(keyMap[e.key])) { keyMap[e.key].forEach(el => el.classList.remove("aktibo")); } iba { keyMap[e.key].classList.remove("aktibo"); } status.textContent = "Susi na inilabas: " + e.key.toUpperCase(); } });

Hakbang 6: Magdagdag ng Start/Stop Control Sa wakas, kailangan namin ng isang paraan upang i-toggle ang debugger sa on at off: // ================================================== // TOGGLE DEBUGGER ON/OFF // ==================================================

document.getElementById("toggle").addEventListener("click", () => { tumatakbo = !running; // I-flip ang running state

kung (tumatakbo) { status.textContent = "Tumatakbo ang debugger..."; updateGamepad(); // Simulan ang loop ng pag-update } iba { status.textContent = "Hindi aktibo ang debugger"; cancelAnimationFrame(rafId); // Itigil ang loop } });

Kaya oo, pindutin ang isang pindutan at ito ay kumikinang. Itulak ang stick at ito ay gumagalaw. Iyon lang. Isa pang bagay: raw values. Minsan gusto mo lang makakita ng mga numero, hindi mga ilaw.

Sa yugtong ito, dapat mong makita:

Isang simpleng on-screen controller, Mga button na tumutugon habang nakikipag-ugnayan ka sa kanila, at Isang opsyonal na pagbabasa ng debug na nagpapakita ng mga indeks ng pinindot na button.

Upang gawin itong hindi gaanong abstract, narito ang isang mabilis na demo ng on-screen na controller na tumutugon sa real time:

Ngayon, ang pagpindot sa Start Recording ay nagtatala ng lahat hanggang sa mapindot mo ang Stop Recording. 2. Pag-export ng Data sa CSV/JSON Kapag mayroon na kaming log, gugustuhin naming i-save ito.

Hakbang 1: Gawin ang Download Helper Una, kailangan namin ng helper function na humahawak sa mga pag-download ng file sa browser: // ================================================== // FILE DOWNLOAD HELPER // ==================================================

function downloadFile(filename, content, type = "text/plain") { // Lumikha ng blob mula sa nilalaman const blob = bagong Blob([nilalaman], { uri }); const url = URL.createObjectURL(blob);

// Lumikha ng pansamantalang link sa pag-download at i-click ito const a = document.createElement("a"); a.href = url; a.download = filename; a.click();

// Linisin ang object URL pagkatapos i-download setTimeout(() => URL.revokeObjectURL(url), 100); }

Gumagana ang function na ito sa pamamagitan ng paggawa ng Blob (binary large object) mula sa iyong data, pagbuo ng pansamantalang URL para dito, at pag-click ng link sa pag-download gamit ang program. Tinitiyak ng paglilinis na hindi kami maglalabas ng memorya. Hakbang 2: Pangasiwaan ang JSON Export Ang JSON ay perpekto para sa pagpapanatili ng kumpletong istraktura ng data:

// ================================================== // EXPORT BILANG JSON // ==================================================

document.getElementById("export-json").addEventListener("click", () => { // Suriin kung mayroong anumang i-export kung (!frames.length) { console.warn("Walang recording na magagamit upang i-export."); bumalik; }

// Gumawa ng payload na may metadata at mga frame const payload = { nilikhaAt: bagong Petsa().toISOString(), mga frame };

// I-download bilang naka-format na JSON downloadFile( "gamepad-log.json", JSON.stringify(payload, null, 2), "application/json" ); });

Pinapanatili ng format ng JSON ang lahat na nakabalangkas at madaling ma-parseable, na ginagawa itong mainam para sa pag-load pabalik sa mga dev tool o pagbabahagi sa mga kasamahan sa koponan. Hakbang 3: Pangasiwaan ang CSV Export Para sa mga pag-export ng CSV, kailangan nating i-flatten ang hierarchical data sa mga row at column:

//================================================== // EXPORT BILANG CSV // ==================================================

document.getElementById("export-csv").addEventListener("click", () => { // Suriin kung mayroong anumang i-export kung (!frames.length) { console.warn("Walang recording na magagamit upang i-export."); bumalik; }

// Bumuo ng CSV header row (mga column para sa timestamp, lahat ng button, lahat ng axes) const headerButtons = frames[0].buttons.map((_, i) => btn${i}); const headerAxes = frames[0].axes.map((_, i) => axis${i}); const header = ["t", ...headerButtons, ...headerAxes].join(",") + "\n";

// Bumuo ng mga row ng data ng CSV const rows = frames.map(f => { const btnVals = f.buttons.map(b => b.value); ibalik [f.t, ...btnVals, ...f.axes].join(","); }).join("\n");

// I-download bilang CSV downloadFile("gamepad-log.csv", header + rows, "text/csv"); });

Mahusay ang CSV para sa pagsusuri ng data dahil direktang bumubukas ito sa Excel o Google Sheets, na nagbibigay-daan sa iyong lumikha ng mga chart, mag-filter ng data, o makakita ng mga pattern nang biswal. Ngayong nasa loob na ang mga button sa pag-export, makakakita ka ng dalawang bagong opsyon sa panel: I-export ang JSON at I-export ang CSV. Ang JSON ay maganda kung gusto mong ibalik ang hilaw na log sa iyong mga tool sa dev o sundutin ang istraktura. Ang CSV, sa kabilang banda, ay bumubukas nang diretso sa Excel o Google Sheets upang maaari kang mag-chart, mag-filter, o maghambing ng mga input. Ipinapakita ng sumusunod na figure kung ano ang hitsura ng panel sa mga karagdagang kontrol na iyon.

3. Snapshot System Minsan hindi mo kailangan ng buong pag-record, isang mabilis na "screenshot" lamang ng mga estado ng pag-input. Doon nakakatulong ang button na Take Snapshot.

At ang JavaScript:

// ================================================== // KUMUHA NG SNAPSHOT // ==================================================

document.getElementById("snapshot").addEventListener("click", () => { // Kunin ang lahat ng konektadong gamepad const pads = navigator.getGamepads(); const activePads = [];

// I-loop at kunin ang estado ng bawat konektadong gamepad para sa (const gp ng mga pad) { kung magpapatuloy ang (!gp); // Laktawan ang mga walang laman na slot

activePads.push({ id: gp.id, // Pangalan/modelo ng Controller timestamp: performance.now(), mga pindutan: gp.buttons.map(b => ({ pinindot: b.pindot, halaga: b.halaga })), axes: [...gp.axes] }); }

// Suriin kung may nakitang mga gamepad kung (!activePads.length) { console.warn("Walang nakakonektang gamepad para sa snapshot."); alert("Walang nakitang controller!"); bumalik; }

// Mag-log at abisuhan ang user console.log("Snapshot:", activePads); alert(Snapshot taken! Nakuha ang ${activePads.length} controller(s.); });

Na-freeze ng mga snapshot ang eksaktong estado ng iyong controller sa isang sandali sa oras. 4. Ghost Input Replay Ngayon para sa masaya: ghost input replay. Ito ay tumatagal ng isang log at nagpe-play ito pabalik na parang isang phantom player ang gumagamit ng controller.

JavaScript para sa replay: // ================================================== // GHOST REPLAY // ==================================================

document.getElementById("replay").addEventListener("click", () => { // Tiyaking mayroon tayong recording na ire-replay kung (!frames.length) { alert("Walang recording na ire-replay!"); bumalik; }

console.log("Simulan ang ghost replay...");

// Subaybayan ang timing para sa naka-sync na pag-playback let startTime = performance.now(); hayaan ang frameIndex = 0;

// I-replay ang animation loop function step() { const now = performance.now(); const elapsed = ngayon - startTime;

// Iproseso ang lahat ng mga frame na dapat ay naganap na ngayon habang (frameIndex < frames.length && frames[frameIndex].t <= elapsed) { const frame = mga frame[frameIndex];

// I-update ang UI gamit ang mga naka-record na estado ng button btnA.classList.toggle("aktibo", frame.buttons[0].pindot); btnB.classList.toggle("aktibo", frame.buttons[1].pindot); btnX.classList.toggle("aktibo", frame.buttons[2].pindot);

// Update status display hayaan ang pinindot = []; frame.buttons.forEach((btn, i) => { if (btn.pressed) pressed.push("Button " + i); }); kung (pindot.length > 0) { status.textContent = "Ghost: " + pressed.join(", "); }

frameIndex++; }

// Continue loop kung marami pang frame if (frameIndex < frames.length) { requestAnimationFrame(step); } iba { console.log("I-replaytapos na."); status.textContent = "Kumpleto na ang replay"; } }

// Simulan ang replay hakbang(); });

Para gawing mas hands-on ang pag-debug, nagdagdag ako ng ghost replay. Kapag nakapag-record ka na ng session, maaari mong pindutin ang replay at panoorin ang UI na kumilos ito, halos parang isang phantom player ang nagpapatakbo ng pad. Isang bagong Replay Ghost button ang lalabas sa panel para dito.

Pindutin ang Record, guluhin nang kaunti ang controller, huminto, pagkatapos ay i-replay. Ine-echo lang ng UI ang lahat ng ginawa mo, tulad ng isang multo na sumusunod sa iyong mga input. Bakit mag-abala sa mga ekstrang ito?

Pinapadali ng pagre-record/pag-export para sa mga tester na ipakita kung ano mismo ang nangyari. Nag-freeze ang mga snapshot sa ilang sandali, sobrang kapaki-pakinabang kapag hinahabol mo ang mga kakaibang bug. Ang ghost replay ay mahusay para sa mga tutorial, pagsuri sa pagiging naa-access, o paghahambing lamang ng mga control setup nang magkatabi.

Sa puntong ito, ito ay hindi lamang isang maayos na demo, ngunit isang bagay na maaari mong talagang gawin. Mga Real-World Use Case Ngayon ay mayroon na kaming debugger na ito na maraming magagawa. Nagpapakita ito ng live na input, nagtatala ng mga log, nag-e-export sa kanila, at kahit na nagre-replay ng mga bagay-bagay. Ngunit ang totoong tanong ay: sino ba talaga ang nagmamalasakit? Para kanino ito kapaki-pakinabang? Mga Nag-develop ng Laro Ang mga controller ay bahagi ng trabaho, ngunit ang pag-debug sa kanila? Kadalasan ay isang sakit. Isipin na sumusubok ka ng combo ng fighting game, tulad ng ↓ → + punch. Sa halip na magdasal, pinindot mo ito sa parehong paraan ng dalawang beses, i-record mo ito nang isang beses, at muling i-play ito. Tapos na. O ipinagpapalit mo ang mga log ng JSON sa isang teammate para tingnan kung pareho ang reaksyon ng iyong multiplayer code sa kanilang makina. Malaki iyon. Mga Practitioner ng Accessibility Ang isang ito ay malapit sa aking puso. Hindi lahat ay naglalaro ng isang "standard" na controller. Ang mga adaptive controller ay nagtatapon ng mga kakaibang signal kung minsan. Gamit ang tool na ito, makikita mo nang eksakto kung ano ang nangyayari. Mga guro, mananaliksik, kung sino man. Maaari silang kumuha ng mga log, ihambing ang mga ito, o i-replay ang mga input nang magkatabi. Biglang lumilitaw ang mga bagay na hindi nakikita. Quality Assurance Testing Karaniwang nagsusulat ang mga tagasubok ng mga tala tulad ng "Na-mashed ko ang mga button dito at nasira ito." Hindi masyadong nakakatulong. ngayon? Maaari nilang makuha ang eksaktong mga pagpindot, i-export ang log, at ipadala ito. Walang hula. Mga tagapagturo Kung gumagawa ka ng mga tutorial o YouTube vids, ang ghost replay ay ginto. Maaari mong literal na sabihin, "Narito ang ginawa ko sa controller," habang ipinapakita ng UI na nangyayari ito. Ginagawang mas malinaw ang mga paliwanag. Higit pa sa Mga Laro At oo, ito ay hindi lamang tungkol sa mga laro. Gumamit ang mga tao ng mga controller para sa mga robot, art project, at accessibility interface. Parehong isyu sa bawat oras: ano ang aktwal na nakikita ng browser? Sa pamamagitan nito, hindi mo kailangang hulaan. Konklusyon Ang pag-debug sa isang input ng controller ay palaging parang lumilipad na bulag. Hindi tulad ng DOM o CSS, walang built-in na inspektor para sa mga gamepad; ito ay mga hilaw na numero lamang sa console, madaling mawala sa ingay. Sa ilang daang linya ng HTML, CSS, at JavaScript, gumawa kami ng kakaiba:

Isang visual debugger na ginagawang nakikita ang mga hindi nakikitang input. Isang layered na CSS system na nagpapanatiling malinis at ma-debug ang UI. Isang hanay ng mga pagpapahusay (pagre-record, pag-export, mga snapshot, ghost replay) na nagpapataas nito mula sa demo patungo sa tool ng developer.

Ipinapakita ng proyektong ito kung hanggang saan ang magagawa mo sa pamamagitan ng paghahalo ng kapangyarihan ng Web Platform sa kaunting pagkamalikhain sa CSS Cascade Layers. Ang tool na ipinaliwanag ko sa kabuuan nito ay open-source. Maaari mong i-clone ang GitHub repo at subukan ito para sa iyong sarili. Ngunit higit sa lahat, maaari mong gawin itong iyong sarili. Magdagdag ng sarili mong mga layer. Bumuo ng iyong sariling replay logic. Isama ito sa iyong prototype ng laro. O kahit na gamitin ito sa mga paraan na hindi ko naisip. Para sa pagtuturo, pagiging naa-access, o pagsusuri ng data. Sa pagtatapos ng araw, ito ay hindi lamang tungkol sa pag-debug ng mga gamepad. Ito ay tungkol sa pagbibigay-liwanag sa mga nakatagong input, at pagbibigay ng kumpiyansa sa mga developer na magtrabaho kasama ang hardware na hindi pa rin ganap na tinatanggap ng web. Kaya, isaksak ang iyong controller, buksan ang iyong editor, at magsimulang mag-eksperimento. Maaaring mabigla ka sa kung ano talaga ang kayang gawin ng iyong browser at ng iyong CSS.

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free