Membangun dengan Chrome

Menghadirkan bata LEGO® ke Web Multiperangkat

Build with Chrome, eksperimen seru untuk pengguna Chrome desktop yang awalnya diluncurkan di Australia, dirilis ulang pada tahun 2014 yang dilengkapi dengan ketersediaan global, memiliki keterkaitan dengan THE LEGO® moviesTM, dan dukungan yang baru ditambahkan untuk perangkat seluler. Dalam artikel ini, kami akan membagikan beberapa pembelajaran dari project ini, terutama terkait peralihan dari pengalaman khusus desktop ke solusi multilayar yang mendukung input mouse dan sentuh.

Sejarah Membangun dengan Chrome

Versi pertama Build with Chrome diluncurkan di Australia pada tahun 2012. Kami ingin mendemonstrasikan kekuatan web dengan cara yang benar-benar baru dan menghadirkan Chrome kepada audiens yang benar-benar baru.

Situs ini memiliki dua bagian utama: mode "Bangun" yang memungkinkan pengguna membuat kreasi menggunakan bata LEGO, dan mode "Explore" untuk menjelajahi kreasi di Google Maps versi lego.

3D interaktif sangat penting untuk memberi pengguna pengalaman bangunan LEGO terbaik. Pada tahun 2012, WebGL hanya tersedia untuk publik di browser desktop, sehingga Build ditargetkan sebagai pengalaman khusus desktop. Explore menggunakan Google Maps untuk menampilkan kreasi, tetapi saat memperbesarnya cukup dekat, Explore akan beralih ke implementasi WebGL dari peta yang menampilkan kreasi dalam 3D, masih menggunakan peta Google sebagai tekstur pelat dasar. Kami berharap dapat membangun sebuah lingkungan tempat penggemar LEGO dari segala usia dapat dengan mudah dan intuitif mengekspresikan kreativitas mereka serta mengeksplorasi kreasi satu sama lain.

Pada tahun 2013, kami memutuskan untuk memperluas Build with Chrome ke teknologi web baru. Di antara teknologi tersebut adalah WebGL di Chrome untuk Android, yang secara alami akan memungkinkan Build dengan Chrome berkembang menjadi pengalaman seluler. Untuk memulai, pertama-tama kami mengembangkan prototipe sentuh sebelum mempertanyakan hardware untuk "Alat Pembuat" guna memahami perilaku gestur dan respons taktil yang mungkin kita hadapi melalui browser dibandingkan dengan aplikasi seluler.

Front-end yang Responsif

Kita harus mendukung perangkat dengan input sentuh dan mouse. Namun, penggunaan UI yang sama pada layar sentuh kecil ternyata menjadi solusi yang kurang optimal karena keterbatasan ruang.

Di Build, ada banyak interaktivitas yang terjadi: memperbesar dan memperkecil, mengubah warna bata, dan tentu saja memilih, memutar, dan menempatkan batu bata. Ini adalah sebuah alat di mana pengguna sering menghabiskan banyak waktu, jadi penting bagi mereka untuk memiliki akses cepat ke semua hal yang sering mereka gunakan, dan mereka harus merasa nyaman saat berinteraksi dengannya.

Saat mendesain aplikasi sentuh yang sangat interaktif, Anda akan menemukan bahwa layar dengan cepat terasa kecil dan jari-jari pengguna cenderung menutupi banyak layar saat berinteraksi. Hal ini menjadi jelas bagi kami saat bekerja dengan Builder. Anda benar-benar harus mempertimbangkan ukuran layar fisik daripada piksel dalam grafis saat melakukan desain. Penting untuk meminimalkan jumlah tombol dan kontrol untuk mendapatkan ruang layar sebanyak mungkin yang didedikasikan untuk konten sebenarnya.

Tujuan kami adalah membuat Build terasa alami di perangkat sentuh, tidak hanya menambahkan input sentuh ke implementasi desktop asli, tetapi membuatnya terasa seolah-olah memang ditujukan untuk sentuhan. Kita akhirnya memiliki dua variasi UI, satu untuk desktop dan tablet dengan layar besar dan satu untuk perangkat seluler dengan layar yang lebih kecil. Jika memungkinkan, sebaiknya gunakan satu implementasi dan lakukan transisi yang lancar antarmode. Dalam kasus ini, kami memutuskan bahwa ada perbedaan pengalaman yang sangat signifikan antara kedua mode ini sehingga kami memutuskan untuk mengandalkan titik henti sementara tertentu. Kedua versi ini memiliki banyak fitur yang sama dan kami telah mencoba melakukan sebagian besar hal hanya dengan satu implementasi kode, tetapi beberapa aspek UI berfungsi secara berbeda di antara keduanya.

