Publicat per

Pràctica 2

Publicat per

Pràctica 2

Ideació inicial de la nova App L’objectiu d’aquesta pràctica 2 ha estat donar continuïtat a la feina feta en la pràctica 1…
Ideació inicial de la nova App L’objectiu d’aquesta pràctica 2 ha estat donar continuïtat a la feina feta en…

Ideació inicial de la nova App

L’objectiu d’aquesta pràctica 2 ha estat donar continuïtat a la feina feta en la pràctica 1 i desenvolupar una app interactiva basada en un puzle de peces mòbils, que permet a l’usuari carregar la imatge amb la qual es jugarà dins del puzle.
A la pràctica 1, l’app permetia escollir entre una imatge feta amb la càmera o una imatge existent a la galeria. A la pràctica 2 mantinc aquestes funcionalitats i n’afegeixo una de nova: obtenir imatges de Picsum per utilitzar-les en el puzle.
També es manté l’opció de mostrar un botó de configuració per escollir la mida del puzle amb què es vol jugar.
Aquests són els esbossos de la pràctica 1 i el resultat final de la pràctica 2.

Interfície proposada a la pràctica 1
Evolució del disseny de la pràctica 2

 

Consultes i passos seguits a la documentació de Capacitor

Per tal de desenvolupar l’app amb Capacitor i integrar funcionalitats natives, he seguit el procés de consulta i experimentació següent:

  • Revisió de la documentació oficial de Capacitor per entendre com funciona la integració amb projectes web.
  • Consulta dels plugins oficials i dels seus exemples d’ús.

Especial focus en:

  • Camera Plugin: per capturar imatges directament des del dispositiu o carregar-les des de la galeria.
  • Haptics Plugin: per afegir feedback tàctil durant la interacció amb el puzle.
  • També s’ha considerat com adaptar el codi perquè funcioni correctament dins d’una app híbrida (ús de webPath, càrrega d’imatges amb p5.loadImage, etc.).

Aquestes consultes han permès comprendre com utilitzar les APIs natives des de JavaScript, i com gestionar errors, permisos i diferents comportaments segons el dispositiu.

Proves amb diferents funcionalitats natives del dispositiu

Per a la pràctica, s’han provat funcionalitats natives per donar valor afegit a l’aplicació:

Càmera i galeria (Camera Plugin)

L’usuari pot:

  • Fer una foto amb la càmera.
  • Seleccionar una imatge de la galeria.

Aquestes imatges es processen i es transformen en un puzle.

Vibració / feedback tàctil (Haptics Plugin)
  • Quan el jugador fa un moviment vàlid, l’app fa una vibració lleugera.
  • Quan el puzle queda resolt, es mostra un efecte extra (vibració més forta o més llarga).

Aquestes funcionalitats fan que l’experiència sigui més “game-like” i milloren la resposta al tacte.

Proves realitzades:
  • Verificar la càrrega correcta de la imatge a p5.js.
  • Comprovar el comportament quan l’usuari cancel·la la selecció (sense perdre la partida actual).
  • Detectar problemes amb l’orientació/simetria de la foto (amb càmera frontal). Aquest punt queda pendent de resoldre per falta de temps per buscar una solució.

Decisions preses i aprenentatges adquirits

Durant el desenvolupament de l’MVP, he pres diverses decisions tècniques i de disseny:

Decisió 1: API externa → Picsum

S’ha triat Picsum com a API externa per:

  • Poder obtenir imatges aleatòries per jugar sense necessitat de tenir fotos personals.
  • Tenir una resposta en format JSON amb dades útils (com l’autor).
  • Evitar complicacions com l’autenticació o l’ús d’API keys.
  • Facilitar la idea d’un joc “rejugable”.
Decisió 2: Mostrar l’autor de la imatge

Quan s’utilitza una imatge de Picsum, es mostra un text sota el puzle amb l’autor. Això aporta:

  • Transparència.
  • Un toc de “crèdit” visual.
  • Millor integració amb el requisit de mostrar dades de l’API dins l’app.
Decisió 3: Afegir una previsualització de la imatge original

Com que el puzle pot ser difícil, s’ha afegit:

  • Una icona que permet veure la imatge sencera com a referència. No es tracta de la imatge original completa, sinó d’una secció quadrada de la imatge original. Aquesta imatge retallada és la que utilitzarà el puzle.
  • Aquesta funcionalitat millora el gameplay i permet resoldre el puzle amb més facilitat.
