LEGO® tuğlalarını çok cihazlı web'e taşıma
İlk olarak Avustralya'da kullanıma sunulan, masaüstü Chrome kullanıcıları için eğlenceli bir deneme olan Build with Chrome, 2014'te dünya genelinde kullanıma sunuldu. Bu sürümde, THE LEGO® MOVIE™ ile bağlantılı içerikler ve mobil cihazlar için yeni eklenen destek de yer aldı. Bu makalede, projeden edindiğimiz bazı bilgileri, özellikle de yalnızca masaüstü deneyiminden hem fare hem de dokunmatik girişi destekleyen çok ekranlı bir çözüme geçişle ilgili olarak paylaşacağız.
Chrome ile Geliştirme'nin Geçmişi
Build with Chrome'un ilk sürümü 2012'de Avustralya'da kullanıma sunuldu. Web'in gücünü yepyeni bir şekilde göstermek ve Chrome'u yepyeni bir kitleye tanıtmak istedik.
Sitenin iki ana bölümü vardı: Kullanıcıların LEGO tuğlalarını kullanarak yapımlar oluşturabileceği "Oluştur" modu ve Google Haritalar'ın LEGO'laştırılmış bir sürümünde yapımlara göz atabileceğiniz "Keşfet" modu.
Kullanıcılara en iyi LEGO yapım deneyimini sunmak için etkileşimli 3D teknolojisi kullanıldı. 2012'de WebGL yalnızca masaüstü tarayıcılarda herkese açık olarak kullanılabiliyordu. Bu nedenle Build, yalnızca masaüstünde kullanılabilecek bir deneyim olarak hedeflendi. Keşfet, içerikleri görüntülemek için Google Haritalar'ı kullanır ancak yeterince yakınlaştırıldığında, içerikleri 3D olarak gösteren haritanın WebGL uygulamasına geçer. Bu uygulamada, taban plakası dokusu olarak yine Google Haritalar kullanılır. Her yaştan LEGO tutkununun yaratıcılıklarını kolayca ve sezgisel bir şekilde ifade edebileceği ve birbirlerinin çalışmalarını keşfedebileceği bir ortam oluşturmayı umuyorduk.
2013'te, Chrome ile Geliştirme'yi yeni web teknolojilerini de kapsayacak şekilde genişletmeye karar verdik. Bu teknolojiler arasında Android için Chrome'daki WebGL de vardı. Bu teknoloji, doğal olarak Chrome ile Geliştirme'nin mobil bir deneyime dönüşmesine olanak tanıyacaktı. Başlamak için ilk olarak, mobil uygulamaya kıyasla tarayıcıda karşılaşabileceğimiz hareket davranışını ve dokunma duyarlılığını anlamak amacıyla "Oluşturucu Aracı"nın donanımını sorgulamadan önce dokunma prototipleri geliştirdik.
Duyarlı kullanıcı arayüzü
Hem dokunma hem de fare girişine sahip cihazları desteklememiz gerekiyordu. Ancak küçük dokunmatik ekranlarda aynı kullanıcı arayüzünün kullanılması, alan kısıtlamaları nedeniyle en uygun çözüm değildi.
Yapım aşamasında birçok etkileşim vardır: yakınlaştırma ve uzaklaştırma, tuğla renklerini değiştirme ve tabii ki tuğlaları seçme, döndürme ve yerleştirme. Kullanıcıların genellikle çok fazla zaman geçirdiği bir araç olduğundan, sık kullandıkları her şeye hızlıca erişebilmeleri ve bu araçla etkileşimde rahat hissetmeleri önemlidir.
Son derece etkileşimli bir dokunmatik uygulama tasarlarken ekranın kısa sürede küçük hissettirdiğini ve kullanıcının parmaklarının etkileşim sırasında ekranın büyük bir kısmını kapladığını fark edersiniz. Bu durum, Builder ile çalışırken bizim için açıkça ortaya çıktı. Tasarım yaparken grafiklerdeki piksellerden ziyade fiziksel ekran boyutunu göz önünde bulundurmanız gerekir. Gerçek içeriğe mümkün olduğunca fazla ekran alanı ayırmak için düğme ve kontrol sayısını en aza indirmek önemlidir.
Amacımız, Build'i dokunmatik cihazlarda doğal hissettirmek ve yalnızca orijinal masaüstü uygulamasına dokunmatik giriş eklemekle kalmayıp gerçekten dokunmatik cihazlar için tasarlanmış bir deneyim sunmaktı. Kullanıcı arayüzünün iki varyantını oluşturduk: biri büyük ekranlı masaüstü bilgisayarlar ve tabletler için, diğeri ise daha küçük ekranlı mobil cihazlar için. Mümkün olduğunda tek bir uygulama kullanmak ve modlar arasında sorunsuz bir geçiş sağlamak en iyisidir. Bizim durumumuzda, bu iki mod arasında deneyim açısından o kadar önemli bir fark olduğunu belirledik ki belirli bir kesme noktasına karar verdik. İki sürümün birçok ortak özelliği var ve çoğu şeyi tek bir kod uygulamasıyla yapmaya çalıştık. Ancak kullanıcı arayüzünün bazı özellikleri iki sürümde farklı şekilde çalışır.
Mobil cihazları algılamak için kullanıcı aracısı verilerini kullanırız ve ardından küçük ekran mobil kullanıcı arayüzünün kullanılıp kullanılmayacağına karar vermek için görüntü alanı boyutunu kontrol ederiz. Fiziksel ekran boyutu için güvenilir bir değer elde etmek zor olduğundan "büyük ekran" için bir kesme noktası belirlemek biraz zordur. Neyse ki bizim durumumuzda küçük ekran kullanıcı arayüzünü büyük ekranlı bir dokunmatik cihazda göstermemiz önemli değil. Çünkü araç yine de düzgün çalışır. Yalnızca bazı düğmeler biraz fazla büyük görünebilir. Son olarak, kesme noktasını 1.000 piksele ayarladık. Siteyi 1.000 pikselden geniş bir pencereden (yatay modda) yüklerseniz büyük ekran sürümünü görürsünüz.
İki ekran boyutu ve deneyimi hakkında biraz konuşalım:
Fare ve dokunma desteğine sahip büyük ekran
Büyük ekran sürümü, fare desteği olan tüm masaüstü bilgisayarlara ve büyük ekranlı dokunmatik cihazlara (Google Nexus 10 gibi) sunulur. Bu sürüm, sunulan gezinme denetimleri açısından orijinal masaüstü çözümüne benzer ancak dokunma desteği ve bazı hareketler eklenmiştir. Kullanıcı arayüzünü pencere boyutuna göre ayarlarız. Bu nedenle, kullanıcı pencereyi yeniden boyutlandırdığında kullanıcı arayüzünün bir kısmı kaldırılabilir veya yeniden boyutlandırılabilir. Bunu CSS medya sorguları kullanarak yaparız.
Örnek: Kullanılabilir yükseklik 730 pikselden azsa Keşfet modundaki yakınlaştırma kaydırma çubuğu denetimi gizlenir:
@media only screen and (max-height: 730px) {
.zoom-slider {
display: none;
}
}
Küçük ekran, yalnızca dokunma desteği
Bu sürüm, mobil cihazlara ve küçük tabletlere (hedef cihazlar Nexus 4 ve Nexus 7) yayınlanır. Bu sürüm için çoklu dokunma desteği gerekir.
Küçük ekranlı cihazlarda içeriğe mümkün olduğunca fazla ekran alanı vermemiz gerekiyor. Bu nedenle, çoğunlukla sık kullanılmayan öğeleri görünmeyen bir yere taşıyarak alanı en üst düzeye çıkarmak için birkaç küçük ayar yaptık:
- Yapı tuğlası seçici, yapı oluştururken renk seçici olarak küçültülür.
- Yakınlaştırma ve yön kontrollerini çoklu dokunma hareketleriyle değiştirdik.
- Chrome'un tam ekran işlevi, daha fazla ekran alanı elde etmek için de yararlıdır.
WebGL Performansı ve Desteği
Modern dokunmatik cihazlar oldukça güçlü GPU'lara sahip olsa da masaüstü cihazlara kıyasla performans açısından hala geride. Bu nedenle, özellikle de aynı anda çok sayıda öğeyi oluşturmamız gereken Keşfet 3D modunda performansla ilgili bazı zorluklarla karşılaşacağımızı biliyorduk.
Yaratıcı bir yaklaşımla, karmaşık şekillere ve hatta saydamlığa sahip birkaç yeni tuğla türü eklemek istedik. Bu özellikler genellikle GPU'da çok fazla kaynak kullanır. Ancak geriye dönük uyumluluğu sağlamak ve ilk sürümdeki öğeleri desteklemeye devam etmek zorunda olduğumuz için öğelerdeki toplam tuğla sayısını önemli ölçüde azaltmak gibi yeni kısıtlamalar koyamadık.
Build'in ilk sürümünde, tek bir yapıda kullanılabilecek maksimum tuğla sınırı vardı. Kalan tuğla sayısını gösteren bir "tuğla ölçer" vardı. Yeni uygulamada, yeni tuğlaların bir kısmı tuğla ölçerini standart tuğlalardan daha fazla etkiledi. Bu nedenle, toplam maksimum tuğla sayısı biraz azaltıldı. Bu, iyi bir performansı korurken yeni tuğlalar eklemenin bir yoludur.
3D Keşfet modunda aynı anda birçok işlem gerçekleşir: taban plakası dokularının yüklenmesi, öğelerin yüklenmesi, öğelerin canlandırılması ve oluşturulması vb. Bu işlem hem GPU'dan hem de CPU'dan çok fazla kaynak gerektirdiğinden, bu parçaları mümkün olduğunca optimize etmek için Chrome DevTools'ta çok sayıda kare profili oluşturduk. Mobil cihazlarda, aynı anda çok fazla reklam öğesi oluşturmak zorunda kalmamak için reklam öğelerini biraz daha yakınlaştırmaya karar verdik.
Bazı cihazlar, WebGL gölgelendiricilerinin bir kısmını tekrar ziyaret edip basitleştirmemizi gerektirdi ancak her zaman bu sorunu çözmenin ve ilerlemenin bir yolunu bulduk.
WebGL olmayan cihazları destekleme
Ziyaretçinin cihazı WebGL'yi desteklemese bile sitenin bir şekilde kullanılabilir olmasını istedik. Bazen kanvas çözümü veya CSS3D özellikleri kullanılarak 3D'ün basitleştirilmiş bir şekilde gösterilmesi mümkündür. Maalesef WebGL kullanmadan 3D Oluştur ve Keşfet özelliklerini kopyalayacak yeterince iyi bir çözüm bulamadık.
Tutarlılık için öğelerin görsel stili tüm platformlarda aynı olmalıdır. 2,5D bir çözüm deneyebilirdik ancak bu, içeriklerin bazı açılardan farklı görünmesine neden olurdu. Ayrıca, Chrome ile Oluştur'un ilk sürümüyle oluşturulan öğelerin sitenin yeni sürümünde de ilk sürümdeki gibi görünmesini ve sorunsuz şekilde çalışmasını nasıl sağlayacağımızı da düşünmemiz gerekiyordu.
WebGL olmayan cihazlar, yeni içerikler oluşturamaz veya 3D olarak keşif yapamaz olsa da Keşfet 2D moduna erişmeye devam edebilir. Bu sayede kullanıcılar, WebGL özellikli bir cihaz kullanıyorlarsa projenin derinliği ve bu aracı kullanarak neler oluşturabilecekleri hakkında fikir edinebilir. Site, WebGL desteği olmayan kullanıcılar için o kadar değerli olmayabilir ancak en azından bir tanıtım görevi görerek kullanıcıları denemeye teşvik etmelidir.
WebGL çözümleri için yedek sürümleri tutmak bazen mümkün değildir. Bunun birçok nedeni olabilir: performans, görsel stil, geliştirme ve bakım maliyetleri vb. Ancak yedek çözüm uygulamamaya karar verdiğinizde en azından WebGL etkin olmayan ziyaretçilere dikkat etmeniz, siteye neden tam olarak erişemediklerini açıklamanız ve WebGL'yi destekleyen bir tarayıcı kullanarak sorunu nasıl çözebileceklerine dair talimatlar vermeniz gerekir.
Öğe Yönetimi
Google, 2013 yılında Google Haritalar'ın kullanıma sunulmasından bu yana en önemli kullanıcı arayüzü değişikliklerini içeren yeni bir sürümünü kullanıma sundu. Bu nedenle, Chrome ile Oluştur'u yeni Google Haritalar kullanıcı arayüzüne uyacak şekilde yeniden tasarlamaya karar verdik ve bu süreçte yeniden tasarıma diğer faktörleri de dahil ettik. Yeni tasarım, net tek renkler ve basit şekillerle nispeten düzdür. Bu sayede, kullanıcı arayüzü öğelerinin çoğunda saf CSS kullanarak resim kullanımını en aza indirdik.
Keşfet'e çok sayıda resim yüklememiz gerekiyor: Yapımlar için küçük resimler, taban plakaları için harita dokuları ve son olarak da gerçek 3D yapılar. Sürekli yeni resimler yüklerken bellek sızıntısı olmaması için ekstra özen gösteriyoruz.
3D yapımlar, PNG resmi olarak paketlenmiş özel bir dosya biçiminde depolanır. 3D içerik verilerini resim olarak depolamak, verileri temel olarak doğrudan içerikleri oluşturmaya yarayan gölgelendiricilere iletmemizi sağladı.
Kullanıcı tarafından oluşturulan tüm resimler için tasarım, tüm platformlarda aynı resim boyutlarını kullanmamıza olanak tanıdı. Böylece depolama alanı ve bant genişliği kullanımı en aza indirildi.
Ekran Yönünü Yönetme
Dikey moddan yatay moda veya tam tersi şekilde geçiş yaptığınızda ekran en-boy oranının ne kadar değiştiğini unutmak kolaydır. Mobil cihazlara uyarlarken bunu baştan hesaba katmanız gerekir.
Kaydırma özelliğinin etkin olduğu geleneksel bir web sitesinde, içeriği ve menüleri yeniden düzenleyen duyarlı bir site elde etmek için CSS kuralları uygulayabilirsiniz. Kaydırma işlevini kullanabildiğiniz sürece bu sorunla başa çıkabilirsiniz.
Bu yöntemi Build için de kullandık ancak içeriğin her zaman görünür olması ve bir dizi kontrol ve düğmeye hızlıca erişilebilmesi gerektiği için düzeni çözme konusunda biraz sınırlıydık. Haber siteleri gibi içerik odaklı siteler için akıcı bir düzen çok mantıklı olsa da bizim gibi bir oyun uygulaması için bu oldukça zordu. Hem yatay hem de dikey yönde çalışabilen, içeriğe iyi bir genel bakış sunan ve etkileşimi kolaylaştıran bir düzen bulmak zordu. Sonunda, derlemeyi yalnızca yatay olarak tutmaya karar verdik ve kullanıcıya cihazını döndürmesini söyledik.
Keşfet'in her iki yönde de çözülmesi çok daha kolaydı. Tutarlı bir deneyim elde etmek için 3D'nin yakınlaştırma seviyesini yöne göre ayarlamamız yeterliydi.
İçerik düzeninin çoğu CSS tarafından kontrol edilir ancak yönle ilgili bazı öğelerin JavaScript'te uygulanması gerekiyordu. Yönlendirmeyi belirlemek için window.orientation özelliğini kullanmak üzere cihazlar arası iyi bir çözüm olmadığını tespit ettik. Bu nedenle, cihazın yönünü belirlemek için yalnızca window.innerWidth ve window.innerHeight özelliklerini karşılaştırıyorduk.
if( window.innerWidth > window.innerHeight ){
//landscape
} else {
//portrait
}
Dokunma desteği ekleme
Web içeriğine dokunma desteği eklemek oldukça basittir. Tıklama etkinliği gibi temel etkileşimler, masaüstü ve dokunmatik cihazlarda aynı şekilde çalışır. Ancak daha gelişmiş etkileşimler söz konusu olduğunda touchstart, touchmove ve touchend dokunma etkinliklerini de ele almanız gerekir. Bu makalede, bu etkinliklerin nasıl kullanılacağıyla ilgili temel bilgiler verilmiştir. Internet Explorer, dokunma etkinliklerini desteklemez. Bunun yerine İşaretçi Etkinlikleri'ni (pointerdown, pointermove, pointerup) kullanır. İşaretçi etkinlikleri standartlaştırma için W3C'ye gönderildi ancak şu anda yalnızca Internet Explorer'da uygulanıyor.
Keşfet 3D modunda, standart Google Haritalar uygulamasıyla aynı gezinme deneyimini sunmak istedik. Bu deneyimde, haritayı kaydırmak için bir parmak, yakınlaştırmak için iki parmak kullanılır. Oluşturmalar 3D olduğundan iki parmakla döndürme hareketini de ekledik. Bu genellikle dokunma etkinliklerinin kullanılmasını gerektirir.
Etkinlik işleyicilerinde 3D'yi güncelleme veya oluşturma gibi yoğun bilgi işlem işlemlerinden kaçınmak iyi bir uygulamadır. Bunun yerine, dokunma girişini bir değişkende saklayın ve requestAnimationFrame oluşturma döngüsünde girişe tepki verin. Bu, aynı anda fare uygulamasını da kolaylaştırır. İlgili fare değerlerini aynı değişkenlerde depolarsınız.
Girişi saklayacak bir nesne başlatarak ve touchstart etkinlik işleyicisini ekleyerek başlayın. Her etkinlik işleyicisinde event.preventDefault() çağrısını yaparız. Bu, tarayıcının dokunma etkinliğini işlemeye devam etmesini engellemek içindir. Bu işlem, sayfanın tamamını kaydırma veya ölçeklendirme gibi bazı beklenmedik davranışlara neden olabilir.
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);
}
}
Girişlerin gerçek depolama işlemini olay işleyicilerde değil, ayrı işleyicilerde (handleDragStart, handleDragging ve handleDragStop) yapıyoruz. Bunun nedeni, bunları fare etkinlik işleyicilerinden de çağırabilmek istememizdir. Kullanıcının dokunmatik ekranı ve fareyi aynı anda kullanabileceğini unutmayın. Bu destek kaydını doğrudan ele almak yerine, herhangi bir sorun yaşanmadığından emin oluruz.
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;
}
}
Dokunma hareketine dayalı animasyonlar yaparken genellikle son etkinlikten sonraki delta hareketini de depolamak yararlıdır. Örneğin, Keşfet'te tüm taban plakaları arasında hareket ederken kameranın hızı için bir parametre olarak bunu kullandık. Çünkü taban plakalarını değil, kamerayı hareket ettiriyorsunuz.
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;
}
Yerleşik örnek: Dokunma etkinliklerini kullanarak bir nesneyi sürükleme. Build with Chrome'da 3D Keşfet haritasını sürüklemekle benzer bir uygulama: http://cdpn.io/qDxvo
Çoklu Dokunma Hareketleri
Hammer veya QuoJS gibi çeşitli çerçeveler ya da kitaplıklar, çoklu dokunma hareketlerinin yönetimini basitleştirebilir. Ancak birden fazla hareketi birleştirmek ve tam kontrol sahibi olmak istiyorsanız bazen sıfırdan başlamak en iyi seçenektir.
İki parmağı yakınlaştırma ve döndürme hareketlerini yönetmek için ikinci parmak ekrana yerleştirildiğinde iki parmak arasındaki mesafeyi ve açıyı depolarız:
//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;
}
Ardından, dokunma hareketi etkinliğinde bu iki parmak arasındaki mesafeyi ve açıyı sürekli olarak ölçeriz. Ardından, başlangıç mesafesi ile mevcut mesafe arasındaki fark ölçeği ayarlamak için, başlangıç açısı ile mevcut açı arasındaki fark ise açıyı ayarlamak için kullanılır.
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;
}
}
Her bir touchmove etkinliği arasındaki mesafe değişikliğini, sürükleme örneğine benzer şekilde kullanabilirsiniz ancak bu yaklaşım genellikle sürekli bir hareket istediğinizde daha kullanışlıdır.
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;
}
İsterseniz yakınlaştırma ve döndürme hareketlerini yaparken nesnenin sürüklenmesini de etkinleştirebilirsiniz. Bu durumda, sürükleme işleyicisinin girişi olarak iki parmak arasındaki orta noktayı kullanırsınız.
Yerleştirilmiş örnek: Bir nesneyi 2D olarak döndürme ve ölçeklendirme. Keşfet'teki haritanın uygulanmasına benzer: http://cdpn.io/izloq
Aynı Donanımda Fare ve Dokunma Desteği
Günümüzde Chromebook Pixel gibi hem fare hem de dokunma girişini destekleyen çeşitli dizüstü bilgisayarlar mevcuttur. Dikkatli olmazsanız bu durum bazı beklenmedik davranışlara neden olabilir.
Önemli bir nokta, dokunma desteğini algılayıp fare girişini yok saymak yerine her ikisini de aynı anda desteklemeniz gerektiğidir.
Dokunma etkinliği işleyicilerinizde event.preventDefault()
kullanmıyorsanız dokunma optimizasyonu yapılmamış çoğu sitenin çalışmaya devam etmesi için bazı taklit fare etkinlikleri de tetiklenir. Örneğin, ekrana tek bir dokunma için aşağıdaki etkinlikler hızlı bir şekilde ve şu sırayla tetiklenebilir:
- touchstart
- touchmove
- touchend
- fareyle üzerine gelme
- mousemove
- mousedown
- mouseup
- click
Biraz daha karmaşık etkileşimleriniz varsa bu fare etkinlikleri bazı beklenmedik davranışlara neden olabilir ve uygulamanızı bozabilir. Dokunma etkinliği işleyicilerinde genellikle event.preventDefault()
kullanmak ve fare girişini ayrı etkinlik işleyicilerinde yönetmek en iyisidir. Dokunma etkinliği işleyicilerinde event.preventDefault()
kullanılmasının, kaydırma ve tıklama etkinliği gibi bazı varsayılan davranışları da engelleyeceğini unutmayın.
"Build with Chrome'da, çoğu tarayıcıda standart olsa da kullanıcı siteye iki kez dokunduğunda yakınlaştırma işleminin yapılmasını istemedik. Bu nedenle, kullanıcı çift dokunuş yaptığında tarayıcıya yakınlaştırma yapmamasını söylemek için görüntü alanı meta etiketini kullanırız. Bu işlem, sitenin duyarlılığını artıran 300 ms tıklama gecikmesini de ortadan kaldırır. (Tıklama gecikmesi, iki kez dokunarak yakınlaştırma özelliği etkinleştirildiğinde tek dokunuş ile iki dokunuş arasında ayrım yapmak için kullanılır.)
<meta name="viewport" content="width=device-width,user-scalable=no">
Bu özelliği kullanırken kullanıcının yakınlaştıramayacağı için siteyi tüm ekran boyutlarında okunabilir hale getirmenin size ait olduğunu unutmayın.
Fare, Dokunma ve Klavye Giriş
3D keşif modunda haritada gezinmek için üç yöntem olmasını istedik: fare (sürükleme), dokunma (sürükleme, yakınlaştırmak ve döndürmek için parmak ucunu yakınlaştırma/uzaklaştırma) ve klavye (ok tuşlarıyla gezinme). Bu gezinme yöntemlerinin tümü biraz farklı çalışır ancak hepsinde aynı yaklaşımı kullandık: Değişkenleri etkinlik işleyicilerinde ayarlama ve requestAnimationFrame döngüsünde bu değişkenleri kullanma. requestAnimationFrame döngüsünün, gezinmek için hangi yöntemin kullanıldığını bilmesi gerekmez.
Örneğin, haritanın hareketini (dragDX ve dragDY) üç giriş yönteminin tamamıyla ayarlayabiliriz. Klavye uygulaması aşağıda verilmiştir:
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;
}
Yerleşik örnek: Gezinmek için fare, dokunma ve klavye kullanma: http://cdpn.io/catlf
Özet
Build with Chrome'u birçok farklı ekran boyutuna sahip dokunmatik cihazları desteklemek için uyarlamak, öğrenme deneyimi oldu. Ekip, dokunmatik cihazlarda bu düzeyde etkileşim sağlama konusunda çok fazla deneyime sahip değildi ve bu süreçte çok şey öğrendik.
En büyük zorluk, kullanıcı deneyimi ve tasarımı nasıl çözeceğimizdi. Teknik zorluklar arasında birçok ekran boyutunu, dokunma etkinliklerini ve performans sorunlarını yönetmek vardı.
Dokunmatik cihazlardaki WebGL gölgelendiricileriyle ilgili bazı zorluklar olsa da bu, beklenenden daha iyi çalıştı. Cihazlar giderek daha güçlü hale geliyor ve WebGL uygulamaları hızla gelişiyor. WebGL'yi yakın gelecekte cihazlarda çok daha fazla kullanacağımızı düşünüyoruz.
Henüz yapmadıysanız harika bir şey oluşturun.