Siguiendo con los experimentos con HTML, Canvas y JavaScript, hoy les traigo un pequeño experimento que permite crear un punto luminoso con JavaScript y Canvas.
A lo largo del tiempo hemos visto varios experimentos empleando JavaScript y Canvas, además de la inmensa cantidad de recursos que existen en Internet que emplean el Canvas y JavaScript como tecnologías fundamentales:
- EL SECRETO DE LAS ANIMACIONES EN JAVASCRIPT (REQUESTANIMATIONFRAME())
- ¿CÓMO CREAR UN EFECTO DE ONDA CON CANVAS Y JAVASCRIPT?
- DIBUJANDO FORMAS GEOMÉTRICAS CON CANVAS EN ANDROID
- ¿CÓMO OBTENER IMÁGENES EN ESCALA DE GRISES CON SOLO HTML5?
- ¿CÓMO OBTENER POR SEPARADO EL CANAL RGB DE UNA IMAGEN CON HTML5?
- RECORTES DE IMÁGENES CON HTML5 Y JQUERY
Creando un punto luminoso (JavaScript)
Sin perder tiempo les presento la totalidad del JavaScript que iremos analizando poco a poco en la siguiente sección:
var _w = 800;
var _h = 400;
var circle;
var c = document.getElementById('canv');
var $ = c.getContext('2d');
$.fillRect(0, 0, c.width, c.height);
var set = function () {
circle = new Circle(100, 100, 15);
point();
}
var point = function () {
var id = $.getImageData(0, 0, _w, _h);
var pxl = id.data;
for (var x = 0; x < _w; x++) {
for (var y = 0; y < _h; y++) {
var dens = circle.dim / dist(x, y, circle.cx, circle.cy);
var idx = x * _w * 4 + y * 4;
pxl[idx] = dens * 70;
pxl[idx + 1] = (dens * 70);
pxl[idx + 2] = (dens * 70) * 0.55;
pxl[idx + 3] = 255;
}
}
$.putImageData(id, 0, 0);
}
var Circle = function (_x, _y, _dim) {
this.cx = _x;
this.cy = _y;
this.dim = _dim;
};
var dist = function (x1, y1, x2, y2) {
var x = x1 - x2;
var y = y1 - y2;
return Math.sqrt(x * x + y * y);
}
set();
Como podrás imaginar, el HTML es extremadamente simple y consta únicamente de un elemento canvas
.
Analizando el JavaScript anterior
Primero declaramos unas variables, entre ellas la que permite acceder al elemento canvas
y su contexto para poder manipularlo:
var _w = 800;
var _h = 400;
var circle;
var c = document.getElementById('canv');
var $ = c.getContext('2d');
$.fillRect(0, 0, c.width, c.height);
También creamos una función de expresión circle
la cual especifica la posición (X y Y) y las dimensiones del círculo:
var Circle = function (_x, _y, _dim) {
this.cx = _x;
this.cy = _y;
this.dim = _dim;
};
La función de expresión simplemente calcula la distancia entre dos puntos:
var dist = function (x1, y1, x2, y2) {
var x = x1 - x2;
var y = y1 - y2;
return Math.sqrt(x * x + y * y);
}
El punto central
La función de expresión point
es el punto central o corazón de nuestro experimento JavaScript; esta función es la que pinta en el elemento canvas
y varía dicho color según la distancia que existe entre cada uno de los puntos (pixeles) que conforman nuestro lienzo o Canvas y el círculo definido a principio del código JavaScript, de esta forma creamos un punto luminoso:
var dens = circle.dim / dist(x, y, circle.cx, circle.cy);
Un detalle interesante el cual es el "truquillo" de este experimento es que mientras más cercanos sean los puntos del Canvas al círculo definido -en un inicio el código- menor será la distancia (obviamente -.-) y por lo tanto el cálculo de la distancia entre dos puntos será más pequeño y la división daría un valor mayor -un color más claro-.
En lo que al cálculo de distancias en una circunferencia, daría puntos con colores iguales o parecidos dando el efecto deseado:
Variando el color del punto luminoso
Las multiplicaciones por valores constantes sirven para variar el color, pruebas distintos valores y verás cambios de colores.
Calculando la posición a pintar
El cálculo de la variable idx
es para recorrer un arreglo de una dimensión a partir de los contadores (x
yy
) de una matriz, esto se debe a que la función getImageData
devuelve un array de una dimensión y no una matriz como podríamos esperar.
Se multiplica por cuatro debido a que hay que agregar los canales RGBA los cuales son 4 y se suman al total de la matriz; si ejecutas el siguiente comando:
id.data.length
Veras que retorna -para nuestro experimento- 1280000
; es decir la longitud de la data es calculada como:
AC * LC * TRGBA
En donde:
- AC = Ancho del Canvas.
- LC = Largo del Canvas.
- TRGBA = Tamaño del canal RGBA (4).
Que en nuestro experimento viene siendo:
800 * 400 * 4 = 1280000
Pitando en el Canvas el punto luminoso
Finalmente pintamos el color calculado a través de la distancia entre dos puntos para cada canal RGBA:
pxl[idx] = dens * 70;
pxl[idx + 1] = (dens * 70);
pxl[idx + 2] = (dens * 70) * 0.55;
pxl[idx + 3] = 255;
Y esto es todo; de nuevo les dejo el enlace del experimento original: CodePen: Chronic Fusion.
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter