8.11.14

Wiris en Guadalinex Edu 2013

Hoy el asunto de mi blog, "co-financiado" por la publicidad de Google (no voy a decir lo que hay que hacer si te resulta útil el artículo, porque es evidente), es Wiris.

Wiris es un recurso educativo muy utilizado por profesores de matemáticas y, si has intentado utilizarlo en Guadalinex 2013, te habrás encontrado que no funciona o peor, que aparece una pantalla como la siguiente:




Pero tranquilidad en las masas, este es un problema que por suerte puede ser solucionado. Los pasos para solucionarlo de forma resumida son:

  1. Descargar la última versión de Java (del JRE – Java Runtime Environment) de la página de java.com. En este ejemplo se usa la versión para Linux (i586) que va comprimida en tar.gz. Hablado claro, la que pone solo "Linux" y nada más en la página de descargas.

  2. Descomprimirlo en una carpeta local. Para este ejemplo vamos a imaginar que se descomprime en la carpeta principal del usuario "usuario" de Guadalinex (que sería "/home/usuario"). Al descomprimirlo generará una carpeta con toda la instalación de Java (algo parecido a "/home/usuario/jdk-8u20-linux-i586"), pero para facilitar todo el ejemplo vamos a cambiarle el nombre a dicha carpeta a algo más fácil, como por ejemplo: "/home/usuario/java".
  3. Poner el camino a la carpeta donde están los binarios de Java como parte de la variable de entorno PATH, modificando el archivo de perfil “.profile”. Esto se hace simplemente para que se pueda ejecutar la nueva versión de java en tu sesión de usuario. En nuestro ejemplo el archivo ".profile" estaría en "/home/usuario/.profile". Para ello, con el explorador de archivos dirígete a la carpeta personal del usuario (Lugares > Carpeta Personal). En dicha carpeta hay un montón de archivos ocultos que puedes ver simplemente pulsando la combinación de teclas "Ctrl+H" (puedes volver a ocultarlos pulsando de nuevo Ctrl+H). Busca el archivo ".profile" y edítalo con un editor de texto plano como "gedit". Hay que añadir lo siguiente (para este caso concreto):

    Si has decidido hacer la instalación de Java en una carpeta diferente a "/home/usuario/java" entonces en vez de "java" tendrás que poner el nombre o camino a la carpeta donde has realizado la instalación.
  4. Instalar el plugin de java applet para el navegador Firefox. Para ello tienes que crear un enlace simbólico al archivo “libnpjp2.so” situado en la carpeta “lib/i386” de nuestra instalación de Java (“/home/usuario/java/lib/i386/libnpjp2.so” en nuestro caso) en la carpeta “.firefox/plugins” (que en nuestro caso sería “/home/usuario/.firefox/plugins”). Si no existe la carpeta “plugins” en la carpeta ".firefox" habrá que crearla.
    Y si todo esto te suena a chino, puedes hacerlo solo usando solo ventanitas, siguiendo los siguientes pasos:
    • Ve a la carpeta “lib/i386” de tu instalación de java y encima del archivo “libnpjp2.so” le das al botón derecho del ratón y seleccionas la opción de “crear enlace”.
    • La operación anterior creará un archivo llamado (más o menos) “Enlace hacia libnpjp2.so” en la misma carpeta “lib/i386” de la instalación de Java.
    • Mueve el archivo “Enlace hacia libnpjp2.so” a la carpeta “.firefox/plugins” (si no existe la carpeta plugins, tendrás que crearla). Y después cámbiale el nombre al archivo “Enlace hacia libnpjp2.so” y déjalo en solo “libnpjp2.so” (es opcional, pero queda mejor así).
  5. Reiniciar la sesión de usuario.
