Örnek Olay - Google I/O 2013 Denemesi

oynadığı filmler
Thomas Reynolds

Giriş

Konferans kaydı başlamadan önce geliştiricilerin Google I/O 2013 web sitesine ilgisini çekmek için, dokunma etkileşimleri, üretken ses ve keşif sevincine odaklanan, mobil cihazlara öncelik veren bir dizi deneme ve oyun geliştirdik. Kod yazmanın potansiyelinden ve oynamanın gücünden esinlenen bu etkileşimli deneyim, yeni I/O logosuna dokunduğunuzda basit "I" ve "O" sesleriyle başlıyor.

Organik Hareket

G ve O animasyonlarını, HTML5 etkileşimlerinde sık görülmeyen sallantılı, organik bir efekt halinde uygulamaya karar verdik. Eğlenceli ve tepkisel bir his verecek seçenekleri aramak biraz zaman aldı.

Bouncy Fizik Kodu Örneği

Bu efekti başarmak için, iki şeklin kenarlarını temsil eden bir dizi nokta üzerinde basit bir fizik simülasyonu kullandık. İki şekilden birine dokunulduğunda, tüm noktalar, dokunulacağı yerden itibaren hızlandırılır. Geri çekilmeden önce uzanır.

Örneklemede, her nokta rastgele bir ivme miktarı ve "geri sıçrama" değeri alır. Böylece, aşağıdaki kodda görebileceğiniz gibi, aynı şekilde hareket etmezler:

this.paperO_['vectors'] = [];

// Add an array of vector points and properties to the object.
for (var i = 0; i < this.paperO_['segments'].length; i++) {
  var point = this.paperO_['segments'][i]['point']['clone']();
  point = point['subtract'](this.oCenter);

  point['velocity'] = 0;
  point['acceleration'] = Math.random() * 5 + 10;
  point['bounce'] = Math.random() * 0.1 + 1.05;

  this.paperO_['vectors'].push(point);
}

Daha sonra, bunlar dokunulduğunda buradaki kod kullanılarak dokunma konumundan dışarı doğru hızlandırılır:

for (var i = 0; i < path['vectors'].length; i++) {
  var point = path['vectors'][i];
  var vector;
  var distance;

  if (path === this.paperO_) {
    vector = point['add'](this.oCenter);
    vector = vector['subtract'](clickPoint);
    distance = Math.max(0, this.oRad - vector['length']);
  } else {
    vector = point['add'](this.iCenter);
    vector = vector['subtract'](clickPoint);
    distance = Math.max(0, this.iWidth - vector['length']);
  }

  point['length'] += Math.max(distance, 20);
  point['velocity'] += speed;
}

Son olarak, her parçacık her karede yavaşlar ve yavaş yavaş dengeye şu kod yaklaşımıyla geri döner:

for (var i = 0; i < path['segments'].length; i++) {
  var point = path['vectors'][i];
  var tempPoint = new paper['Point'](this.iX, this.iY);

  if (path === this.paperO_) {
    point['velocity'] = ((this.oRad - point['length']) /
      point['acceleration'] + point['velocity']) / point['bounce'];
  } else {
    point['velocity'] = ((tempPoint['getDistance'](this.iCenter) -
      point['length']) / point['acceleration'] + point['velocity']) /
      point['bounce'];
  }

  point['length'] = Math.max(0, point['length'] + point['velocity']);
}

Organik Hareket Demosu

Oynamanız için I/O ana sayfa modunu burada bulabilirsiniz. Bu uygulamada bir dizi ek seçeneği de kullanıma sunduk. "Puanları göster" özelliğini etkinleştirirseniz fizik simülasyonunun ve kuvvetlerin etki ettiği noktaları tek tek görürsünüz.

Yeniden ciltleme

Ev modu hareketinden memnun kaldığımızda, aynı efekti iki retro mod için kullanmak istiyorduk: Eightbit ve Ascii.

Yeniden görünüm oluşturmak için, ana sayfa modundaki aynı tuvali kullandık ve iki efektin her birini oluşturmak için piksel verilerini kullandık. Bu yaklaşım, sahnenin her bir pikselinin incelendiği ve değiştirildiği bir OpenGL parçası gölgelendiricisini andırır. Bu konuya biraz daha yakından bakalım.

Tuval "Gölgelendirici" Kod Örneği

Tuval üzerindeki pikseller getImageData yöntemi kullanılarak okunabilir. Döndürülen dizi, her piksel RGBA değerini temsil eden piksel başına 4 değer içerir. Bu pikseller dizi benzeri devasa bir yapı içinde birbirine dizilmiştir. Örneğin, 2x2 boyutundaki bir kanvasın imageData dizisinde 4 piksel ve 16 giriş olacaktır.

Tuvalimiz tam ekran olduğundan, ekranın 1024x768 olduğunu varsayarsak (iPad'de olduğu gibi) dizide 3.145.728 giriş olur. Bu bir animasyon olduğu için dizinin tamamı saniyede 60 kez güncellenir. Modern JavaScript motorları, kare hızını tutarlı tutmak için bu kadar çok verideki döngüleri ve işlemleri hızla işleyebilir. (İpucu: Bu verileri geliştirici konsoluna kaydetmeyi denemeyin, aksi takdirde tarayıcınızı yavaşlatabilir veya tamamen kilitleyebilirsiniz.)

Sekiz Bit modumuzun, ev modu tuvalini nasıl okuduğunu ve bloke edici bir etki yaratmak için pikselleri nasıl üflediğini burada görebilirsiniz:

var pixelData = pctx.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height);

