Advertisement
  1. Web Design
  2. UX/UI
  3. Prototyping

Cómo Crear un Prototipo de Aplicación Usando CSS y JavaScript

Scroll to top
Read Time: 8 min

() translation by (you can also view the original English article)

La animación es realmente una de las mejores características en llegar a CSS en mucho tiempo. Después de todo, como nos hemos dado cuenta, el movimiento puede mejorar la experiencia de usuario y motivar acciones en donde los contextos estáticos se quedan cortos. En este tutorial vamos a construir un prototipo para una aplicación usando animaciones CSS y un toque de JavaScript.

Lo Que Estamos Creando

Para este ejercicio desarrollaremos un prototipo para una aplicación que permite a los suscriptores seguirse unos a otros. Inicialmente, cargaremos una lista de usuarios con sus nombres debajo de cada avatar correspondiente. Esos avatares, cuando se les da clic, dispararán un modal conteniendo un botón "seguir" e información adicional perteneciente a cada usuario individual.

Para propósitos de demostración cargaremos 30 usuarios usando un servicio llamado Generador Aleatorio de Usuarios. Su API no solo proporciona imágenes aleatorias para usuarios, sino que también proporciona datos aleatorios como nombres, direcciones, correos electrónicos y mucho más.

1. Establece el Escenario

He discutido opciones anteriormente para construir conceptos de prototipo, pero para este artículo construiremos un prototipo con código real. Para esta tarea estaremos usando Marvel Devices; una librería de código abierto que contiene dispositivos móviles de CSS puro para mostrar prototipos típicamente hechos con Marvel App.

Para comenzar incluye devices.min.css en la parte superior de tu documento, regresa a la demostración y selecciona la combinación que quieres, después, copia y pega el HTML generado en tu proyecto.

2. Carga los Usuarios

Con el CSS obtenido para nuestro dispositivo de demostración (Nexus 5) es tiempo de trabajar en cargar los usuarios de nuestra aplicación.

1
<div class="marvel-device nexus5">
2
    <div class="top-bar"></div>
3
    <div class="sleep"></div>
4
    <div class="volume"></div>
5
    <div class="camera"></div>
6
    <div class="screen">
7
        <h3 class="title">Results</h3>
8
        <ul class="users"></ul>
9
    </div>
10
</div>

Los usuarios serán cargados como elementos de lista e inyectados en la lista sin orden .users. Esta es la base inicial, pero necesitamos usar JavaScript para comunicar con la API de usuario aleatorio para poder insertar estos elementos de lista. Para hacer esta petición usaremos JavaScript plano estilo ES6.

1
let request = new XMLHttpRequest();

El request es la variable que contendrá nuestra petición AJAX, pero requiere una URL con la cuál conectar.

1
request.open('GET', 'https://randomuser.me/api/?results=30', true);

El método open regresará los datos de la API desde la URL y los parámetros que establecimos. Hay muchos otros parámetros para usar, pero para esta demostración solo regresaremos 30 resultados. Ahora que tenemos nuestra URL en su lugar y la petición enviada, regresemos esa información.

1
// Utility for DOM selection

2
function select(s) {
3
  return document.querySelector(s);
4
}
5
6
// Store for referencing

7
const users = select('.users'),
8
9
// AJAX Request

10
request.onload = function() {
11
  if (request.status >= 200 && request.status < 400) {
12
13
    let data = JSON.parse(request.responseText),
14
        l    = data.results.length;
15
16
    for(var i = 0; i < l; i++) {
17
        // data results

18
        console.log(data.results[i]);
19
    }
20
21
  } else {
22
    alert('We reached our target server, but there was an error');
23
  }
24
};
25
26
request.onerror = function() {
27
  alert('There was a connection error of some sort')
28
};
29
30
// Send Ajax call

31
request.send();

La petición entera está ahora en  posición. Abriendo la consola verás todos los resultados de los datos proporcionados listados. Este es un buen comienzo, pero definitivamente necesitamos hacer más que solo registrar la salida a la consola.

