Excalidraw ve Fugu: Temel Kullanıcı Yolculuklarını İyileştirme

Yeterince ileri düzeyde olan hiçbir teknoloji sihirden ayırt edilemez. Bunu anlamadıysanız. Adım Thomas Steiner. Google'da Geliştirici İlişkileri bölümünde çalışıyorum. Google I/O konuşmamla ilgili bu yazıda, yeni Fugu API'lerinden bazılarına ve Excalidraw PWA'daki temel kullanıcı yolculuklarını nasıl iyileştirdiklerine değineceğim. Böylece, bu fikirlerden ilham alıp kendi uygulamalarınıza uygulayabilirsiniz.

Excalidraw'a nasıl geldim?

Hikayeyle başlamak istiyorum. 1 Ocak 2020'de Christopher Chedeau, Facebook'ta yazılım mühendisi. Küçük bir çizim uygulaması hakkında tweet attı. bir araya geldi. Bu araçla, kutular ve oklar çizmek için çizgi film el çizimi. Ertesi gün aynı zamanda elipsler ve metin çizmenin yanı sıra nesneleri seçip hareket ettirebilirsiniz. etraflıca düşünebiliriz. 3 Ocak'ta uygulama Excalidraw'a adını verdi. Her olumlu yönden alan adını satın almak, Christopher'ın ilk eylemlerinden biriydi. Ölçüt Artık renkleri kullanabilir ve çizimin tamamını PNG olarak dışa aktarabilirsiniz.

Excalidraw prototip uygulamasının dikdörtgen, ok, elips ve metni desteklediğini gösteren ekran görüntüsü.

15 Ocak'ta Christopher, blog yayını benimki de dahil olmak üzere Twitter'da çok ilgi gördüm. Yayın, bazı etkileyici istatistiklerle başladı:

  • 12 bin tekil etkin kullanıcı
  • GitHub'da 1,5 B yıldız
  • Katkıda bulunan 26 kullanıcı

Sadece iki hafta önce başlatılan bir proje için bu hiç de kötü bir şey değil. Ama aslında işinize yarayacak ilgimin daha da arttığını fark ettim. Christopher, bu oyunda yeni bir şey denediğini yazdı. zaman: Çekme isteği alan herkese koşulsuz taahhüt erişimi verme. Aynı gün blog yayınını okuduğumda bir çekme isteği aldım Excalidraw'a File System Access API desteği ekledi. Bir kullanıcının gönderdiği özellik isteği.

PR'mi duyurduğum tweet'in ekran görüntüsü.

Push isteğim bir gün sonra birleştirildi ve daha sonra tam kaydetme erişimim oldu. Şu sözlere gerek yok, Gücümü kötüye kullanmadım. Şu ana kadar katkıda bulunan 149 kullanıcı arasından başka bir kullanıcı yoktu.

Günümüzde Excalidraw, uygulama ve ekran görüntüsü alma işlemlerini içeren çevrimdışı desteği, çarpıcı bir koyu mod ve evet, Chrome Tarayıcı File System Access API.

Bugünkü durumdaki Excalidraw PWA'nın ekran görüntüsü.

Neden bu kadar zamanını Excalidraw'a ayırdığıyla ilgili Lipis

"Excalidraw'a nasıl geldiğim"in sonuna geldik ama diğer örneklere geçmeden önce Excalidraw'ın muhteşem özellikleri. Panayiotis'i tanıtmaktan memnuniyet duyuyorum. Panayiotis Lipiridis, üzerinde lipis olarak bilinen internet, dünya çapında Excalidraw. Lipi'lere, vaktinin çoğunu Excalidraw'a ayırmaya neyin motive ettiğini sordum:

Tıpkı Christopher'ın tweet'inden bu proje hakkında öğrendiğim herkes gibi. İlk katkım Open Color kitaplığı eklemekti. Şu anda bugün Excalidraw'ın bir parçası. Proje büyüdükçe ve çok sayıda talep aldıkça, bir sonraki büyük kullanıcıların paylaşabilmesi için çizimlerin depolanacağı bir arka uç oluşturmaktı. Ama ne Excalidraw'ı deneyen her kişi, her şeyden önce bir şeyler bulmak için tekrarlamanız gerekebilir.

Lipi'lere tamamen katılıyorum. Excalidraw'ı deneyen her kişi, bu programı tekrar kullanmak için bahane bulmaya çalışıyor.

Excalidraw uygulama şekli