Haciendo todos estos pasos hasta aquí, ya no hará crash firefox al intentar cargar Wiris. Pero todavía, en algunas circunstancias, no funcionará dado que java bloquea por seguridad algunas ubicaciones no confiables para los applets. Este es el caso de los centros que tienen instalado Wiris en el servidor de contenidos (“http://c0:8180/wiris”) o de quienes ejecutan wiris de algunos servidores de la consejería de educación de la Junta de Andalucía. En estos casos, al intentar acceder te saldrá una ventana como esta:

Para solucionar este punto hay que añadir la “Ubicación” ("http://c0:8180" en la imagen anterior) como una ubicación segura para java, siguiendo los siguientes pasos: 

  1. Ejecutar el “ControlPanel” de Java, situado en la carpeta “bin” dentro de nuestra instalación de java (“/home/usuario/java/bin/ControlPanel” en nuestro caso).
  2. Una vez en el ControlPanel, vamos a la pestaña de “seguridad”. Dentro de la pestaña de "seguridad" hacemos click en el botón que pone “Editar lista de sitios”. Al pulsar el botón sale una ventana como la siguiente, donde deberemos meter la ubicación de Wiris:

    Después nos pedirá que confirmemos la operación, una vez realizado, habremos terminado.
Y esto es todo! Si te ha gustado o te ha sido útil, no dudes en compartirlo.




22.10.14

Desarrollo en papel de una figura 3D

Como este año me ha tocado dar Tecnologías a 2º de la E.S.O., he pensado que el alumnado puede hacer una figura en 3D, partiendo de un desarrollo en papel, y que a partir de ella, una vez que ya la puede manejar fácilmente, dibujara las vistas en el sistema diédrico (alzado, perfiles, etc.). De esta forma, simplemente girando la figura (izquierda, derecha, arriba, etc.) puede ver fácilmente con que corresponde cada una de las vistas que se dibujan en dicho sistema. El problema ha sido que al buscar por Internet no he encontrado muchos desarrollos en papel de figuras 3D, salvo de figuras geométricas puras (cubo, tetraedro, etc.), por lo que he decidido hacer yo una.

Versión SVG (InkScape) Versión PDF

13.6.14

Crear un editor de imágenes sencillo con HTML5, Javascript y Canvas

Desde hace un tiempo empecé mi proceso personal de actualización a Salva 3.1, enfocado principalmente a renovar/ampliar mis conocimientos en el desarrollo web. Y cuanto más profundizo, más alucino. Hoy en día es posible hacer cosas en la web impensables hace unos pocos años (realmente pocos). Por ejemplo, ya es posible crear una página web que sea un editor de imágenes, sin usar Flash, ni Java, ni ningún plug-in o extensión al navegador (siempre que tu navegador sea moderno y soporte Canvas).

Esto es algo que funciona bastante bien en Firefox y Chrome. Aquí os dejo una pequeña aplicación web que he realizado y que hace uso de todo esto (y algunas cosas más). Simplemente buscas una imagen de tu ordenador, tu navegador la carga y desde javascript, sin subir la imagen a ningún servidor, te permite cierta capacidad de edición, para después permitir descargar la imagen, todo con un código javascript relativamente sencillo y con una complejidad técnica muy baja (en comparación con la misma aplicación para sobremesa):
Imagina que en tu web pones un Canvas (elemento ampliamente permitido en los navegadores modernos):
<canvas id="canvas_ed" width="300" height="300"></canvas>
¿Podrías cargar una imagen del sistema cliente en dicho Canvas, procesarla y volver a guardarla en del cliente directamente sin pasar por ningún tipo de aplicación en servidor? Pues la respuesta es SI.

Para empezar, la imagen se cargaría a través de un elemento de formulario tipo “file”:
<input type="file" accept="image/*" id="img_from_pc" />
 Ahora, cuando se cambia la imagen en ese input, se genera un evento “change” que se puede capturar (lo pongo suponiendo que se usa jQuery):
$(function () {
$("#img_from_pc").change(function (event)
{
var fileList=this.files;
if (fileList.length&gt;0)
{
leerImagenDeArchivoYActualizarCanvas(fileList[0]);
}
});
});
Ahí se usa el atributo “files” del elemento input[type="file"], que contendrá una lista con las imágenes seleccionadas, realmente es un objeto FileList, y cada elemento de la lista será un objeto de tipo File, que permite conocer el nombre del archivo cargado.

Si el input[type="file"] tiene algún archivo se invoca la función “ leerImagenDeArchivoYActualizarCanvas(fileList[0])”, que es una función a medida, que actuará de la siguiente manera:
  • Carga la imagen del cliente en un elemento HTML tipo <IMG> (que podremos ocultar para que no se vea).
  • Una vez que la imagen se ha cargado en el <IMG>, se vuelca la imagen del <IMG> al <CANVAS>.
¿Cómo se carga la imagen del cliente en un elemento <IMG>? Supongamos que tenemos un IMG oculto tal que así:
<img id="image_output">
Pues la función anterior debería leer la imagen y ponerla como “src” de la imagen, así de simple:
function leerImagenDeArchivoYActualizarCanvas(file)
{
var img=$("image_output")[0];
var fr = new FileReader();
fr.onload = function(e) {
img.src = e.target.result;
};
fr.readAsDataURL(file);
}
Esto utilizaría FileReader, que es un prototipo de objeto del api de HTML que permite leer archivos. Invocamos el método “readAsDataURL” con un objeto tipo File para comenzar la descarga, y como dicha descarga es asíncrona, hay que indicar en el atributo “onload” de dicho objeto que función se ejecutará (closure en este caso) cuando se termine la carga. Lo que se hace en este caso en la función asignada a “onload” es simplemente poner el resultado de la descarga (que será una URL de tipo data con la imagen codificada en base64) como src de la imagen.

Bien, ya tenemos la imagen, pero como pasamos la imagen al canvas, pues así. Añadimos lo siguiente a la función anterior:
function leerImagenDeArchivoYActualizarCanvas(file)
{
var img=$("image_output")[0];
img.onload=function () {

var canvas=$("#canvas_ed")[0];
var canvas_ctx=canvas.getContext("2d");
canvas_ctx.drawImage(img,0,0,300,300);
};

var fr = new FileReader();
fr.onload = function(e) {

img.src = e.target.result;
};
fr.readAsDataURL(file);
}
De esta manera, cuando la imagen se haya cargado se invocará al handler “onload”, que será una función (closure en este caso) que pintará el canvas de la imagen. Dentro de dicha función se usan obviamente objetos del api de Canvas.

Una vez que ya hemos modificado la imagen a nuestro antojo, podemos poner por ejemplo un enlace para descargarla directamente al cliente (PC, móvil, etc.). Eso sí, hay que tener en cuenta que no todos los navegadores soportan esta opción (se puede detectar con Modernizr). Esto funciona mejor en Firefox que en Chrome, aunque funciona en los dos.

Supongamos que tenemos dos enlaces:
<a id=”donwlink” href="" onclick="descargar();return false;">Haz click aquí para descargar imagen</a>
<a id="downlink_hidden" href="" download="imagen.png"></a>
El segundo enlace se supone que está oculto y utiliza el atributo “download” para decir que es un archivo para descargar y no una imagen. Nuevamente, esa opción no funciona del todo en todos los navegadores, y habría que comprobarla con Modernizr por ejemplo. Al hacer clic en el primero se invoca la siguiente función:
function descargar() {
var canvas=$("canvas_ed")[0];
$("#downlink_hidden").attr("href",canvas.toDataURL("image/png"))[0].click();
}
Al ejecutar esta función lo que hacemos es poner como destino del segundo enlace, es decir como “href”, la imagen en base 64 como URL de tipo data. Hay que verificar, con Modernizr por ejemplo, que existe la función “toDataURL” en el canvas y a que formatos de imagen es posible exportar (“image/png”, “image/jpeg” o “image/webp”), porque no todos los navegadores tienen dicha función (por ejemplo, ni Safari ni Internet Explorer la tienen) o no soportan exportar a todos los formatos.

Y esto es todo.

26.5.14

Nueva versión de HippoCalc en camino

Hace tiempo que no publico nada en mi blog y bueno, quizás debería tomarme un poco más en serio esto del blog, pero no lo hago, y claro, mi blog da pena...

Hace tiempo que estoy trabajando en un pequeño proyecto, conforme me van quedando huecos libres. Es un proyecto pequeño y sencillo, pero el tiempo es el tiempo. Tengo una "calculadora IP educativa" en una web (hippocalc.net24.com) que he decidido actualizar y renovar. La verdad es que lo llevo bastante avanzado y aquí se puede ver un par de pantallazos de la nueva aplicación web (cuidado, todavía no la he subido):



La idea es tener una aplicación web que luego pueda fácilmente convertir a aplicación para el móvil (usando cordova u otro framework), que tenga un diseño adaptativo y que cambie de aspecto al cambiar el tamaño de la pantalla o al verlo en un dispositivo móvil (responsive web design) y que además pueda convertir fácilmente en un WebApp instalable a través de Chrome o Firefox en un PC. Como se puede ver en los pantallazos de arriba, sería la misma aplicación, pero básicamente donde se han usado CSS media queries y un javascript adaptado a cada tamaño (3 en realidad), respondiendo a las necesidades de cada vista.

Para realizarlo he usado mínimamente JQuery... y la idea inicial era no usarlo... aunque ahora que estoy aprendiendo a usar AngularJS me he dado cuenta de que realmente he hecho el tonto (o quizás no).


La verdad es que si todavía no lo he puesto online es porque me he currado unos scripts, que como son míos son maravillosos, para darle soporte multi-idioma desde javascript y PHP sin cambiar los datos de origen. Desde javascript y PHP se leen los mismos archivos de configuración de idioma, y se cargan las mismas traducciones y se genera una versión traducida de la parte "estática" del texto (la dinámica siempre se genera con javascript, aunque la "estática" también se cambia, o se puede cambiar, desde javascript).

Cuando me refiero a la parte "estática", me refiero por ejemplo a las etiquetas de los inputs en los formularios, que no cambian en función de los datos de entrada, y a otros textos que no se calculan en función de unos parámetros de entrada. Y el rollo de hacer esto ha sido porque los buscadores no ejecutan el JavaScript (bueno google si, pero es el único), y no se enteran del contenido dinámico.

Si lo hubiera echo solo en javascript, que es adecuado para pasar tu aplicación HTML5+Javascript a una app para un móvil (con Cordova o PhoneGap, por ejemplo), los buscadores, al ver la versión web y hacer "clic" en otro idioma, se encuentran un JavaScript, y no ven "nada" realmente en otro idioma. De esta forma, tal y como lo he hecho, a través de PHP se genera y cachea una versión del HTML con el texto "estático" en cada idioma, y se convierten los enlaces a enlaces navegables por un buscador (no se ejecuta javascript en ese caso), de tal manera que los buscadores "ven" que hay versiones en otros idiomas.

Y ahí estoy, con casi todo ya listo, y traduciendo del español al inglés... que claro, como no hacer la traducción y dejar algo que ya tengo hecho y funciona sin utilizar... y paradojicamente es donde estoy más atascado y oxidado :-P... pero me sirve de entrenamiento para el año que viene, que empiezo, si hay plazas, 4º de inglés en la EOI.