Kami menggunakan data agen pengguna untuk mendeteksi perangkat seluler, lalu memeriksa ukuran area pandang untuk memutuskan apakah UI seluler layar kecil harus digunakan. Agak sulit untuk memilih titik henti sementara yang semestinya seperti "layar besar", karena sulit untuk mendapatkan nilai yang dapat diandalkan dari ukuran layar fisik. Untungnya, dalam kasus ini, tidak terlalu penting jika kita menampilkan UI layar kecil pada perangkat sentuh dengan layar besar, karena alat ini akan tetap berfungsi dengan baik, hanya saja beberapa tombol mungkin terasa sedikit terlalu besar. Pada akhirnya, kita menetapkan titik henti sementara menjadi 1.000 piksel; jika Anda memuat situs dari jendela yang lebih lebar dari 1.000 piksel (dalam mode lanskap), Anda akan mendapatkan versi layar besar.

Mari kita bahas sedikit tentang dua ukuran layar dan pengalaman:

Perangkat layar besar, dengan dukungan mouse dan sentuh

Versi layar besar ditayangkan ke semua komputer desktop yang memiliki dukungan mouse dan untuk perangkat sentuh dengan layar besar (seperti Google Nexus 10). Versi ini mirip dengan solusi desktop asli dalam jenis kontrol navigasi yang tersedia, tetapi kami menambahkan dukungan sentuh dan beberapa gestur. Kami menyesuaikan UI bergantung pada ukuran jendela, jadi saat pengguna mengubah ukuran jendela, ia mungkin akan menghapus atau mengubah ukuran beberapa UI. Kami melakukannya menggunakan kueri media CSS.

Contoh: Jika tinggi yang tersedia kurang dari 730 piksel, kontrol penggeser zoom dalam mode Jelajahi akan disembunyikan:

@media only screen and (max-height: 730px) {
    .zoom-slider {
        display: none;
    }
}

Layar kecil, hanya dukungan sentuh

Versi ini ditayangkan ke perangkat seluler dan tablet kecil (perangkat target, Nexus 4 dan Nexus 7). Versi ini memerlukan dukungan multi-sentuh.

Pada perangkat layar kecil, kami perlu memberikan ruang layar sebanyak mungkin kepada konten, jadi kami melakukan beberapa penyesuaian untuk memaksimalkan ruang, terutama dengan memindahkan elemen yang jarang digunakan agar tidak terlihat:

  • Pemilih bata Build diperkecil menjadi pemilih warna saat membangun.
  • Kami mengganti kontrol zoom dan orientasi dengan gestur multi-kontrol.
  • Fungsi layar penuh Chrome juga membantu mendapatkan ruang layar ekstra.
Membangun aplikasi di perangkat layar besar
Buat aplikasi di perangkat layar besar. Pemilih fisik selalu terlihat dan ada beberapa kontrol di sisi kanan.
Membangun aplikasi di layar kecil
Buat aplikasi di layar kecil. Pemilih bata diperkecil dan beberapa tombol telah dihapus.

Performa dan Dukungan WebGL

Perangkat sentuh modern memiliki GPU yang cukup canggih, tetapi masih jauh dari perangkat desktop, jadi kami tahu bahwa akan ada beberapa tantangan dalam hal performa, terutama dalam mode Explore 3D yang mengharuskan kita merender banyak kreasi secara bersamaan.

Secara kreatif, kami ingin menambahkan beberapa jenis bata baru dengan bentuk yang rumit dan bahkan transparansi -- fitur yang biasanya sangat berat di GPU. Namun, kami harus kompatibel dengan versi lama dan terus mendukung kreasi dari versi pertama, jadi kami tidak dapat menetapkan batasan baru, misalnya mengurangi jumlah total batu bata secara signifikan dalam kreasi tersebut.