Şimdi size Excalidraw'ı pratikte nasıl kullanabileceğinizi göstermek istiyorum. İyi bir sanatçı değilim ama Google I/O logosu yeterince basit; deneyeyim. Kutu "i"dir, bir çizgi eğik çizgi ve "o" bir daire. Mükemmel bir daire çizebilmek için üst karakter tuşunu basılı tutuyorum. Hareket etmeme izin ver daha iyi görünür. Şimdi "i" için biraz renk ve "o" harfini ekleyin. Mavi iyidir. Belki farklı bir dolgu stili mi olmalı? Tümü sabit mi, yoksa çapraz bağlantılı mı? Yok, hachure harika görünüyor. Mükemmel olmasa da Excalidraw'ın ana fikri bu, o yüzden kaydedeyim.

Kaydet simgesini tıklıyorum ve dosya kaydetme iletişim kutusuna bir dosya adı giriyorum. Chrome'da, File System Access API'yi destekliyor. Bu bir indirme değil, dosyanın konumunu ve adını seçeceğim. Düzenleme yaparsam, dosyayı nereye anlamına gelir.

Logoyu değiştirip "i" harfini yapmak istiyorum. kırmızı. Şimdi tekrar kaydet düğmesini tıklarsam değişikliğim aynı dosyayı yükleyin. Kanıt olarak, tuvali temizleyip dosyayı yeniden açayım. Gördüğünüz gibi değişiklik yapılmış kırmızı-mavi logo yine görünür.

Dosyalarla çalışma

Şu anda File System Access API'yi desteklemeyen tarayıcılarda her kaydetme işlemi bir indiriyorum. Bu nedenle, değişiklik yaptığımda İndirilenler klasörümü dolduran bir dosya adı oluşturdum. Ancak, bu dezavantaja rağmen dosyayı kaydedebilirim.

Dosya açma

Peki sırrı nedir? Farklı tarayıcılarda açma ve kaydetme özelliği farklı tarayıcılarda nasıl çalışır? File System Access API'yi destekliyor mu? Excalidraw'da bir dosya açmak, loadFromJSON)() içeren bir boyuttur. Bu da fileOpen() adlı bir işlev çağırır.

export const loadFromJSON = async (localAppState: AppState) => {
  const blob = await fileOpen({
    description: 'Excalidraw files',
    extensions: ['.json', '.excalidraw', '.png', '.svg'],
    mimeTypes: ['application/json', 'image/png', 'image/svg+xml'],
  });
  return loadFromBlob(blob, localAppState);
};

Yazdığım küçük bir kitaplıktan gelen fileOpen() işlevi. browser-fs-access Excalidraw. Bu kitaplık, Eski bir yedeği olan File System Access API emin olun.

Öncelikle size API'nin desteklendiği durumlardaki uygulamayı göstereyim. Bu çerçevenin MIME türlerini ve dosya uzantılarını içeriyorsa, merkezi parça, File System Access API'nin showOpenFilePicker() işlevi. Bu işlev, bağımsız değişkene bağlı olarak bir dizi dosya veya tek bir dosya döndürür. seçim yapmanıza yardımcı olur. Bundan sonra tek yapmanız gereken, dosyanın herkese açık kullanıcı adını nesnesinin bir kopyasını oluşturun.

export default async (options = {}) => {
  const accept = {};
  // Not shown: deal with extensions and MIME types.
  const handleOrHandles = await window.showOpenFilePicker({
    types: [
      {
        description: options.description || '',
        accept: accept,
      },
    ],
    multiple: options.multiple || false,
  });
  const files = await Promise.all(handleOrHandles.map(getFileWithHandle));
  if (options.multiple) return files;
  return files[0];
  const getFileWithHandle = async (handle) => {
    const file = await handle.getFile();
    file.handle = handle;
    return file;
  };
};

Yedek uygulama, "file" türünde bir input öğesini kullanır. Projenin gidişatına dair kabul edilecek MIME türlerini ve uzantılarını kullanıyorsanız, bir sonraki adım öğesini seçmeniz gerekir. Değişiklik durumunda, yani kullanıcı bir veya daha fazla dosya eklerseniz vadetilmiş olur.

export default async (options = {}) => {
  return new Promise((resolve) => {
    const input = document.createElement('input');
    input.type = 'file';
    const accept = [
      ...(options.mimeTypes ? options.mimeTypes : []),
      options.extensions ? options.extensions : [],
    ].join();
    input.multiple = options.multiple || false;
    input.accept = accept || '*/*';
    input.addEventListener('change', () => {
      resolve(input.multiple ? Array.from(input.files) : input.files[0]);
    });
    input.click();
  });
};

