Hace no mucho tiempo se me ocurrió renovar mi portafolio con un estilo más ad hoc con mi perfil de programador. Mi idea, que ya no está vigente, fue la creación de un sistema operativo completo en javascript - jQuery y HTML y comencé haciendo la terminal.
Curioso que la terminal quedó bastante simple y usable. Nació Terminal.js, el cual está hosteado en mi Github.
Esta vez no quise tomar como referencia ningún plugin ya existente para hacer este efecto, así que en el desarrollo de la primera versión, me surgieron varios retos.
Suena fácil, pero llegar a un markup y un código que cumpla con la función básica de escribir al estilo terminal, no fue sencillo; la terminal tenía que escribirse de manera natural, junto con el efecto del cursor del texto haciendo blink.
El markup lo hice de la siguiente manera:
<div id="terminal"> <div id="handle"><p>Kinduff's Terminal</p></div> <div class="terminal"> <div id="respuesta"></div> <span>$ </span><span class="clone"></span><span class="blink"></span> <input id="user" type="text" size="2" value="" /> </div> </div>
Donde tenemos un contenedor principal llamado #terminal
, un #handle
que funciona como barra de título. Un div #respuesta
para imprimir las respuestas de la terminal, el primer span
con el símbolo de usuario de UNIX, el segundo como contenedor de clonación y el tercero como el cursor que hace blink.
El tercer elemento es un input #user
, el cual con CSS no encargaremos que no se muestre.
Básicamente la lógica que sigue es que el usuario tiene un focus
hacia el input #user
, al escribir, el valor del input es clonado con cada tecleo en .clone
, entre el símbolo de dolar y el cursor.
La lógica detrás de cómo hacer el código escalable y fácil de mantener fue algo complicado, pero al final me basé en dos archivos: "Main" para funciones generales y "Views" para las preguntas y respuestas de la terminal.
Cubre funciones como el focus, el escrito y clonación de texto en contenedores, el "submit" a la terminal para recibir una respuesta, el efecto drag&drop y el efecto blink del cursor. Puedes revisar el código en el repositorio.
$(document).ready(function() { function focus() { $('#user').focus(); } $('.terminal').show(); focus(); // Focus, focus everywhere. $(window).focus(function() { focus(); $('#user').val($('#user').val()); }); $(document).click(function(e) { focus(); $('#user').val($('#user').val()); }); $('#user').on('input',function(e){ $('.clone').text($(this).val()); }); // Si es usuario presiona alguna tecla $('#user').keypress(function(e) { // Si es usuario presiona enter if(e.keyCode===13){ e.preventDefault(); var valor = $(this).val(); // Rescatamos valor $(this).val(''); // Hacemos clear al input $('.clone').text(''); // Hacemos clear al clon $('#respuesta').append('<p class="comando">'+valor+'</p>'); // Simulamos metida del comando en contenedor caso = cases.indexOf(valor); // views.js -> tomamos valor del array if (caso === -1) { // Si no existe el comando regresa -1 $('#respuesta').append('<p class="respuesta">Comando "'+valor+'" no identificado.<br />Para ver lista de comandos, escribe: help</p>'); } else { terminal(caso); // Si existe regresa 1..oo, ejecutamos función terminal } } }); function terminal(caso) { // Comando es un objeto, accedemos al caso if (comando[caso]) { // Si el caso tiene valor var x = comando[caso]; // asignamos a variable $('#respuesta').append('<p class="respuesta">'+x+'</p>'); // Simulamos respuesta } else { // Si no, es el primer comando, es decir, comando clear (limpia pantalla) $('#respuesta, .info').empty(); // Pasamos un trapito } } // Función para hacer blink al cursor // http://stackoverflow.com/questions/12903594/set-css-with-jquery-after-ajax $('.blink').each(function() { var elem = $(this); setInterval(function() { if (elem.css('visibility') == 'hidden') { elem.css('visibility', 'visible'); } else { elem.css('visibility', 'hidden'); } }, 500); }); // Para tomar la barra superior, simulamos drag en mouse $("#handle").live("mousedown", function () { // Click! $(this).css('cursor','move'); // Drag }).live("mouseup", function () { // Click-off... $(this).css('cursor','default'); // Default }); // Handler con dom-drag.js // DYNAMIC DRIVE FUCK YEAH! // http://www.dynamicdrive.com/dynamicindex11/domdrag/ var theHandle = document.getElementById("handle"); var theRoot = document.getElementById("terminal"); Drag.init(theHandle, theRoot); });
Únicamente cubre los casos específicos que se darán en la terminal y las respuestas que deberá de entregar, imprimiendo HTML directamente. Puedes revisar el código en el repositorio.
var cases = ['clear', 'help', 'resumen', 'cv', 'portafolio', 'contacto']; // Casos var comando = { 1: 'Comandos disponibles:<br />clear<br />help<br />resumen<br />cv<br />portafolio<br />contacto', 2: 'Muestra Resumen.', 3: 'Muestra CV.', 4: 'Muestra Portafolio.', 5: 'Muestra Contacto.' } // Respuesta a comandos
El demo lo puedes ver siguiendo este enlace.
Copyright © 2012-2013 AbarcaRodriguez.com