3. Inyectar Datos de Usuario

Para esta siguiente parte, inyectaremos marcado usando los datos que tenemos disponibles de la API de usuarios aleatorios.

1
users.insertAdjacentHTML('beforeend', '<li><img src="'+ 
2
                         data.results[i].picture.medium +'" data-pic="'+ 
3
                         data.results[i].picture.large +'" data-name="'+ 
4
                         data.results[i].name.first + ' ' + 
5
                         data.results[i].name.last + '" data-email="'+ 
6
                         data.results[i].email +'"><span class="user-name">'+ 
7
                         data.results[i].name.first +'</span></li>');

Las líneas de código de arriba serán colocadas en el ciclo creado anteriormente que estaba registrando datos a la consola. Como se mencionó, tenemos unas cuantas opciones en relación a los datos adjuntos a los objetos de usuario, como un primer nombre, correo electrónico y tamaños de avatar. El tamaño mediano de imagen será usado para mostrar inicialmente, mientras que el tamaño grande será usado para nuestro modal que es disparado cuando el avatar miniatura es presionado. Todas estas piezas de información serán almacenadas dentro de atributos de datos para que podamos recogerlos según sea necesario.

4. Detecta la Posición de Avatar

Vamos a construir otro componente para esta demostración; un modal es disparado desde el punto de ejecución (ej. dando clic sobre un avatar). Necesitaremos a nuestro querido amigo matemáticas para realmente determinar de donde se expandirá el modal. 

1
var transOriginNames = {
2
  webkitTransformOrigin : 'webkitTransformOrigin',
3
  MozTransformOrigin    : 'MozTransformOrigin',
4
  msTransformOrigin     : 'msTransformOrigin',
5
  transformOrigin       : 'transformOrigin'
6
};
7
8
users.addEventListener('click', function(e) {
9
  let target        = e.target,
10
      target_coords = target.getBoundingClientRect();
11
12
  if(target.nodeName === 'IMG') {
13
    for(var name in transOriginNames) {
14
      modal.style[name] = (target.offsetLeft + (target_coords.width/2)) +'px ' + ((target.offsetTop + (target_coords.height/2)) - screen_scroll.scrollTop) + 'px';
15
    }
16
  }
17
});

Para lograr esta expansión del modal desde el punto de ejecución necesitamos asegurar que nuestro transform-origin es correcto para poder escalar apropiadamente el modal. Estoy usando un object para contener todos nuestros prefijos transform-origin ya que estamos usando JavaScript para establecerlos y también necesitamos asegurar que todas las bases están cubiertas para navegadores que no soportan el estándar.

Toma nota de las matemáticas requeridas para determinar los valores transform-origin.

1
modal.style[name] = (target.offsetLeft + (target_coords.width/2)) +'px ' + ((target.offsetTop + (target_coords.height/2)) - screen_scroll.scrollTop) + 'px';

El diagrama de arriba explica visualmente cómo se están calculando las matemáticas. Para poder determinar la ubicación correcta usamos offsetLeft y offsetTop más la mitad de width y height respectivamente para encontrar el centro exacto del avatar. scrollTop también es muy importante porque 30 usuarios desbordarán los límites de la pantalla del dispositivo y offsetTop necesitará tener este valor restado para determinar la distancia apropiada de la parte superior de la pantalla. Todos los valores en el diagrama de arriba son proporcionados por nuestro amigo getBoundingClientRect.

Registrando target_coords a la consola puedes ver todas las dimensiones y valores que requerimos para hacer una suposición apropiada. Estos valores con relación a width y height siempre cambiarán dependiendo de la posición del avatar dentro de la pantalla del dispositivo.

5. Anima el Modal

Con las coordenadas del avatar prepuestas y listas para recibir nuestro evento clic, es tiempo de agregar el movimiento modal que mostrará el perfil de usuario.

