Halo, dunia (aneh)
Halaman beranda Google adalah lingkungan yang menarik untuk membuat kode. Hal ini memiliki banyak batasan yang menantang: fokus khusus pada kecepatan dan latensi, harus memenuhi berbagai jenis browser dan bekerja dalam berbagai kondisi, dan… ya, kejutan dan kesenangan.
Saya berbicara tentang Google doodle, ilustrasi khusus yang terkadang menggantikan logo kami. Meskipun hubungan saya dengan pena dan kuas telah lama memiliki rasa yang khas dari perintah penahanan, saya sering berkontribusi pada yang interaktif.
Setiap doodle interaktif yang saya kode (Pac-Man, Jules Verne, World's Fair) – dan banyak yang saya bantu – sama-sama futuristik dan anachronis: peluang besar untuk aplikasi yang tidak realistis dari fitur Web canggih… dan pragmatisme yang keras dari kompatibilitas lintas browser.
Kami belajar banyak dari setiap doodle interaktif, dan game mini Stanisław Lem terbaru tidak terkecuali, dengan 17.000 baris kode JavaScript yang mencoba banyak hal untuk pertama kalinya dalam sejarah doodle. Hari ini, saya ingin membagikan kode tersebut kepada Anda – mungkin Anda akan menemukan sesuatu yang menarik di sana, atau menunjukkan kesalahan saya – dan membahasnya sedikit.
Lihat kode doodle Stanisław Lem »
Hal yang perlu diingat adalah halaman beranda Google bukan tempat untuk demo teknologi. Dengan doodle, kami ingin merayakan orang dan peristiwa tertentu, dan kami ingin melakukannya menggunakan seni terbaik dan teknologi terbaik yang dapat kami gunakan – tetapi jangan pernah merayakan teknologi hanya demi teknologi. Artinya, Anda harus melihat dengan cermat bagian apa pun dari HTML5 yang dipahami secara luas yang tersedia, dan apakah hal itu membantu kami membuat doodle menjadi lebih baik tanpa mengganggu atau mengaburkan doodle.
Jadi, mari kita bahas beberapa teknologi Web modern yang ada dalam doodle Stanisław Lem – dan beberapa yang tidak ada.
Grafik melalui DOM dan kanvas
Kanvas sangat andal dan dibuat untuk hal-hal yang ingin kita lakukan dalam doodle ini. Namun, beberapa browser lama yang kami minati tidak mendukungnya – dan meskipun saya benar-benar berbagi kantor dengan orang yang menyusun excanvas yang sangat bagus, saya memutuskan untuk memilih cara yang berbeda.
Saya menyusun mesin grafis yang memisahkan primitif grafis yang disebut “rects”, lalu merendernya menggunakan kanvas, DOM jika kanvas tidak tersedia.
Pendekatan ini memiliki beberapa tantangan yang menarik – misalnya, memindahkan atau mengubah objek di DOM memiliki konsekuensi langsung, sedangkan untuk kanvas, ada momen tertentu saat semuanya digambar secara bersamaan. (Saya memutuskan untuk hanya memiliki satu kanvas, dan menghapusnya serta menggambar dari awal dengan setiap frame. Terlalu banyak, secara harfiah, bagian yang bergerak di satu sisi – dan di sisi lain tidak cukup kompleks untuk menjamin pemisahan menjadi beberapa kanvas yang tumpang-tindih dan memperbaruinya secara selektif.)
Sayangnya, beralih ke kanvas tidak semudah mencerminkan latar belakang CSS
dengan drawImage()
: Anda kehilangan sejumlah hal
yang tersedia secara gratis saat menggabungkan semuanya
melalui DOM – yang paling penting adalah pelapisan dengan z-index, dan peristiwa mouse.
Saya telah memisahkan z-index dengan konsep yang disebut “bidang”. Doodle
menentukan sejumlah bidang – dari langit yang jauh di belakang, hingga kursor
mouse di depan semuanya – dan setiap aktor dalam doodle harus
memutuskan bidang mana yang dimaksud (koreksi plus/minus kecil dalam
bidang dapat dilakukan dengan menggunakan planeCorrection
).
Dengan rendering melalui DOM, bidang hanya diterjemahkan menjadi z-index. Namun, jika merender melalui kanvas, kita perlu mengurutkan persegi panjang berdasarkan bidangnya sebelum menggambarnya. Karena melakukannya setiap kali akan menghabiskan banyak biaya, urutan hanya dihitung ulang saat aktor ditambahkan atau saat aktor berpindah ke bidang lain.
Untuk peristiwa mouse, saya juga memisahkannya… Untuk DOM dan kanvas, saya menggunakan elemen DOM mengambang tambahan yang sepenuhnya transparan dengan z-index tinggi, yang fungsinya hanya untuk bereaksi terhadap mouse over/out, klik, dan ketukan.
Salah satu hal yang ingin kami coba dengan doodle ini adalah mematahkan dinding keempat. Mesin di atas memungkinkan kita menggabungkan aktor berbasis kanvas dengan aktor berbasis DOM. Misalnya, ledakan di bagian akhir berada di kanvas untuk objek dalam alam semesta dan di DOM untuk halaman beranda Google lainnya. Burung, yang biasanya terbang berkeliling dan terpotong oleh maskara bergerigi seperti aktor lainnya, memutuskan untuk tidak menimbulkan masalah selama tingkat pengambilan gambar, dan duduk di tombol I’m Feeling Lucky. Cara melakukannya adalah dengan membuat burung keluar dari kanvas dan menjadi elemen DOM (dan sebaliknya nanti), yang saya harap akan sepenuhnya transparan bagi pengunjung.
Kecepatan frame
Mengetahui kecepatan frame saat ini, dan bereaksi saat kecepatan frame terlalu lambat (dan terlalu cepat) adalah bagian penting dari mesin kami. Karena browser tidak melaporkan kembali kecepatan frame, kita harus menghitungnya sendiri.
Saya mulai menggunakan requestAnimationFrame,
kembali ke
setTimeout
lama jika yang pertama tidak tersedia.
requestAnimationFrame
dengan cerdik menghemat CPU dalam
beberapa situasi – meskipun kita melakukannya sendiri, seperti yang akan
dijelaskan di bawah – tetapi juga memungkinkan kita mendapatkan kecepatan frame
yang lebih tinggi daripada setTimeout
.
Menghitung kecepatan frame saat ini itu sederhana, tetapi dapat mengalami perubahan drastis – misalnya, kecepatan frame dapat turun dengan cepat saat aplikasi lain menggunakan komputer untuk sementara. Oleh karena itu, kami menghitung kecepatan frame “rolling” (rata-rata) hanya di setiap 100 tick fisik dan membuat keputusan berdasarkan hal tersebut.
Keputusan seperti apa?
Jika kecepatan frame lebih tinggi dari 60 fps, kami akan membatasinya. Saat ini,
requestAnimationFrame
di beberapa versi Firefox tidak memiliki batas atas pada kecepatan frame, dan tidak ada gunanya membuang CPU. Perhatikan bahwa kita sebenarnya membatasi kecepatan frame pada 65 fps, karena error pembulatan yang membuat kecepatan frame sedikit lebih tinggi dari 60 fps di browser lain – kita tidak ingin mulai melakukan throttling secara tidak sengaja.Jika kecepatan frame lebih rendah dari 10 fps, kita cukup memperlambat mesin, bukan menghapus frame. Ini adalah proposisi yang merugikan, tetapi saya merasa bahwa melewatkan frame secara berlebihan akan lebih membingungkan daripada hanya memiliki game yang lebih lambat (tetapi masih koheren). Ada efek samping bagus lainnya dari hal itu – jika sistem melambat untuk sementara, pengguna tidak akan mengalami lompatan aneh karena mesin berusaha mengejar. (Saya melakukannya dengan sedikit perbedaan untuk Pac-Man, tetapi kecepatan frame minimum adalah pendekatan yang lebih baik.)
Terakhir, kita dapat mempertimbangkan untuk menyederhanakan grafis saat kecepatan frame menjadi sangat rendah. Kami tidak melakukannya untuk doodle Lem, kecuali kursor mouse (selengkapnya di bawah), tetapi secara hipotetis, kita dapat menghilangkan beberapa animasi yang tidak relevan agar doodle terasa lancar bahkan di komputer yang lebih lambat.
Kita juga memiliki konsep centang fisik dan centang logis. Yang pertama berasal dari
requestAnimationFrame
/setTimeout
. Rasio dalam
gameplay normal adalah 1:1, tetapi untuk mempercepat, kita hanya menambahkan lebih banyak jeda
logis per jeda fisik (hingga 1:5). Hal ini memungkinkan kita melakukan semua
perhitungan yang diperlukan untuk setiap tanda logika, tetapi hanya menetapkan yang terakhir
sebagai yang memperbarui hal-hal di layar.
Membuat tolok ukur
Asumsi dapat (dan memang, pada awalnya) dibuat bahwa kanvas akan lebih cepat daripada DOM setiap kali tersedia. Hal ini tidak selalu benar. Saat melakukan pengujian, kami mendapati bahwa Opera 10.0–10.1 di Mac, dan Firefox di Linux sebenarnya lebih cepat saat memindahkan elemen DOM.
Dalam dunia yang sempurna, doodle akan secara diam-diam menjalankan benchmark pada berbagai teknik grafis – elemen DOM dipindahkan menggunakan style.left
dan style.top
, menggambar di kanvas, dan mungkin bahkan elemen DOM dipindahkan menggunakan transformasi CSS3
– lalu beralihlah ke salah satu yang memberikan kecepatan frame tertinggi. Saya mulai menulis kode untuk itu, tetapi mendapati bahwa setidaknya cara saya melakukan benchmark cukup tidak dapat diandalkan dan memerlukan banyak waktu. Waktu yang tidak kita miliki di halaman beranda – kami sangat memperhatikan kecepatan dan ingin doodle muncul secara instan serta gameplay dimulai segera setelah Anda mengklik atau mengetuk.
Pada akhirnya, pengembangan Web terkadang bermuara pada keharusan melakukan apa yang
harus Anda lakukan. Saya melihat ke belakang untuk memastikan tidak ada yang melihat, lalu
hanya meng-hardcode Opera 10
dan Firefox dari kanvas. Di kehidupan berikutnya, saya akan kembali sebagai tag <marquee>
.
Menghemat CPU
Anda tahu teman yang datang ke rumah Anda, menonton final musim Breaking Bad, membocorkan ceritanya kepada Anda, lalu menghapusnya dari DVR Anda? Anda tidak ingin menjadi orang seperti itu, bukan?
Jadi, ya, analogi terburuk. Namun, kami juga tidak ingin doodle kami menjadi orang yang seperti itu. Fakta bahwa kami diizinkan masuk ke tab browser seseorang adalah hak istimewa, dan menimbun siklus CPU atau mengganggu pengguna akan membuat kami menjadi tamu yang tidak menyenangkan. Oleh karena itu, jika tidak ada yang bermain dengan doodle (tidak ada ketukan, klik mouse, gerakan mouse, atau penekanan tombol), kita ingin aplikasi tersebut akhirnya tidur.
Kapan?
- setelah 18 detik di halaman beranda (game arcade menyebutnya mode menarik)
- setelah 180 detik jika tab memiliki fokus
- setelah 30 detik jika tab tidak memiliki fokus (misalnya, pengguna beralih ke jendela lain, tetapi mungkin masih menonton doodle sekarang di tab yang tidak aktif)
- segera jika tab menjadi tidak terlihat (misalnya, pengguna beralih ke tab lain di jendela yang sama – tidak ada gunanya membuang siklus jika kita tidak dapat dilihat)
Bagaimana cara mengetahui tab saat ini memiliki fokus? Kita melampirkan diri ke window.focus
dan window.blur
Bagaimana
kita tahu tab terlihat? Kita menggunakan Page Visibility API baru dan
bereaksi terhadap peristiwa yang sesuai.
Waktu tunggu di atas lebih toleran daripada biasanya untuk kami. Saya menyesuaikannya dengan doodle khusus ini, yang memiliki banyak animasi standby (terutama langit dan burung). Idealnya, waktu tunggu akan dibatasi pada interaksi dalam game – misalnya, tepat setelah mendarat, burung dapat melaporkan kembali ke doodle bahwa sekarang ia dapat tidur – tetapi pada akhirnya saya tidak menerapkan hal itu.
Karena langit selalu bergerak, saat tertidur dan bangun, sketsel tidak hanya berhenti atau dimulai – sketsel melambat sebelum dijeda, dan sebaliknya untuk melanjutkan, meningkatkan atau menurunkan jumlah jeda logika per jeda fisik sesuai kebutuhan.
Transisi, transformasi, peristiwa
Salah satu keunggulan HTML adalah Anda dapat membuatnya lebih baik sendiri: jika ada sesuatu yang tidak cukup baik dalam portofolio HTML dan CSS reguler, Anda dapat menggunakan JavaScript untuk memperluasnya. Sayangnya, hal ini sering kali berarti Anda harus memulai dari awal. Transisi CSS3 sangat bagus, tetapi Anda tidak dapat menambahkan jenis transisi baru atau menggunakan transisi untuk melakukan hal lain selain menata gaya elemen. Contoh lainnya: Transformasi CSS3 sangat cocok untuk DOM, tetapi saat beralih ke kanvas, Anda tiba-tiba sendirian.
Masalah ini, dan lainnya, adalah alasan doodle Lem memiliki mesin transisi dan transformasi sendiri. Ya, saya tahu, tahun 2000 memanggil, dll. – kemampuan yang saya buat tidak sekuat CSS3, tetapi apa pun yang dilakukan mesin, semuanya dilakukan secara konsisten dan memberi kita lebih banyak kontrol.
Saya memulai dengan sistem tindakan
(peristiwa) sederhana – linimasa yang memicu peristiwa di masa mendatang tanpa
menggunakan setTimeout
, karena pada titik tertentu waktu coretan dapat
terpisah dari waktu fisik karena semakin cepat (maju cepat), lebih lambat
(frekuensi frame rendah atau tertidur untuk menghemat CPU), atau berhenti sepenuhnya
(menunggu gambar selesai dimuat).
Transisi hanyalah jenis tindakan lainnya. Selain gerakan dan rotasi dasar, kami juga mendukung gerakan relatif (misalnya, memindahkan sesuatu 10 piksel ke kanan), hal-hal kustom seperti getaran, dan juga animasi gambar keyframe.
Saya telah menyebutkan rotasi, dan hal itu juga dilakukan secara manual: kita memiliki sprite untuk berbagai sudut objek yang perlu diputar. Alasan utamanya adalah rotasi CSS3 dan kanvas memperkenalkan artefak visual yang kami anggap tidak dapat diterima – dan selain itu, artefak tersebut bervariasi di setiap platform.
Mengingat bahwa beberapa objek yang berputar terpasang ke objek berputar lain – salah satu contohnya adalah tangan robot yang terhubung ke lengan bawah, yang sendirinya terpasang ke lengan atas yang berputar – ini berarti saya juga perlu membuat transform-origin sederhana dalam bentuk pivot.
Semua ini adalah pekerjaan yang solid yang pada akhirnya mencakup dasar-dasar yang telah ditangani oleh HTML5 – tetapi terkadang dukungan native tidak cukup baik dan inilah saatnya untuk menciptakan kembali roda.
Menangani gambar dan sprite
Mesin tidak hanya untuk menjalankan doodle, tetapi juga untuk mengerjakannya. Saya telah membagikan beberapa parameter debug di atas: Anda dapat menemukan sisanya di
engine.readDebugParams
.
Spriting
adalah teknik terkenal yang juga kami gunakan untuk membuat coretan. Hal ini memungkinkan kita
menghemat byte dan mengurangi waktu pemuatan, serta mempermudah pramuat.
Namun, hal ini juga mempersulit pengembangan – setiap perubahan pada gambar akan
memerlukan pembuatan ulang (sebagian besar otomatis, tetapi masih rumit). Oleh karena itu,
mesin mendukung pengoperasian pada gambar mentah untuk pengembangan serta
sprite untuk produksi melalui engine.useSprites
– keduanya
disertakan dengan kode sumber.

Kami juga mendukung pramuat gambar seiring berjalannya waktu dan menghentikan doodle jika gambar tidak dimuat tepat waktu – lengkap dengan status progres palsu. (Faux karena, sayangnya, bahkan HTML5 tidak dapat memberi tahu kita berapa banyak file gambar yang telah dimuat.)

Untuk beberapa scene, kita menggunakan lebih dari satu sprite tidak sebanyak untuk mempercepat pemuatan menggunakan koneksi paralel, tetapi hanya karena batasan 3/5 juta piksel untuk gambar di iOS.
Di mana HTML5 sesuai dengan semua ini? Tidak banyak yang ada di atas, tetapi alat yang saya tulis untuk membuat spriting/pemangkasan adalah semua teknologi Web baru: kanvas, blob, a[download]. Salah satu hal menarik tentang HTML adalah bahwa HTML secara perlahan menyerap hal-hal yang sebelumnya harus dilakukan di luar browser; satu-satunya bagian yang perlu kita lakukan di sana adalah mengoptimalkan file PNG.
Menyimpan status di antara game
Dunia Lem selalu terasa besar, hidup, dan realistis. Ceritanya biasanya dimulai tanpa banyak penjelasan, halaman pertama dimulai dengan medias res, dengan pembaca harus menemukan jalannya sendiri.
Cyberiad tidak terkecuali dan kami ingin mereplikasi perasaan tersebut untuk doodle. Kita mulai dengan mencoba tidak menjelaskan cerita secara berlebihan. Bagian besar lainnya adalah pengacakan yang kami rasa sesuai dengan sifat mekanis alam semesta buku; kami memiliki sejumlah fungsi bantuan yang menangani pengacakan yang kami gunakan di banyak tempat.
Kami juga ingin meningkatkan replayability dengan cara lain. Untuk itu, kita perlu mengetahui berapa kali doodle selesai sebelumnya. Solusi teknologi yang secara historis benar untuk hal tersebut adalah cookie, tetapi hal itu tidak berfungsi untuk halaman beranda Google. Setiap cookie akan meningkatkan payload setiap halaman, dan sekali lagi, kami sangat memperhatikan kecepatan dan latensi.
Untungnya, HTML5 memberi kita Penyimpanan Web, yang mudah digunakan, sehingga kita dapat menyimpan dan mengingat jumlah pemutaran umum dan adegan terakhir yang diputar oleh pengguna – dengan lebih banyak kemudahan daripada yang diizinkan cookie.
Apa yang kami lakukan dengan informasi ini?
- kami menampilkan tombol maju cepat, yang memungkinkan pengguna melewati cutscene yang telah dilihat sebelumnya
- kita menampilkan item N yang berbeda selama final
- kami sedikit meningkatkan tingkat kesulitan pengambilan gambar
- kami menampilkan sedikit easter egg probability dragon dari cerita yang berbeda pada pemutaran ketiga dan berikutnya
Ada sejumlah parameter debug yang mengontrol hal ini:
?doodle-debug&doodle-first-run
– berpura-puralah bahwa ini adalah pengujian mesin perdana?doodle-debug&doodle-second-run
– berpura-puralah bahwa ini adalah operasi kedua?doodle-debug&doodle-old-run
– berpura-puralah bahwa ini adalah lari lama
Perangkat sentuh
Kami ingin doodle terasa nyaman di perangkat sentuh – perangkat yang paling modern cukup canggih sehingga doodle berjalan dengan sangat baik, dan mengalami game melalui ketukan jauh lebih menyenangkan daripada dengan mengklik.
Beberapa perubahan awal pada pengalaman pengguna perlu dilakukan. Awalnya, kursor mouse adalah satu-satunya tempat yang menyampaikan bagian cutscene/non-interaktif sedang berlangsung. Kemudian, kita menambahkan sedikit indikator di sudut kanan bawah, sehingga kita tidak perlu mengandalkan kursor mouse saja (mengingat kursor tidak ada di perangkat sentuh).
Normal | Sibuk | Dapat diklik | Diklik | |
---|---|---|---|---|
Dalam proses | ![]() |
![]() |
![]() |
![]() |
Final | ![]() |
![]() |
![]() |
![]() |
Sebagian besar fitur dapat langsung digunakan. Namun, pengujian kegunaan secara spontan dan cepat dari pengalaman sentuh kami menunjukkan dua masalah: beberapa target terlalu sulit ditekan, dan ketukan cepat diabaikan karena kita baru saja mengganti peristiwa klik mouse.
Memiliki elemen DOM transparan yang dapat diklik secara terpisah sangat membantu di sini, karena saya dapat mengubah ukurannya secara terpisah dari visual. Saya memperkenalkan padding tambahan 15 piksel untuk perangkat sentuh dan menggunakannya setiap kali elemen yang dapat diklik dibuat. (Saya juga menambahkan padding 5 piksel untuk lingkungan mouse, hanya untuk membuat Mr. Fitts senang.)
Untuk masalah lainnya, saya hanya memastikan untuk melampirkan dan menguji pengendali awal dan akhir sentuh yang tepat, bukan mengandalkan klik mouse.
Kami juga menggunakan properti gaya yang lebih modern untuk menghapus beberapa fitur sentuh yang ditambahkan browser WebKit secara default (sorot ketuk, info ketuk).
Dan bagaimana cara mendeteksi apakah perangkat tertentu yang menjalankan doodle mendukung sentuhan? Secara lambat. Daripada mencari tahu sebelumnya, kita hanya menggunakan IQ gabungan untuk menyimpulkan bahwa perangkat mendukung sentuhan… setelah kita mendapatkan peristiwa awal sentuhan pertama.
Menyesuaikan kursor mouse
Namun, tidak semuanya berbasis sentuh. Salah satu prinsip panduan kami adalah menempatkan sebanyak mungkin hal dalam dunia doodle. UI sidebar kecil (maju cepat, tanda tanya), tooltip, dan bahkan, kursor mouse.
Bagaimana cara menyesuaikan kursor mouse? Beberapa browser memungkinkan perubahan kursor mouse dengan menautkan ke file gambar khusus. Namun, hal ini tidak didukung dengan baik dan juga agak membatasi.
Jika bukan ini, lalu apa? Nah, mengapa tidak menjadikan kursor mouse sebagai aktor lain dalam doodle? Cara ini berfungsi, tetapi disertai dengan sejumlah ketentuan, terutama:
- Anda harus dapat menghapus kursor mouse native
- Anda harus cukup mahir dalam menjaga kursor mouse tetap sinkron dengan kursor "sebenarnya"
Yang pertama itu rumit. CSS3 memungkinkan cursor: none
, tetapi
juga tidak didukung di beberapa browser. Kita perlu melakukan beberapa
hal: menggunakan file .cur
kosong sebagai penggantian, menentukan perilaku
yang konkret untuk beberapa browser, dan bahkan melakukan hard code pada browser lain dari
pengalaman apa pun.
Yang lainnya relatif sepele, tetapi dengan kursor mouse yang hanya merupakan bagian lain dari dunia doodle, kursor tersebut juga akan mewarisi semua masalahnya. Tantangan terbesarnya? Jika kecepatan frame doodle rendah, kecepatan frame pointer mouse juga akan rendah – dan hal itu memiliki konsekuensi yang mengerikan karena pointer mouse, sebagai ekstensi alami tangan Anda, harus terasa responsif apa pun yang terjadi. (Orang-orang yang pernah menggunakan Commodore Amiga kini mengangguk dengan keras.)
Salah satu solusi yang agak rumit untuk masalah tersebut adalah memisahkan kursor mouse dari loop update reguler. Kita melakukannya – di alam lain tempat saya tidak perlu tidur. Solusi yang lebih sederhana untuk masalah ini? Cukup kembali ke kursor mouse native jika kecepatan frame bergulir turun di bawah 20 fps. (Di sinilah kecepatan frame rolling berguna. Jika kita bereaksi terhadap kecepatan frame saat ini, dan jika terjadi osilasi sekitar 20 fps, pengguna akan melihat kursor mouse kustom yang selalu disembunyikan dan ditampilkan.) Hal ini akan membawa kita ke:
Rentang kecepatan frame | Perilaku |
---|---|
>10fps | Perlambat game agar lebih banyak frame yang tidak dihapus. |
10–20fps | Gunakan kursor mouse native, bukan kursor kustom. |
20–60fps | Operasi normal. |
>60fps | Batasi agar kecepatan frame tidak melebihi nilai ini. |
Oh, dan kursor mouse kita berwarna gelap di Mac, tetapi berwarna putih di PC. Mengapa? Karena perang platform membutuhkan bahan bakar bahkan di alam semesta fiksi.
Kesimpulan
Ini bukan mesin yang sempurna, tetapi tidak berusaha menjadi sempurna. Aplikasi ini dikembangkan bersama doodle Lem, dan sangat spesifik untuknya. Tidak masalah. “Pengoptimalan yang terlalu dini adalah akar dari semua kejahatan”, seperti yang diucapkan Don Knuth, dan saya tidak percaya bahwa menulis mesin secara terpisah terlebih dahulu, dan hanya menerapkannya nanti adalah hal yang masuk akal – praktik ini memberi tahu teori sebanyak teori memberi tahu praktik. Dalam kasus saya, kode dihapus, beberapa bagian ditulis ulang berulang kali, dan banyak bagian umum diperhatikan setelahnya, bukan sebelum fakta. Namun, pada akhirnya, apa yang kita miliki di sini memungkinkan kita melakukan hal yang kita inginkan – merayakan karier Stanisław Lem dan gambar oleh Daniel Mróz dengan cara terbaik yang dapat kita pikirkan.
Semoga penjelasan di atas dapat menjelaskan beberapa pilihan desain dan kompromi yang perlu kita buat – dan cara kita menggunakan HTML5 dalam skenario tertentu di dunia nyata. Sekarang, mainkan kode sumber, coba, dan beri tahu kami pendapat Anda.
Saya melakukannya sendiri – gambar di bawah ini ditayangkan dalam beberapa hari terakhir, menghitung mundur ke dini hari 23 November 2011 di Rusia, yang merupakan zona waktu pertama yang melihat doodle Lem. Mungkin hal yang konyol, tetapi seperti coretan, hal-hal yang tampak tidak penting terkadang memiliki makna yang lebih dalam – penghitung ini benar-benar merupakan “pengujian stres” yang bagus untuk mesin.

Dan itulah salah satu cara untuk melihat siklus proses doodle Google – berbulan-bulan bekerja, berminggu-minggu melakukan pengujian, 48 jam untuk menyiapkannya, semuanya untuk sesuatu yang dimainkan orang selama lima menit. Setiap baris JavaScript dari ribuan baris tersebut berharap bahwa 5 menit tersebut akan menjadi waktu yang bermanfaat. Selamat menikmati.