Aprenentatges principals
  • Les funcionalitats natives en apps híbrides poden tenir comportaments diferents segons el dispositiu (càmera frontal invertida, cancel·lacions, permisos…).
  • La UI afecta molt l’experiència: cal ajustar espais, alineacions, overlays i coherència visual.

Esbossos, captures i iteracions que mostrin l’evolució del projecte

Iteració 1: MVP funcional (PR1): puzzle amb imatge local i funcionament bàsic:

 

 

 

 

 

 

Iteració 2: Integració de l’API

  • Afegir el botó de Picsum per arregar una imatge aleatòria des del JSON.
  • Mostrar l’autor de la imatges
  • Afegir un HUD amb:
    • Comptador de moviments.
    • Comptador de temps.
    • Icona de previsualització i overlay per mostrar la imatge utilitzada en el puzzle itenir-la de referència.

Justificació breu: problemes trobats, solucions i conclusions

  • Problema 1: l’autor desapareix quan es cancel·la galeria/càmera
    Causa: el text de l’autor s’esborrava abans de confirmar que s’havia carregat una nova imatge.
    Solució: netejar l’autor només quan la càrrega de la nova imatge sigui exitosa.
  • Problema 2: puzles que començaven ja resolts
    Causa: el shuffle podia deixar el mateix estat final que el puzle resolt.
    Solució: aplicar una comprovació després del shuffle i repetir-lo fins que el puzle no estigui resolt.
  • Problema 3: el temps no s’aturava en resoldre el puzle
    Causa: el valor puzzle.solved no s’actualitzava just en el mateix moment del touchStarted.
    Solució: aturar el cronòmetre des del draw() quan el puzle està resolt.

Citació de totes les fonts utilitzades

Documentació oficial / fonts tècniques:

  • Capacitor (documentació oficial): Camera Plugin i Haptics Plugin.
  • Recursos sobre CORS i consum d’APIs en aplicacions web.

API externa:

  • Lorem Picsum API (endpoint /v2/list i càrrega d’imatges per ID).

He utilitzat ChatGPT com a suport per:

  • Depurar errors de l’app.
  • Proposar estructures de codi.
  • Millorar el CSS i la UX.
  • Resoldre conflictes d’overlays i layout.

Vídeo

Per realitzar aquest vídeo he utilitzat un ZTE Blade A51, Android versió 11.

Carregant...

Debat0el Pràctica 2

No hi ha comentaris.

Publicat per

Pràctica 1

Publicat per

Pràctica 1

Introducció i objectiu de l’App L’objectiu d’aquest projecte ha estat desenvolupar una App interactiva basada en un puzle de peces mòbils que…
Introducció i objectiu de l’App L’objectiu d’aquest projecte ha estat desenvolupar una App interactiva basada en un puzle de…

Introducció i objectiu de l’App

L’objectiu d’aquest projecte ha estat desenvolupar una App interactiva basada en un puzle de peces mòbils que permet a l’usuari carregar una imatge des de la càmera o la galeria del dispositiu. L’App transforma aquesta imatge en un trencaclosques i ofereix opcions de configuració per ajustar-ne la dificultat (mida del puzle).

Procés d’ideació de l’App

Des de l’inici tenia clar que volia crear una App lúdica i senzilla, però tenia dubtes sobre quines funcionalitats natives del mòbil volia incorporar. Finalment, vaig decidir experimentar amb la càmera i, a partir d’aquí, em va sorgir la idea de desenvolupar un joc de puzle utilitzant una imatge triada per l’usuari.
Com que aquesta App tindrà continuïtat a la Pràctica 2, he creat una estructura inicial senzilla amb la previsió d’ampliar-la i evolucionar-la en la pròxima entrega.

En el menú opcions ofereix la possibilitat de triar la mida del puzzle. Es permet triar 2×2,3×3,4×4, 5×5,6×6. L’opció escollida es guarda en localStorage per redimensionar la graella del puzzle.

Consultes externes

Durant el desenvolupament vaig realitzar consultes externes per resoldre dubtes tècnics i generar proves ràpides. Principalment, vaig utilitzar ChatGPT com a suport per:

  • Detectar errors en la gestió del DOM amb p5 i millorar l’estructura del codi i l’organització de funcions.
  • Consultar exemples de projectes similars i fragments d’algorismes per assegurar-me que seguia una lògica correcta.

Documentació de Capacitor rellevant per a l’App