1
.modal {
2
  transform: scale(0) translateZ(0);
3
  transition-duration: 320ms;
4
  transition-timing-function: cubic-bezier(.4, 0, .2, 1);
5
  transition-property: transform, opacity;
6
  opacity: 0;
7
}

El código de arriba está reducido de la demostración para mostrar las propiedades exactas de movimiento que vamos a estar usando. Estamos escondiendo inicialmente usando opacity y scale.

Ahora es tiempo de definir las propiedades CSS que manejarán el estado activo para el movimiento del modal.

1
.screen.active .modal {
2
    transform: scale(1) translateZ(0);
3
    opacity: 1;
4
 }

Usando JavaScript vamos a intercalar una clase active en screen. En las líneas de arriba estamos revisando lo que establecimos anteriormente. Así es como creamos el efecto de expansión del modal. Es un estilo muy de Google Material Design que ayuda desde interrumpir el comportamiento cognitivo y rápidamente responde a la entrada del usuario de manera precisa haciendo responsivo al movimiento. Este estilo también confirma la entrada de usuario expandiendo inmediatamente hacia afuera del punto de contacto.

6. Dale Movimiento a los Avatares

Durante la carga crearemos un efecto de escalamiento haciendo la secuencia menos estática y más responsiva. Cada avatar escalará en un intervalo diferente que el siguiente y para eso usaremos CSS.

1
@keyframes fade-in {
2
  from { opacity: 0; }
3
  to   { opacity: 1; }
4
}
5
6
@keyframes expand-out {
7
  from { transform: scale(0); }
8
  to   { transform: scale(1); }
9
}
10
11
.users li {
12
    opacity: 0;
13
}

Inicialmente ocultaremos los usuarios y después intercalaremos una clase show una vez que la petición AJAX esté lista. También he incluido nuestros fotogramas que transformarán nuestras propiedades a los valores correctos. Usaremos estos fotogramas en el siguiente pedazo de código que establece el movimiento en reproducción.

1
$user-count: 30;
2
$duration: 200ms;
3
$stagger_delay: 0.0125s;
4
$easing: cubic-bezier(.66, .14, .83, .67);
5
6
.users.show {
7
  li {
8
    animation-duration: $duration;
9
    animation-name: fade-in;
10
    animation-fill-mode: both;
11
    animation-timing-function: $easing;
12
    opacity: 1;
13
14
    img {
15
      animation-duration: $duration;
16
      animation-name: expand-out;
17
      animation-fill-mode: both;
18
      animation-timing-function: $easing;
19
    }
20
21
    @for $i from 1 through $user-count {
22
      &:nth-of-type(#{$i}) {
23
        animation-delay: ($stagger_delay * $i);
24
        img {
25
          animation-delay: ($stagger_delay * $i);
26
        }
27
      }
28
    }
29
  }
30
}

Para ayudar con las matemáticas estoy usando ciclos Sass y variables para contener la cuenta de nuestros usuarios que también está atada con nuestros resultados JS desde la llamada de API de usuario aleatorio. El ciclo es la clave de todo el rompecabezas ya que ciclará sobre nuestra cuenta de usuarios y agregará el valor que definimos en una variable.

Arriba está nuestro resultado con la secuencia final de animación de avatar. Recuerda que solo estamos usando animaciones de fotograma en CSS y usando JavaScript para intercalar la clase show una vez que los avatares son recuperados desde la API de usuario aleatorio.

Ideas de Cierre

Asegúrate de ver la demostración  ya que ahí también hay elementos adicionales que agregan beneficios, tales como un cargador animado que mostrará mientras los usuarios está cargando y se remueve a el mismo una vez que los avatares están cargados.

Gracias a Shaw por su visión y esta toma Dribble usada para inspiración. Como siempre deja cualquier comentario abajo para discusión futura, ¡y dale a esta demostración algunos corazones en CodePen si quieres ver más como este!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.