Dosyalar kaydediliyor

Şimdi kaydedilmeye geçelim. Excalidraw'da kaydetme işlemi, saveAsJSON() adlı bir işlevde gerçekleşir. İlk olarak Excalidraw öğe dizisini JSON'a serileştirir, JSON'u bir blob'a dönüştürür ve ardından bir fileSave() adlı işleve göz atın. Bu işlev de aynı şekilde browser-fs-access kitaplığına erişim sağlar.

export const saveAsJSON = async (
  elements: readonly ExcalidrawElement[],
  appState: AppState,
) => {
  const serialized = serializeAsJSON(elements, appState);
  const blob = new Blob([serialized], {
    type: 'application/vnd.excalidraw+json',
  });
  const fileHandle = await fileSave(
    blob,
    {
      fileName: appState.name,
      description: 'Excalidraw file',
      extensions: ['.excalidraw'],
    },
    appState.fileHandle,
  );
  return { fileHandle };
};

İlk olarak, File System Access API desteği sunan tarayıcılardaki uygulamaya bakayım. İlgili içeriği oluşturmak için kullanılan ilk birkaç satırda biraz sorun var gibi görünse de, tüm bunların MIME türlerini ve dosyasını belirlemekten uzantılar. Önceden kaydettiğim bir dosya herkese açık kullanıcı adına sahipse kaydetme iletişim kutusunun gösteriliyor. Ancak bu ilk kayıtsa bir dosya iletişim kutusu gösterilir ve uygulamaya bir dosya adı verilir ileride kullanılmak üzere geri gönderebilirsiniz. Geri kalan her şey, dosyaya yazmak için kullanılır ve bu işlem yazabilir akış.

export default async (blob, options = {}, handle = null) => {
  options.fileName = options.fileName || 'Untitled';
  const accept = {};
  // Not shown: deal with extensions and MIME types.
  handle =
    handle ||
    (await window.showSaveFilePicker({
      suggestedName: options.fileName,
      types: [
        {
          description: options.description || '',
          accept: accept,
        },
      ],
    }));
  const writable = await handle.createWritable();
  await writable.write(blob);
  await writable.close();
  return handle;
};

"Farklı kaydet" detay

Mevcut bir dosya herkese açık kullanıcı adını yoksaymaya karar verirsem "farklı kaydet" oluşturma özelliğini yeni bir dosya oluşturabilirsiniz. Bunu göstermek için mevcut bir dosyayı açıp ve ardından mevcut dosyanın üzerine yazmamak, ancak farklı kaydet işlevini kullanarak yeni bir dosya özelliğini kullanabilirsiniz. Bu işlem, orijinal dosyayı olduğu gibi bırakır.

File System Access API'yi desteklemeyen tarayıcılar için uygulama süreci kısadır, çünkü değeri, istenen dosya adı olan download özelliğine sahip bir bağlantı öğesi oluşturmak ve bir blob URL'sini href özellik değeri olarak belirleyin.

export default async (blob, options = {}) => {
  const a = document.createElement('a');
  a.download = options.fileName || 'Untitled';
  a.href = URL.createObjectURL(blob);
  a.addEventListener('click', () => {
    setTimeout(() => URL.revokeObjectURL(a.href), 30 * 1000);
  });
  a.click();
};

Ardından, sabit öğe programatik olarak tıklanır. Bellek sızıntılarını önlemek için blob URL'sinin iptal edilir. Bu sadece bir indirme işlemi olduğundan, hiçbir dosya kaydetme iletişim kutusu gösterilmez ve dosyaları varsayılan Downloads klasörüne yerleştirilir.

Sürükle ve bırak

Masaüstünde en sevdiğim sistem entegrasyonlarından biri sürükle ve bırak işlevi. Excalidraw'da, bir öğeyi .excalidraw dosyasını uygulamaya eklerim, hemen açılır ve düzenlemeye başlayabilirim. Tarayıcılarda daha sonra değişikliklerimi anında kaydedebilirim. Gitmenize gerek yok gerekli dosya tutma yeri, sürükle ve bırak aracından elde edildiği için bir dosya kaydetme iletişim kutusuyla işlemidir.