Per integrar funcionalitats natives, he utilitzat Capacitor. Les parts més rellevants han estat:

  • Camera API: per obtenir imatges del dispositiu. A través de Camera.getPhoto() amb resultType: Uri vaig recuperar la ruta webPath que posteriorment es carrega a p5 amb loadImage().
    Per fer us de la càmera cal modificar el AndroidManifest.xml. Aconcretament, s’ha d’afegir aquest codi dins manifest > application > provider.
<intent-filter>
<action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
</intent-filter>
<meta-data android:name="photopicker_activity:0:required" android:value="" />

A l’apartat de permisos també cal afegir:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

En el codi, cal instal·lar les dependències necessàries:

import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
import { Haptics, ImpactStyle } from '@capacitor/haptics';

I executar les següents ordres:

npm install @capacitor/camera
npm install @capacitor/haptics
  • Haptics API: he aprofitat l’exemple del tutorial Pomodoro per afegir feedback a la interacció. Cada moviment vàlid de peça activa un impact lleuger i, en completar el puzle, una vibració curta.
import { Haptics, ImpactStyle } from '@capacitor/haptics';

Amb la següent ordre:

npm install @capacitor/haptics

Esbossos i captures

 

 

 

 

 

 

 

 

 

 

Principals proves i millores

Les principals proves i millores han estat les següents:

  • Ajust del canvas a la pantalla per garantir una experiència coherent en diferents dispositius.
  • Tractament de la imatge: inicialment, la imatge es deformava; es va solucionar aplicant un retall quadrat centrat (cropToSquare) abans de redimensionar-la al canvas.
  • Barreja del puzle: per evitar combinacions impossibles, es va implementar una barreja basada en moviments vàlids a partir de la configuració inicial resolta.
  • Experiència d’usuari: es va incorporar feedback hàptic en cada moviment i també quan es completa el puzle.

Problemes trobats

Durant el desenvolupament, els principals problemes trobats han estat:

  • Gestió de l’estat: com detectar quan hi ha una imatge carregada i com canviar correctament la vista.
  • Tractament d’imatges amb formats diferents: solucionat amb un retall quadrat centrat i el redimensionament posterior.Assegurar que la barreja del puzle fos resoluble: solucionat mitjançant una barreja basada en moviments vàlids.

A més, prèviament vaig tenir un problema amb el Virtual Device Manager d’Android Studio. En intentar iniciar l’emulador Medium Phone API 36.1 des del Virtual Device Manager, apareixia un error que impedia l’execució.

Tot i que utilitzo Ubuntu 24.04.3 LTS, també vaig provar d’executar-lo en Windows i el problema es mantenia. Per resoldre aquesta incidència, vaig utilitzar especialment ChatGPT com a suport.
Finalment, vaig entendre que aquest error indicava que l’emulador no podia utilitzar l’acceleració per maquinari (KVM) perquè el dispositiu /dev/kvm no existia. Aquesta situació acostuma a produir-se per diversos motius, però en el meu cas la causa era que la virtualització (VT-x/AMD-V) estava desactivada a la BIOS.

Debat0el Pràctica 1

No hi ha comentaris.

Publicat per

R3 extensió web

Publicat per

R3 extensió web

Documentació de l’Extensió Rellotge Binari   Concepte del projecte Aquesta extensió és una aplicació de tipus WebExtension per al navegador Firefox. Mostra…
Documentació de l’Extensió Rellotge Binari   Concepte del projecte Aquesta extensió és una aplicació de tipus WebExtension per al…

Documentació de l’Extensió Rellotge Binari

 

Concepte del projecte

Aquesta extensió és una aplicació de tipus WebExtension per al navegador Firefox. Mostra un rellotge binari minimalista dins d’un popup, permetent personalitzar el color dels bits i la visualització de l’hora digital. L’objectiu és oferir una eina visual i estètica que representi el temps d’una manera alternativa.

Esbossos del disseny


Les tres columnes representen l’hora (columna esquerra), els minuts (columna central) i els segons (columna dreta). Cada columna té sis quadrats que representen els bits d’un nombre binàri.

Hi ha nombres que, en convertir-los a binari, no necessiten 6 dígits per ser representats. Per exemple, el número 23 es converteix en 10111, que només té 5 dígits. Per mantenir totes les columnes del rellotge amb la mateixa alçada i el mateix nombre de quadrats, he afegit zeros a l’esquerra fins a completar els 6 dígits. D’aquesta manera, hores, minuts i segons sempre formen columnes uniformes i visualment alineades.

Alhora de representar aquest números binaris en les columnes, el primer dígit de l’esquerra es representa a dalt de tot en la seva colummna corresponent i els digits següents és van dibuixant en la columna en ordre descendent. Els quadrats grisos equivalen a 0 i els quadrats blaus equivalen a 1.