Pada Build versi pertama, kami memiliki batas maksimum batu bata yang bisa digunakan dalam satu kreasi. Terdapat "meter bata" yang menunjukkan jumlah batu bata yang tersisa. Dalam implementasi baru, beberapa batu bata baru memiliki pengaruh yang lebih besar pada batu bata dibandingkan dengan batu bata standar, sehingga sedikit mengurangi jumlah total batu bata maksimum. Ini adalah salah satu cara untuk memasukkan batu bata baru, sekaligus tetap mempertahankan performanya.

Dalam mode Jelajahi 3D, ada cukup banyak hal yang terjadi secara bersamaan; memuat tekstur pelat dasar, memuat kreasi, menganimasikan dan merender kreasi, dan sebagainya. Ini membutuhkan banyak hal dari GPU dan CPU, jadi kami melakukan banyak pembuatan profil bingkai di Chrome DevTools untuk mengoptimalkan bagian-bagian ini sebanyak mungkin. Pada perangkat seluler, kami memutuskan untuk memperbesar sedikit demi sedikit kreasi sehingga kami tidak perlu merender kreasi sebanyak mungkin sekaligus.

Beberapa perangkat meminta kami meninjau kembali dan menyederhanakan beberapa shader WebGL, tetapi kami selalu menemukan cara untuk menyelesaikannya dan melanjutkan.

Mendukung perangkat non-WebGL

Kami ingin situs dapat bermanfaat meskipun perangkat pengunjung tidak mendukung WebGL. Terkadang ada cara untuk merepresentasikan 3D dengan cara yang disederhanakan menggunakan solusi kanvas atau fitur CSS3D. Sayangnya, kami tidak menemukan solusi yang cukup baik untuk mereplikasi fitur Build dan Explore 3D tanpa menggunakan WebGL.

Agar konsisten, gaya visual kreasi harus sama di semua platform. Kami berpotensi mencoba menggunakan solusi 2.5D, namun ini akan membuat kreasi terlihat berbeda dalam beberapa hal. Kami juga harus mempertimbangkan cara memastikan bahwa kreasi yang dibuat menggunakan Build with Chrome versi pertama akan terlihat sama dan berjalan mulus di situs versi baru seperti yang dilakukan di versi pertama.

Mode 2D masih dapat diakses oleh perangkat non-WebGL, meskipun Anda tidak dapat membuat kreasi baru atau menjelajah dalam 3D. Jadi, pengguna masih bisa mendapatkan gambaran tentang kedalaman project dan apa yang dapat dibuat menggunakan alat ini jika mereka menggunakan perangkat yang mendukung WebGL. Situs mungkin tidak terlalu berharga bagi pengguna tanpa dukungan WebGL, tetapi setidaknya harus berfungsi sebagai pemikat dan membuat mereka terlibat dalam mencobanya.

Menyimpan versi penggantian untuk solusi WebGL terkadang tidak mungkin dilakukan. Ada banyak kemungkinan alasan; biaya performa, gaya visual, pengembangan dan pemeliharaan, dan sebagainya. Namun, bila Anda memutuskan untuk tidak menerapkan penggantian, Anda setidaknya harus menangani pengunjung yang tidak mendukung WebGL, menjelaskan alasan mereka tidak dapat mengakses situs secara penuh, dan memberikan petunjuk tentang cara mengatasi masalah tersebut dengan menggunakan browser yang mendukung WebGL.

Manajemen Aset

Pada tahun 2013, Google memperkenalkan versi baru Google Maps dengan perubahan UI yang paling signifikan sejak diluncurkan. Jadi, kami memutuskan untuk mendesain ulang Build with Chrome agar sesuai dengan UI Google Maps yang baru, dan dalam melakukannya, kami mempertimbangkan faktor lain dalam desain ulang tersebut. Desain baru relatif datar dengan warna solid yang bersih dan bentuk yang sederhana. Ini memungkinkan kita untuk menggunakan CSS murni pada banyak elemen UI, sehingga meminimalkan penggunaan gambar.

Dalam Jelajahi, kita perlu memuat banyak gambar; gambar thumbnail untuk kreasi, tekstur peta untuk pelat dasar, dan terakhir kreasi 3D. Kami sangat berhati-hati untuk memastikan bahwa tidak ada kebocoran memori saat kita terus-menerus memuat gambar baru.