Bunu sağlamanın sırrı, getAsFileSystemHandle() numaralı telefonu File System Access API desteklendiğinde veri aktarımı öğesi. Ardından bunu iletiyorum yukarıdaki birkaç paragraftan hatırlayabileceğiniz gibi, dosya herkese açık kullanıcı adını loadFromBlob() olarak ayarlayın. Çok fazla çok fazla şey yapabilirsiniz: açma, kaydetme, fazla kaydetme, sürükleme, bırakma. Meslektaşım Pete Tüm bu püf noktalarını ve daha fazlasını makalemizde belirttim. aklınıza gelebilecek her şey gözüme çarptı.

const file = event.dataTransfer?.files[0];
if (file?.type === 'application/json' || file?.name.endsWith('.excalidraw')) {
  this.setState({ isLoading: true });
  // Provided by browser-fs-access.
  if (supported) {
    try {
      const item = event.dataTransfer.items[0];
      file as any.handle = await item as any
        .getAsFileSystemHandle();
    } catch (error) {
      console.warn(error.name, error.message);
    }
  }
  loadFromBlob(file, this.state).then(({ elements, appState }) =>
    // Load from blob
  ).catch((error) => {
    this.setState({ isLoading: false, errorMessage: error.message });
  });
}

Dosyaları paylaşma

Şu anda Android, ChromeOS ve Windows'daki bir başka sistem entegrasyonu da Web Paylaşımı Hedef API'si. Downloads klasörümdeki Dosyalar uygulamasındayım. İ biri açıklayıcı olmayan untitled adlı ve bir zaman damgasına sahip iki dosya görebilir. Kontrol etmek istediğiniz üç noktayı tıklıyorum, ardından paylaşıyorum ve açılan seçeneklerden biri. Excalidraw. Simgeye dokunduğumda dosyanın tekrar yalnızca I/O logosunu içerdiğini görüyorum.

Kullanımdan kaldırılan Electron sürümünde Lipis

Henüz bahsetmediğim dosyalarla yapabileceklerinizden biri de onları doubleclick'e yazmaktır. Genellikle dosyanın MIME türüyle ilişkilendirilmiş uygulama olduğu için bir dosyayı açılır. Örneğin, .docx için Microsoft Word kullanılır.

Excalidraw, uygulamanın Electron sürümüne sahipti: bu tür dosya türü ilişkilendirmelerini desteklediğinden bir .excalidraw dosyasını çift tıkladığınızda Excalidraw Electron uygulaması açılır. İçerik üretici, daha önce tanıştığınız Lipis'ti. ve Excalidraw Electron'un çürütücüsü. Kendisine Elektron sürümü:

Kullanıcılar en başından beri Electron uygulamasını istiyorlar, çünkü asıl istedikleri dosyaları çift tıklayarak açabilirsiniz. Uygulamayı uygulama mağazalarına da yerleştirmeyi amaçladık. Buna paralel olarak, bunun yerine bir PWA oluşturulmasını önerdi. Biz de her ikisini de yaptık. Neyse ki Fugu Projesi bize Dosya sistemi erişimi, pano erişimi, dosya işleme gibi API'ler. Tek bir tıklamayla yapabilecekleriniz: uygulamayı masaüstünüze veya mobil cihazınıza Electron'un ekstra ağırlığı olmadan yükleyebilirsiniz. Çok kolaydı Electron sürümünü kullanımdan kaldırma kararını, yalnızca web uygulamasına odaklanmasını olabilecek en iyi PWA'dır. Bunların yanı sıra, artık PWA'ları Play Store ve Microsoft Mağaza! Muazzam!

Electron için Excalidraw'ın desteğinin sonlandırılmadığı söylenebilir çünkü Electron'un kötü olduğu söylenemez ama çünkü web yeterince iyi hale geldi. Bunu beğendim!

Dosya işleme

"Web yeterince iyi hale geldi" dediğimde, bunun nedeni artık yeni çıkmış dosya Kullanım.

Bu, normal bir macOS Big Sur yüklemesidir. Şimdi bir tane sağ tıklayıp tıkladığımda ne olduğuna Excalidraw dosyası. Ancak yüklü PWA'yı (Progresif Web Uygulaması) Excalidraw ile açmayı tercih edebilirim. Tabii ki çift tıklamak da işe yarar, ancak bir ekran video kaydında bunu göstermek daha az dramatiktir.