// tctx is the Target Context for the output Canvas element
tctx.clearRect(0, 0, targetCanvas.width + 1, targetCanvas.height + 1);

var size = ~~(this.width_ * 0.0625);

if (this.height_ * 6 < this.width_) {
 size /= 8;
}

var increment = Math.min(Math.round(size * 80) / 4, 980);

for (i = 0; i < pixelData.data.length; i += increment) {
  if (pixelData.data[i + 3] !== 0) {
    var r = pixelData.data[i];
    var g = pixelData.data[i + 1];
    var b = pixelData.data[i + 2];
    var pixel = Math.ceil(i / 4);
    var x = pixel % this.width_;
    var y = Math.floor(pixel / this.width_);

    var color = 'rgba(' + r + ', ' + g + ', ' + b + ', 1)';

    tctx.fillStyle = color;

    /**
     * The ~~ operator is a micro-optimization to round a number down
     * without using Math.floor. Math.floor has to look up the prototype
     * tree on every invocation, but ~~ is a direct bitwise operation.
     */
    tctx.fillRect(x - ~~(size / 2), y - ~~(size / 2), size, size);
  }
}

Sekiz Bit Gölgelendirici Demosu

Aşağıda, Sekiz Bit yer paylaşımını kaldırır ve alttaki orijinal animasyonu görürüz. "Ekranı sonlandır" seçeneği, kaynak piksellerin yanlış örneklenmesiyle karşılaştığımız tuhaf bir efekti gösterir. Sekiz Bit modu, beklenmedik en boy oranlarına göre yeniden boyutlandırıldığında, bunu "duyarlı" bir paskalya yumurtası olarak kullandık. Kolay gelsin!

Tuval Birleştirme

Birden fazla oluşturma adımını ve maskeyi birleştirerek yapabilecekleriniz oldukça etkileyicidir. Her topun kendi dairesel gradyanının olmasını ve bu gradyanların topların çakıştığı yerde karıştırılmasını gerektiren bir 2D metatop oluşturduk. (Bunu aşağıdaki demoda görebilirsiniz.)

Bunun için iki ayrı tuval kullandık. İlk tuval, metatop şeklini hesaplar ve çizer. İkinci tuval ise her top konumunda dairesel renk geçişleri çiziyor. Daha sonra, şekil gradyanları maskeler ve nihai sonucu oluştururuz.

Birleştirme Kodu Örneği

Her şeyi sağlayan kod şudur:

// Loop through every ball and draw it and its gradient.
for (var i = 0; i < this.ballCount_; i++) {
  var target = this.world_.particles[i];

  // Set the size of the ball radial gradients.
  this.gradSize_ = target.radius * 4;

  this.gctx_.translate(target.pos.x - this.gradSize_,
    target.pos.y - this.gradSize_);

  var radGrad = this.gctx_.createRadialGradient(this.gradSize_,
    this.gradSize_, 0, this.gradSize_, this.gradSize_, this.gradSize_);

  radGrad.addColorStop(0, target['color'] + '1)');
  radGrad.addColorStop(1, target['color'] + '0)');

  this.gctx_.fillStyle = radGrad;
  this.gctx_.fillRect(0, 0, this.gradSize_ * 4, this.gradSize_ * 4);
};

Ardından, kanvası maskeleme ve çizim için ayarlayın:

// Make the ball canvas the source of the mask.
this.pctx_.globalCompositeOperation = 'source-atop';

// Draw the ball canvas onto the gradient canvas to complete the mask.
this.pctx_.drawImage(this.gcanvas_, 0, 0);
this.ctx_.drawImage(this.paperCanvas_, 0, 0);

Sonuç

Kullandığımız tekniklerin çeşitliliği ve uyguladığımız teknolojiler (Canvas, SVG, CSS Animasyonu, JS Animasyonu, Web Ses vb.) projeyi geliştirmeyi son derece eğlenceli hale getirdi.

Hatta burada gördüklerinizden çok daha keşfedilecek şeyler var. I/O logosuna dokunmaya devam ederseniz doğru reklam dizilimilerle daha çok mini deneme, oyun, sıra dışı görsel ve belki de bazı kahvaltılık yiyeceklerin kilidini açabilirsiniz. En iyi deneyimi yaşamak için akıllı telefonunuzda veya tabletinizde denemenizi öneririz.

Başlamanıza yardımcı olacak bir kombinasyon şöyle: Hemen deneyin: google.com/io

Açık Kaynak

Kod Apache 2.0 lisansımızı açık kaynaklı hale getirdik. GitHub'umuzda http://github.com/Instrument/google-io-2013 adresindeki bulabilirsiniz.

Kredi

Geliştiriciler:

  • oynadığı filmler
  • Burak Halıcı
  • Stefanie Kuluçka Makinesi
  • Peker Ayhan

Tasarımcılar:

  • Dan Schechter
  • Adaçayı Kahverengisi
  • daha fazla içerik

Yapımcılar:

  • Amie Pascal
  • Burçin Bilgili