Kreasi 3D disimpan dalam format file khusus yang dikemas sebagai gambar PNG. Dengan menyimpan data kreasi 3D sebagai gambar, kami dapat meneruskan data secara langsung ke shader yang merender kreasi tersebut.

Untuk semua gambar yang dibuat pengguna, desain ini memungkinkan kami menggunakan ukuran gambar yang sama untuk semua platform, sehingga meminimalkan penggunaan bandwidth dan penyimpanan.

Mengelola Orientasi Layar

Sangat mudah untuk melupakan seberapa besar perubahan rasio aspek layar saat beralih dari mode potret ke mode lanskap atau sebaliknya. Anda perlu mempertimbangkan hal ini sejak awal saat beradaptasi untuk perangkat seluler.

Di situs tradisional dengan scroll aktif, Anda dapat menerapkan aturan CSS untuk mendapatkan situs responsif yang mengatur ulang konten dan menu. Selama Anda dapat menggunakan fungsi scroll, hal ini cukup mudah dikelola.

Kami juga menggunakan metode ini dengan Build, tetapi cara kami memecahkan tata letak agak terbatas, karena kami harus membuat konten terlihat setiap saat dan tetap memiliki akses cepat ke sejumlah kontrol dan tombol. Untuk situs konten murni seperti situs berita, tata letak yang fleksibel sangat masuk akal, tetapi bagi aplikasi game seperti aplikasi kami itu adalah hal yang sulit. Menemukan tata letak yang berfungsi baik dalam orientasi lanskap maupun potret menjadi tantangan tersendiri, sambil tetap mempertahankan ringkasan konten yang baik dan cara berinteraksi yang nyaman. Pada akhirnya, kami memutuskan untuk tetap menggunakan Build dalam mode lanskap dan memberi tahu pengguna untuk memutar perangkatnya.

Penjelajahan jauh lebih mudah dipecahkan di kedua orientasi. Kita hanya perlu menyesuaikan tingkat zoom 3D untuk mendapatkan pengalaman yang konsisten.

Sebagian besar tata letak konten dikontrol oleh CSS, tetapi beberapa hal terkait orientasi perlu diimplementasikan dalam JavaScript. Kami menemukan bahwa tidak ada solusi lintas perangkat yang baik untuk menggunakan window.Orientation untuk mengidentifikasi orientasi, sehingga pada akhirnya kami hanya membandingkan window.innerWidth dan window.innerHeight untuk mengidentifikasi orientasi perangkat.

if( window.innerWidth > window.innerHeight ){
  //landscape
} else {
  //portrait
}

Menambahkan Dukungan Sentuh

Menambahkan dukungan sentuh ke konten web cukup mudah. Interaktivitas dasar, seperti peristiwa klik, berfungsi sama di desktop dan perangkat yang mendukung sentuhan, tetapi jika menyangkut interaksi yang lebih canggih, Anda juga perlu menangani peristiwa sentuh: touchstart, touchmove, dan touchend. Artikel ini membahas dasar-dasar cara menggunakan peristiwa ini. Internet Explorer tidak mendukung peristiwa sentuh, tetapi menggunakan Peristiwa Pointer (pointerdown, pointermove, pointerup). Pointer Events telah dikirimkan ke W3C untuk standardisasi, tetapi untuk saat ini hanya diterapkan di Internet Explorer.

Pada mode Jelajahi 3D, kami menginginkan navigasi yang sama seperti penerapan Google Maps standar; menggunakan satu jari untuk menggeser peta dan mencubit dengan dua jari untuk memperbesar. Karena kreasi dilakukan dalam 3D, kami juga menambahkan gestur putar dua jari. Hal ini biasanya memerlukan penggunaan peristiwa sentuh.

Praktik yang baik adalah menghindari komputasi berat, seperti mengupdate atau merender 3D di pengendali peristiwa. Sebagai gantinya, simpan input sentuh dalam variabel dan berikan reaksi pada input tersebut dalam loop render requestAnimationFrame. Hal ini juga mempermudah implementasi mouse secara bersamaan, hanya dengan menyimpan nilai mouse yang sesuai dalam variabel yang sama.

Mulailah dengan menginisialisasi objek untuk menyimpan input dan menambahkan pemroses peristiwa touchstart. Di setiap pengendali peristiwa, kita memanggil event.preventDefault(). Ini untuk mencegah browser melanjutkan proses peristiwa sentuh, yang dapat menyebabkan beberapa perilaku tidak terduga seperti men-scroll atau menskalakan seluruh halaman.