Peki bu nasıl çalışır? İlk adım, uygulamamın işleyebileceği dosya türlerini işletim sistemidir. Bunu, web uygulaması manifestindeki file_handlers adlı yeni bir alanda yapıyorum. Bu value, bir işlem ve accept özelliği olan bir nesne dizisidir. İşlem, URL'yi belirler işletim sisteminin uygulamanızı başlattığınız ve kabul edilen nesne MIME anahtar/değer çiftleridir türlerini ve ilişkili dosya uzantılarını görmenize yardımcı olur.

{
  "name": "Excalidraw",
  "description": "Excalidraw is a whiteboard tool...",
  "start_url": "/",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "file_handlers": [
    {
      "action": "/",
      "accept": {
        "application/vnd.excalidraw+json": [".excalidraw"]
      }
    }
  ]
}

Sonraki adım, uygulama başlatıldığında dosyanın işlenmesidir. Bu, launchQueue içinde gerçekleşir setConsumer() numaralı telefonu arayarak tüketici ayarı yapmam gereken bir arayüz oluşturuyor. Bu parametre fonksiyonu launchParams öğesini alan eşzamansız bir işlevdir. Bu launchParams nesne "dosyalar" adlı bir alana sahip ve bu alan, üzerinde çalışabileceğim bir dizi dosya tutma yeri sağlıyor. Yalnızca şu ürünle ilgileniyorum: ve bu dosya tanıtıcısından bir blob alıyorum. Sonra da eski arkadaşımıza loadFromBlob()

if ('launchQueue' in window && 'LaunchParams' in window) {
  window as any.launchQueue
    .setConsumer(async (launchParams: { files: any[] }) => {
      if (!launchParams.files.length) return;
      const fileHandle = launchParams.files[0];
      const blob: Blob = await fileHandle.getFile();
      blob.handle = fileHandle;
      loadFromBlob(blob, this.state).then(({ elements, appState }) =>
        // Initialize app state.
      ).catch((error) => {
        this.setState({ isLoading: false, errorMessage: error.message });
      });
    });
}

Bu işlem çok hızlı ilerlediyse, Dosya İşleme API'sı hakkında daha fazla bilgiyi makalem. Deneysel web platformunu ayarlayarak dosya işlemeyi etkinleştirebilirsiniz özellikler işareti Bu yılın ilerleyen dönemlerinde Chrome'da yayınlanması planlanıyor.

Pano entegrasyonu

Excalidraw'ın bir diğer iyi özelliği de pano entegrasyonu. çizimimi tamamen kopyalayabilirim bir filigran ekleyebilir, isterseniz bir filigran ekleyebilir, sonra da başka bir uygulama. Bu arada, Windows 95 Paint uygulamasının web sürümüdür.

Bunun çalışma şekli şaşırtıcı derecede basit. İhtiyacım olan tek şey, tuvali bir blob olarak blob içeren bir ClipboardItem içeren tek öğeli diziyi navigator.clipboard.write() işlevi. Panoyla yapabilecekleriniz hakkında daha fazla bilgi için API, Jason'ın makalesine ve makaleme bakın.

export const copyCanvasToClipboardAsPng = async (canvas: HTMLCanvasElement) => {
  const blob = await canvasToBlob(canvas);
  await navigator.clipboard.write([
    new window.ClipboardItem({
      'image/png': blob,
    }),
  ]);
};

export const canvasToBlob = async (canvas: HTMLCanvasElement): Promise<Blob> => {
  return new Promise((resolve, reject) => {
    try {
      canvas.toBlob((blob) => {
        if (!blob) {
          return reject(new CanvasError(t('canvasError.canvasTooBig'), 'CANVAS_POSSIBLY_TOO_BIG'));
        }
        resolve(blob);
      });
    } catch (error) {
      reject(error);
    }
  });
};

Başkalarıyla ortak çalışma

Oturum URL'sini paylaşma

Excalidraw'da ortak çalışma modu da olduğunu biliyor muydunuz? Farklı insanlar çeşitli konulardaki görürsünüz. Yeni bir oturum başlatmak için canlı ortak çalışma düğmesini tıklıyorum ve kabul edilir. sayesinde, oturum URL'sini ortak çalışanlarla kolayca paylaşabiliyorum. Excalidraw'ın entegre ettiği Web Paylaşımı API.

Canlı ortak çalışma

Pixelbook'umdaki Google I/O logosu üzerinde çalışarak yerel olarak ortak çalışma oturumunun simülasyonunu yaptım. Pixel 3a telefonum ve iPad Prom. Bir cihazda yaptığım değişikliklerin Google Cloud'a diğer tüm cihazlarda kullanılabilir.