Casos d’ús principals

  • Consultar l’hora en format binari.
  • Personalitzar el color dels bits per adaptar-lo al gust o al tema del navegador.
  • Activar o desactivar la visualització de l’hora digital.

Interacció amb els elements

La icona de configuració en el popup redirecciona a la secció de configuració on es pot decidir:

  • Mostrar o no l’hora en format digital
  • Canviar el color dels cuadrats que representen bits actius.

Ús de storeItem() i getItem()

L’extensió utilitza localStorage per recordar les preferències de l’usuari. Quan l’usuari canvia el color dels bits o la configuració de l’hora digital, la informació s’emmagatzema amb storeItem(). Quan el popup es torna a obrir, getItem() recupera les preferències guardades, permetent mantenir la configuració personalitzada sempre activa.

Millora proposada
Fixar el popup perquè es pugui mantenir obert (“pin popup”).

Normalment, el popup d’una extensió es tanca automàticament quan l’usuari fa clic fora o canvia de pestanya. Això és una limitació de totes les extensions: un popup no pot quedar-se obert per si mateix. La millora consisteix a simular un “popup fix” obrint una finestra pròpia de l’extensió que actua com una mini-aplicació flotant.

Això permetria:

  • Mantenir el rellotge sempre visible.
  • Posicionar-lo lliurement.
  • Tancar-lo manualment quan l’usuari vulgui.
  • Obrir múltiples “rellotges” si es permet.

Procediment proposat:

  • Afegir una icona estil “xinxeta” al popup

Quan l’usuari prem el botó, sobre una petita finestra independent que no es tanca sola, es pot moure, i té el mateix contingut que el popup.

  • Diferenciar el popup real de la finestra flotant

El codi podria detectar si està dins una finestra flotant:

  • 3. Desactivar elements innecessaris en la versió fixada.

• Amagar el botó “Opcions”
• amagar la icona “xinxeta” (per no obrir infinites finestres)

Enllaç Git

https://github.com/magulloc/rellotge-binari.git

Debat0el R3 extensió web

No hi ha comentaris.

Publicat per

R2 – Healthy Smile

Publicat per

R2 – Healthy Smile

Es tracta d’una aplicació interactiva que utilitza la càmera web per detectar la cara de l’usuari i, més concretament, l’obertura de la…
Es tracta d’una aplicació interactiva que utilitza la càmera web per detectar la cara de l’usuari i, més concretament,…

Es tracta d’una aplicació interactiva que utilitza la càmera web per detectar la cara de l’usuari i, més concretament, l’obertura de la boca. Quan l’usuari obre la boca, l’aplicació genera animacions, combinades amb música i elements visuals com fantasmes i una carabassa animada. L’objectiu és oferir una experiència que connecti el moviment facial amb efectes gràfics en temps real.

Workflow del App

L’aplicació s’inicia mostrant una pantalla de benvinguda amb el títol i un botó “Començar”, indicant a l’usuari que ha d’obrir la boca per generar animacions. En prémer el botó, es carrega la càmera i es detecta la cara en temps real amb FaceMesh; quan l’usuari obre la boca, apareixen partícules animades (caramels) sobre els llavis. Alhora, la música es reprodueix i es pot controlar amb el botó de play/pause i el slider de volum. La interacció continua fins que l’usuari tanca l’aplicació, moment en què es deixa de processar el vídeo i s’aturen les animacions i el so.

Aspectes tècnics

He fet servir p5.js 2.0.5 i per detectar el moviment dels llavis en temps real he triat la llibreria externa ml5.js, concretament el model FaceMesh. Es tracta d’una llibreria JavaScript basada en TensorFlow.js que facilita l’ús de models d’intel·ligència artificial directament al navegador.

El model FaceMesh detecta de forma automàtica i en temps real més de 400 punts de referència de la cara, incloent-hi els llavis, els ulls i el contorn facial. Aquesta detecció detallada permet calcular l’obertura de la boca i generar animacions de partícules exactament en la posició correcta dels llavis.

L’avantatge de fer servir ml5.js és que tot es processa localment al navegador, sense necessitat de servidors externs ni enviar imatges de la càmera a la xarxa, millorant la privacitat i la fluïdesa de l’experiència.

Enllaços

Github

https://github.com/magulloc/healthy_smile

Web

https://editor.p5js.org/magulloc/full/QXkPzX7lH

Debat0el R2 – Healthy Smile

No hi ha comentaris.