var input = {dragStartX:0, dragStartY:0, dragX:0, dragY:0, dragDX:0, dragDY:0, dragging:false};
plateContainer.addEventListener('touchstart', onTouchStart);

function onTouchStart(event) {
  event.preventDefault();
  if( event.touches.length === 1){
    handleDragStart(event.touches[0].clientX , event.touches[0].clientY);
    //start listening to all needed touchevents to implement the dragging
    document.addEventListener('touchmove', onTouchMove);
    document.addEventListener('touchend', onTouchEnd);
    document.addEventListener('touchcancel', onTouchEnd);
  }
}

function onTouchMove(event) {
  event.preventDefault();
  if( event.touches.length === 1){
    handleDragging(event.touches[0].clientX, event.touches[0].clientY);
  }
}

function onTouchEnd(event) {
  event.preventDefault();
  if( event.touches.length === 0){
    handleDragStop();
    //remove all eventlisteners but touchstart to minimize number of eventlisteners
    document.removeEventListener('touchmove', onTouchMove);
    document.removeEventListener('touchend', onTouchEnd);
    //also listen to touchcancel event to avoid unexpected behavior when switching tabs and some other situations
    document.removeEventListener('touchcancel', onTouchEnd);
  }
}

Kita tidak melakukan penyimpanan input sebenarnya dalam pengendali peristiwa melainkan dalam pengendali terpisah: handleDragStart, handleDragging, dan handleDragStop. Ini karena kita ingin memanggilnya dari pengendali peristiwa mouse juga. Perlu diingat bahwa meskipun tidak mungkin, pengguna dapat menggunakan sentuhan dan mouse secara bersamaan. Daripada menangani kasus itu secara langsung, kami hanya memastikan tidak ada yang meledak.

function handleDragStart(x ,y ){
  input.dragging = true;
  input.dragStartX = input.dragX = x;
  input.dragStartY = input.dragY = y;
}

function handleDragging(x ,y ){
  if(input.dragging) {
    input.dragDX = x - input.dragX;
    input.dragDY = y - input.dragY;
    input.dragX = x;
    input.dragY = y;
  }
}

function handleDragStop(){
  if(input.dragging) {
    input.dragging = false;
    input.dragDX = 0;
    input.dragDY = 0;
  }
}

Saat melakukan animasi berdasarkan touchmove, menyimpan gerakan delta juga sering kali berguna sejak peristiwa terakhir. Misalnya, kami menggunakan ini sebagai parameter untuk kecepatan kamera saat bergerak di semua pelat dudukan di Explore, karena Anda tidak menarik pelat dudukan, tetapi Anda benar-benar menggerakkan kamera.

function onAnimationFrame() {
  requestAnimationFrame( onAnimationFrame );

  //execute animation based on input.dragDX, input.dragDY, input.dragX or input.dragY
 /*
  /
  */

  //because touchmove is only fired when finger is actually moving we need to reset the delta values each frame
  input.dragDX=0;
  input.dragDY=0;
}

Contoh tersemat: Menarik objek menggunakan peristiwa sentuh. Implementasi yang mirip dengan menarik peta 3D di Build with Chrome: http://cdpn.io/qDxvo

Gestur Multisentuh

Ada beberapa framework atau library, seperti Hammer atau QuoJS, yang dapat menyederhanakan pengelolaan gestur multi-kontrol, tetapi jika Anda ingin menggabungkan beberapa gestur dan mendapatkan kontrol penuh, sebaiknya lakukan dari awal.

Untuk mengelola gestur cubit dan putar, kami menyimpan jarak dan sudut antara dua jari saat jari kedua ditampilkan di layar:

//variables representing the actual scale/rotation of the object we are affecting
var currentScale = 1;
var currentRotation = 0;

function onTouchStart(event) {
  event.preventDefault();
  if( event.touches.length === 1){
    handleDragStart(event.touches[0].clientX , event.touches[0].clientY);
  }else if( event.touches.length === 2 ){
    handleGestureStart(event.touches[0].clientX, event.touches[0].clientY, event.touches[1].clientX, event.touches[1].clientY );
  }
}