Tüm imleçlerin hareket ettiğini bile görebiliyorum. Pixelbook kontrol edildiği için imleci sabit bir şekilde hareket ediyor ancak Pixel 3a telefonun imleci ile iPad Pro'nun tablet imleci arasında zıplıyor çünkü bu cihazları parmağımla dokunarak kontrol et.

Ortak çalışan durumlarını görme

Hatta gerçek zamanlı ortak çalışma deneyimini iyileştirmek için çalışan boşta kalma algılama sistemi bile var. iPad Pro'yu kullandığımda imleci yeşil bir nokta gösteriyor. Bir farklı bir tarayıcı sekmesi veya uygulaması. Excalidraw uygulamasında hiçbir şey yapmadan, imleç beni üç zZZ harfiyle sembolize edilen boşta olarak gösteriyor.

Yayınlarımızın tutkulu okuyucuları, boşta kalma algılamasının, Idle Detection API, irdeleyelim. Spoiler uyarısı: Aslında öyle değil. Daha önce söz konusu API'yi temel alan kullanmaya karar verdik. Sonunda, ölçüme dayalı daha geleneksel bir yaklaşıma işaretçi hareketi ve sayfa görünürlüğü.

WICG Boşta Kalma Algılama deposuna gönderilen Boşta Algılama geri bildiriminin ekran görüntüsü.

Idle Detection API'nin neden kullanıldığıyla ilgili geri bildirim gönderdik problemi çözemiyorduk. Tüm Project Fugu API'leri açık ortamda geliştirilmektedir, isteyen herkes sesini duyurabilir!

Excalidraw'ı engelleyen dudaklar

Bundan bahsetmişken, Lipis'e web'de eksik olduğunu düşündüğü şeylerle ilgili son bir soru sordum. etkin bir platformdur:

File System Access API çok iyi, ama ne olduğunu biliyor musunuz? Bu günlerde önem verdiğim dosyaların çoğu sabit diskimde değil, Dropbox'ımda veya Google Drive'ımda bulunuyor. File System Access API'nin Dropbox veya Google gibi uzak dosya sistemi sağlayıcıların entegre edilmesi için bir soyutlama katmanı ekleme kod yazmasına yardımcı oluyor. Böylece kullanıcılar rahatlayıp dosyalarının güvende olduğunu anlayabilir güvenilir bir bulut sağlayıcı ile görüşün.

Lipis'e tamamen katılıyorum, ben de bulutta yaşıyorum. Umarım bunu uygular yakında.

Sekmeli uygulama modu

İnanılmaz! Excalidraw'da birçok harika API entegrasyonu gördük. Dosya sistemi, dosya işleme, clipboard, web paylaşımı ve web paylaşımı hedefi. Ancak bir şey daha var. Şimdiye kadar ne yaptığını aynı anda tek bir dokümanı düzenleme. Ama artık değil. Google Play'in ilk oyunlarından biri Excalidraw'daki sekmeli uygulama modu. Bu şekilde görünüyor.

Bağımsız modda çalışan yüklü Excalidraw PWA'da açık bir dosyam var. Şimdi Bağımsız pencerede yeni bir sekme açarım. Bu normal bir tarayıcı sekmesi değil, PWA sekmesidir. Burada yeni sekmeden ikinci bir dosya açabilir ve aynı uygulama penceresinden bu dosyalar üzerinde bağımsız olarak çalışabilirim.

Sekmeli uygulama modu henüz ilk aşamalarındadır ve tüm özellikleri sabitlenmiş değildir. Eğer bu özelliğin mevcut durumu hakkında bilgi edinmek için makalem.

Kapanış

Bu ve diğer özelliklerden haberdar olmak için Fugu API izleyici. Web'i ileriye taşıyacak ve platformda daha fazlasını yapmanızı sağlar. Sürekli gelişen bir Excalidraw'ı keşfedin ve harika uygulamalar geliştireceksiniz. Hemen oluşturmaya başlayın excalidraw.com.

Bugün gösterdiğim API'lerden bazılarını uygulamalarınızda görmek için sabırsızlanıyorum. Adım Tolga. beni Twitter'da ve genel olarak internette @tomayac olarak bulabilirsiniz. İzlediğiniz için çok teşekkür eder ve Google I/O'daki diğer başarılarınızın keyfini çıkarmanızı dileriz.