function handleGestureStart(x1, y1, x2, y2){
  input.isGesture = true;
  //calculate distance and angle between fingers
  var dx = x2 - x1;
  var dy = y2 - y1;
  input.touchStartDistance=Math.sqrt(dx*dx+dy*dy);
  input.touchStartAngle=Math.atan2(dy,dx);
  //we also store the current scale and rotation of the actual object we are affecting. This is needed to support incremental rotation/scaling. We can't assume that an object is always the same scale when gesture starts.
  input.startScale=currentScale;
  input.startAngle=currentRotation;
}

Dalam peristiwa touchmove, kami akan terus mengukur jarak dan sudut antara kedua jari tersebut. Perbedaan antara jarak awal dan jarak saat ini digunakan untuk menyetel skala, dan perbedaan antara sudut awal dan sudut saat ini digunakan untuk menetapkan sudut.

function onTouchMove(event) {
  event.preventDefault();
  if( event.touches.length  === 1){
    handleDragging(event.touches[0].clientX, event.touches[0].clientY);
  }else if( event.touches.length === 2 ){
    handleGesture(event.touches[0].clientX, event.touches[0].clientY, event.touches[1].clientX, event.touches[1].clientY );
  }
}

function handleGesture(x1, y1, x2, y2){
  if(input.isGesture){
    //calculate distance and angle between fingers
    var dx = x2 - x1;
    var dy = y2 - y1;
    var touchDistance = Math.sqrt(dx*dx+dy*dy);
    var touchAngle = Math.atan2(dy,dx);
    //calculate the difference between current touch values and the start values
    var scalePixelChange = touchDistance - input.touchStartDistance;
    var angleChange = touchAngle - input.touchStartAngle;
    //calculate how much this should affect the actual object
    currentScale = input.startScale + scalePixelChange*0.01;
    currentRotation = input.startAngle+(angleChange*180/Math.PI);
    //upper and lower limit of scaling
    if(currentScale<0.5) currentScale = 0.5;
    if(currentScale>3) currentScale = 3;
  }
}

Anda berpotensi menggunakan perubahan jarak antara setiap peristiwa touchmove dengan cara yang sama seperti contoh dengan menarik, tetapi pendekatan tersebut sering kali lebih berguna saat Anda menginginkan gerakan berkelanjutan.

function onAnimationFrame() {
  requestAnimationFrame( onAnimationFrame );
  //execute transform based on currentScale and currentRotation
  /*
  /
  */

  //because touchmove is only fired when finger is actually moving we need to reset the delta values each frame
  input.dragDX=0;
  input.dragDY=0;
}

Anda juga dapat mengaktifkan penarikan objek saat melakukan gestur cubit dan putar jika ingin. Dalam hal ini, Anda akan menggunakan titik tengah di antara dua jari sebagai input untuk pengendali penarikan.

Contoh tersemat: Memutar dan menskalakan objek dalam 2D. Mirip dengan penerapan peta di Explore: http://cdpn.io/izloq

Dukungan Mouse dan Sentuhan pada Hardware yang Sama

Saat ini, ada beberapa komputer laptop, seperti Chromebook Pixel, yang mendukung input mouse dan sentuh. Hal ini dapat menyebabkan beberapa perilaku tak terduga jika Anda tidak berhati-hati.

Satu hal yang penting adalah Anda tidak hanya mendeteksi dukungan sentuh kemudian mengabaikan input mouse, tetapi juga mendukung keduanya secara bersamaan.

Jika Anda tidak menggunakan event.preventDefault() dalam pengendali peristiwa sentuh, akan ada beberapa peristiwa mouse yang diemulasikan, sehingga sebagian besar situs yang dioptimalkan untuk non-sentuh tetap berfungsi. Misalnya, untuk satu ketukan di layar, peristiwa ini dapat diaktifkan dalam urutan cepat dan dalam urutan ini:

  1. mulai sentuh
  2. gerakan sentuh
  3. {i>touchend<i}
  4. mouseover
  5. mousemove
  6. mousedown
  7. gerakan mouse
  8. click

Jika Anda memiliki interaksi yang sedikit lebih kompleks, peristiwa mouse ini dapat menyebabkan beberapa perilaku yang tidak diharapkan, dan mengacaukan implementasi Anda. Sebaiknya gunakan event.preventDefault() dalam pengendali peristiwa sentuh dan kelola input mouse dalam pengendali peristiwa terpisah. Anda perlu mengetahui bahwa menggunakan event.preventDefault() di pengendali peristiwa sentuh juga akan mencegah beberapa perilaku default, seperti men-scroll dan peristiwa klik.

"Di Build with Chrome, kami tidak ingin zoom terjadi saat seseorang mengetuk situs dua kali, meskipun itu adalah hal standar di sebagian besar browser. Jadi, kita menggunakan tag meta area pandang untuk memberi tahu browser agar tidak melakukan zoom saat pengguna mengetuk dua kali. Hal ini juga menghilangkan penundaan klik 300 md, yang meningkatkan responsivitas situs. (Penundaan klik digunakan untuk membuat perbedaan antara sekali ketuk dan ketuk dua kali saat zoom ketuk dua kali diaktifkan.)

<meta name="viewport" content="width=device-width,user-scalable=no">

Ingatlah bahwa saat menggunakan fitur ini, Anda harus membuat situs dapat dibaca di semua ukuran layar, karena pengguna tidak akan dapat memperbesar/memperkecil tampilan.

Input Mouse, Sentuhan, dan Keyboard

Dalam mode Jelajahi 3D, kami ingin ada tiga cara untuk menavigasi peta: mouse (menyeret), sentuh (menyeret, mencubit untuk memperbesar dan memutar), dan keyboard (navigasi dengan tombol panah). Semua metode navigasi ini berfungsi sedikit berbeda, tetapi kami menggunakan pendekatan yang sama pada semuanya; menyetel variabel dalam pengendali peristiwa dan menindaklanjutinya dalam loop requestAnimationFrame. Loop requestAnimationFrame tidak perlu mengetahui metode mana yang digunakan untuk menavigasi.

Sebagai contoh, kita dapat menetapkan pergerakan peta (dragDX dan dragDY) dengan ketiga metode input tersebut. Berikut adalah implementasi keyboard:

document.addEventListener('keydown', onKeyDown );
document.addEventListener('keyup', onKeyUp );

function onKeyDown( event ) {
  input.keyCodes[ "k" + event.keyCode ] = true;
  input.shiftKey = event.shiftKey;
}

function onKeyUp( event ) {
  input.keyCodes[ "k" + event.keyCode ] = false;
  input.shiftKey = event.shiftKey;
}

//this needs to be called every frame before animation is executed
function handleKeyInput(){
  if(input.keyCodes.k37){
    input.dragDX = -5; //37 arrow left
  } else if(input.keyCodes.k39){
    input.dragDX = 5; //39 arrow right
  }
  if(input.keyCodes.k38){
    input.dragDY = -5; //38 arrow up
  } else if(input.keyCodes.k40){
    input.dragDY = 5; //40 arrow down
  }
}

function onAnimationFrame() {
  requestAnimationFrame( onAnimationFrame );
  //because keydown events are not fired every frame we need to process the keyboard state first
  handleKeyInput();
  //implement animations based on what is stored in input
   /*
  /
  */

  //because touchmove is only fired when finger is actually moving we need to reset the delta values each frame
  input.dragDX = 0;
  input.dragDY = 0;
}

Contoh tersemat: Menggunakan mouse, sentuh, dan keyboard untuk menavigasi: http://cdpn.io/catlf

Ringkasan

Mengadaptasikan Build with Chrome untuk mendukung perangkat sentuh dengan berbagai ukuran layar adalah pengalaman belajar. Tim kami tidak memiliki banyak pengalaman dalam melakukan level interaktivitas ini di perangkat sentuh dan kami belajar banyak selama melakukannya.

Tantangan terbesarnya ternyata adalah bagaimana memecahkan pengalaman pengguna dan desain. Tantangan teknisnya adalah mengelola banyak ukuran layar, peristiwa sentuh, dan masalah performa.

Meskipun ada beberapa tantangan dengan shader WebGL pada perangkat sentuh, ini adalah sesuatu yang bekerja hampir lebih baik dari yang diharapkan. Perangkat menjadi semakin canggih dan penerapan WebGL meningkat dengan cepat. Kami merasa bahwa kami akan lebih sering menggunakan WebGL di perangkat dalam waktu dekat.

Sekarang, jika Anda belum melakukannya, mulailah dan buat sesuatu yang luar biasa!