• Ir al contenido
  • Ir a la navegación
  • Ir al buscador
 
Infoudo
ING English
Directorio WAP para móvil, Tablet, iPhone o Smartphone

Centro de Noticias de la Universidad de Oriente

Categorías

 

Inicio  |  Contacto  |  Posts  |  TIENDA PUBLISHOP  |  Sobre nosotros  |  Registro y Planes  |  Pagos  |  Donaciones

Ver Código QR de esta página

Campaña #AyudemosaYuli  |  Campaña #AyudemosaStephany.  |  ¿Interesado(a) en cursos y resolución de ejercicios de materias prácticas? Para más información, contáctenos por: Teléfono: +58 (412) - 8226575. WhatsApp y Telegram: +58 (426) - 6836955 o escriba al correo: [email protected]. Únete al grupo: SISTEMAS (UDOMO).

[»] **Musica para tu celular

WEB TRANSLATOR

LINK for English Language

Use this link for translate into English


+ Buscar en InfoUDO

 

Pizarra interactiva multiusuario

Tweet
 

domingo julio 10, 2016

25 - Pizarra interactiva multiusuario


El último ejemplo que implementaré y utilizará JSON para la comunicación entre el cliente y el servidor será una "pizarra interactiva multiusuario", básicamente desarrollaremos una aplicación que muestre un tablero con letras que se puedan mover con el mouse. Lo interesante será que cada un cierto tiempo nos comunicaremos con el servidor e informaremos las letras que se han desplazado dentro de la ventana, esto permitirá que cualquier otro usuario que esté ejecutando en ese momento la misma página verá el desplazamiento que efectuó otra persona.

Para probar si realmente funciona esta característica podemos ejecutar el "problema resuelto" utilizando el FireFox y el Chrome. Podremos observar como se sincronizan las posiciones de las letras dentro de la ventana (si un usuario mueve una letra hacia la derecha, luego de algunos segundos todos los otros usuarios verán reflejado el cambio en sus navegadores.

Veamos los distintos archivos que intervienen (pagina1.html):

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Problema</title>
  <script src="funciones.js"></script>
</head>
<body style="background:#eee">
  <div><strong>Puede desplazar las letras con el mouse para escribir palabras que serán vistas por otros usuarios que visiten la página en este momento o más tarde.</strong></div>
  <div id="letras"></div>
</body>
</html>

Este archivo no tiene nada de especial toda la complejidad se encuentra en el archivo funciones.js que lo incorporamos con la siguiente línea:

  <script src="funciones.js"></script>

Ahora el archivo donde se encuentra toda la complejidad del código que se ejecuta en el cliente está en funciones.js:

addEventListener('load',inicializarEventos,false);

function desactivarSeleccion(e)
{
 return false
}


var conexion1;
function inicializarEventos()
{
  document.onmousedown=desactivarSeleccion;
  document.onmousemove=desactivarSeleccion;

  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  conexion1.open('GET','pagina1.php', true);
  conexion1.send();
}

var datos;
var datosNuevos;
var datosMovil;
var vectorLetras=new Array();
var reloj=null;
var relojGeneral=null;
var pasos=0;
function procesarEventos()
{
  if(conexion1.readyState == 4)
  {
    datos=JSON.parse(conexion1.responseText);
    crearLetras();
    relojGeneral=window.setInterval(actualizarCoordenadas, 5000);
  } 
}

function crearLetras()
{

  for(var f=0;f<datos.length;f++)
  {
    var ob=document.createElement('div');
    ob.style.left=datos[f].x+'px';
    ob.style.top=datos[f].y+'px';
    ob.style.width='17px';
    ob.style.height='17px';
    ob.style.background='#eee';
    ob.style.position='absolute';
    ob.style.fontSize='18px';
    ob.style.padding='3px';
    ob.style.cursor='pointer';
    ob.id='div'+f;
    ob.style.textAlign='center';
    var x=document.getElementById('letras');
    x.appendChild(ob);
    var ref=document.getElementById('div'+f);
    ref.innerHTML=datos[f].letra;
    vectorLetras[f]=new Recuadro(ob,datos[f].letra,f+1,datos[f].x,datos[f].y);
  }
}

function letrasMovidas(cod,x,y) {
  this.codigo=cod;
  this.x=x;
  this.y=y;
}

function actualizarCoordenadas()
{
  var vecletras=new Array();
  var con=0;
  for(var f=0;f<vectorLetras.length;f++)
  {
    if (datos[f].x!=vectorLetras[f].retornarX() ||
        datos[f].y!=vectorLetras[f].retornarY())
    {
      datos[f].x=vectorLetras[f].retornarX();
      datos[f].y=vectorLetras[f].retornarY();
      vecletras[con]=new letrasMovidas(datos[f].codigo,vectorLetras[f].retornarX(),vectorLetras[f].retornarY());
      con++;
    } 
 }
  var aleatorio=Math.random();
  var cadena=JSON.stringify(vecletras);
  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventosContinuos;
  conexion1.open('GET','pagina2.php?letras='+cadena+"&aleatorio="+aleatorio, true);
  conexion1.send();

}

function procesarEventosContinuos()
{
  if(conexion1.readyState == 4)
  {
    datosNuevos=JSON.parse(conexion1.responseText);
    datosMovil=JSON.parse(conexion1.responseText);

    var cambios=false;
    for(var f=0;f<datosNuevos.length;f++)
    {
       if (datosNuevos[f].x!=datos[f].x ||
           datosNuevos[f].y!=datos[f].y)
       {
           datosMovil[f].x=datos[f].x;
           datosMovil[f].y=datos[f].y;
           cambios=true;
       }
    } 
    if (cambios)
    {
      if (reloj==null)
        reloj=window.setInterval(moverLetras, 5);
     clearInterval(relojGeneral);
     pasos=20; 
    }
  } 
}

function moverLetras()
{
    var cambios=false;
    pasos--;
    for(var f=0;f<datosNuevos.length;f++)
    {
       if (datosNuevos[f].x!=datos[f].x ||
           datosNuevos[f].y!=datos[f].y)
       {
           cambios=true;
           var dx=Math.abs(datosNuevos[f].x-datos[f].x);
           var avancex;
           if ((datosNuevos[f].x-datos[f].x)>0)
             avancex=Math.round(dx/20);
           else
             avancex=Math.round(-dx/20);
           datosMovil[f].x=parseInt(datosMovil[f].x)+avancex;
          
           var dy=Math.abs(datosNuevos[f].y-datos[f].y);
           var avancey;
           if ((datosNuevos[f].y-datos[f].y)>0)
             avancey=Math.round(dy/20);
           else
             avancey=Math.round(-dy/20);
           datosMovil[f].y=parseInt(datosMovil[f].y)+avancey;

           cambios=true;
           if (pasos==0)
           {
             vectorLetras[f].fijarX(datosNuevos[f].x);
             vectorLetras[f].fijarY(datosNuevos[f].y);
           }
           else
           {
             vectorLetras[f].fijarX(datosMovil[f].x);
             vectorLetras[f].fijarY(datosMovil[f].y);
           }
       }
    } 
    if (pasos==0)
    {
      clearInterval(reloj);
      reloj=null;
      relojGeneral=window.setInterval(actualizarCoordenadas, 5000);
    }
}


//Drag and Drop

Recuadro=function(div)
{
    tX=0;
    tY=0;
    difX=0;
    difY=0;
    div.addEventListener('mousedown',inicioDrag,false);

    function coordenadaX(e)
    {
        return e.pageX;
    }

    function coordenadaY(e)
    {
        return e.pageY;
    }

    function inicioDrag(e) 
    {
      var eX=coordenadaX(e);
      var eY=coordenadaY(e);
      var oX=parseInt(div.style.left);
      var oY=parseInt(div.style.top);
      difX=oX-eX;
      difY=oY-eY;
      document.addEventListener('mousemove',drag,false);
      document.addEventListener('mouseup',soltar,false);

    }

    function drag(e) 
    { 
      tX=coordenadaY(e)+difY+'px';
      tY=coordenadaX(e)+difX+'px'
      div.style.top=tX; 
      div.style.left=tY; 
    }
  

    function soltar(e)
    { 
      document.removeEventListener('mousemove',drag,false);
      document.removeEventListener('mouseup',soltar,false);
      actualizarCoordenadas();
    }

    this.retornarX=function()
    {
      return parseInt(div.style.left);
    }
    
    this.retornarY=function()
    {
      return parseInt(div.style.top);
    }

    this.fijarX=function(xx)
    {
      div.style.left=xx+'px'; 
    }
    
    this.fijarY=function(yy)
    {
      div.style.top=yy+'px'; 
    }

}

La primera función que se ejecuta es inicializarEventos donde tenemos:

  document.onmousedown=desactivarSeleccion;
  document.onmousemove=desactivarSeleccion;

Con estas dos asignaciones desactivamos la posibilidad de seleccionar texto dentro de la página, esto es para que no se puedan seleccionar las letras.

Luego:

  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  conexion1.open('GET','pagina1.php', true);
  conexion1.send();

creamos un objeto de la clase crearXMLHttpRequest para recuperar la posición de cada letra. Veremos más adelante que tenemos una base de datos donde almacenamos las letras y las coordenadas de cada una.

La funcion procesarEventos:

function procesarEventos()
{
  if(conexion1.readyState == 4)
  {
    datos=JSON.parse(conexion1.responseText);
    crearLetras();
    relojGeneral=window.setInterval(actualizarCoordenadas, 5000);
  } 
}

cuando los datos se han enviado por completo del servidor procedemos a rescatarlos y generar un objeto literal en JavaScript llamando a la función parse del objeto JSON.
Llamamos seguidamente a la función crearLetras() y finalmente creamos un timer o alarma para que se dispare cada 5 segundos, veremos luego que tiene por objetivo recuperar las coordenadas de las letras almacenadas en el servidor:

    relojGeneral=window.setInterval(actualizarCoordenadas, 5000);

La función crearLetras:

function crearLetras()
{

  for(var f=0;f<datos.length;f++)
  {
    var ob=document.createElement('div');
    ob.style.left=datos[f].x+'px';
    ob.style.top=datos[f].y+'px';
    ob.style.width='17px';
    ob.style.height='17px';
    ob.style.background='#eee';
    ob.style.position='absolute';
    ob.style.fontSize='18px';
    ob.style.padding='3px';
    ob.style.cursor='pointer';
    ob.id='div'+f;
    ob.style.textAlign='center';
    var x=document.getElementById('letras');
    x.appendChild(ob);
    var ref=document.getElementById('div'+f);
    ref.innerHTML=datos[f].letra;
    vectorLetras[f]=new Recuadro(ob,datos[f].letra,f+1,datos[f].x,datos[f].y);
  }
}

crea elementos HTML de tipo "div" y los dispone en las coordenadas que acabamos de recuperar del servidor:

    ob.style.left=datos[f].x+'px';
    ob.style.top=datos[f].y+'px';

El ancho y el alto son fijos:

    ob.style.width='17px';
    ob.style.height='17px';

Definimos un id distinto a cada uno:

    ob.id='div'+f;

Por último lo añadimos a la página:

    ref.innerHTML=datos[f].letra;
    vectorLetras[f]=new Recuadro(ob,datos[f].letra,f+1,datos[f].x,datos[f].y);

y creamos un objeto de la clase Recuadro que nos permitirá desplazarlo con el mouse (esta clase se estudió en el curso de DHTML Ya.

La función actualizarCoordenadas se dispara cada 5 segundos o inmediatamente después que un usuario desplaza una letra en la pantalla:

function actualizarCoordenadas()
{
  var vecletras=new Array();
  var con=0;
  for(var f=0;f<vectorLetras.length;f++)
  {
    if (datos[f].x!=vectorLetras[f].retornarX() ||
        datos[f].y!=vectorLetras[f].retornarY())
    {
      datos[f].x=vectorLetras[f].retornarX();
      datos[f].y=vectorLetras[f].retornarY();
      vecletras[con]=new letrasMovidas(datos[f].codigo,vectorLetras[f].retornarX(),vectorLetras[f].retornarY());
      con++;
    } 
  }
  var aleatorio=Math.random();
  var cadena=JSON.stringify(vecletras);
  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventosContinuos;
  conexion1.open('GET','pagina2.php?letras='+cadena+"&aleatorio="+aleatorio, true);
  conexion1.send();

}

Dentro del for identificamos si alguna de las letras fue desplazada con el mouse:

    if (datos[f].x!=vectorLetras[f].retornarX() ||
        datos[f].y!=vectorLetras[f].retornarY())

En caso afirmativo actualizamos la estructura datos:

      datos[f].x=vectorLetras[f].retornarX();
      datos[f].y=vectorLetras[f].retornarY();

y además creamos una componente del a clase letrasMoviles:

     let[con]=new 
         letrasMovidas(datos[f].codigo,vectorLetras[f].retornarX(),vectorLetras[f].retornarY());

Este vector vecletras tiene los cambios efectuados en pantalla para ser eviados al servidor.

Fuera del for creamos un objeto de la clase XMLHttpRequest y procedemos a enviar los datos al servidor:

  conexion1.open('GET','pagina2.php?letras='+cadena+"&aleatorio="+aleatorio, true);

Recordemos que para convertir el vector de JavaScript a JSON lo hacemos:

  var cadena=JSON.stringify(vecletras);

La función procesarEventosContinuos:

function procesarEventosContinuos()
{
  if(conexion1.readyState == 4)
  {
    datosNuevos=JSON.parse(conexion1.responseText);
    datosMovil=JSON.parse(conexion1.responseText);

    var cambios=false;
    for(var f=0;f<datosNuevos.length;f++)
    {
       if (datosNuevos[f].x!=datos[f].x ||
           datosNuevos[f].y!=datos[f].y)
       {
           datosMovil[f].x=datos[f].x;
           datosMovil[f].y=datos[f].y;
           cambios=true;
       }
    } 
    if (cambios)
    {
      if (reloj==null)
        reloj=window.setInterval(moverLetras, 5);
     clearInterval(relojGeneral);
     pasos=20; 
    }
  } 
}

Recupera las coordenadas actuales de las letras que se encuentran registradas en el servidor:

    datosNuevos=JSON.parse(conexion1.responseText);
    datosMovil=JSON.parse(conexion1.responseText);

Utilizamos dos variables ya que una la utilizaremos para ir desplazando lentamente la letra por la pantalla.

Dentro de un for verificamos si hay coordenadas distintas entre las que administra nuestro navegador y las registradas en el servidor:

       if (datosNuevos[f].x!=datos[f].x ||
           datosNuevos[f].y!=datos[f].y)
       {

En caso de haber diferencias:

    if (cambios)
    {
      if (reloj==null)
        reloj=window.setInterval(moverLetras, 5);
     clearInterval(relojGeneral);
     pasos=20; 
    }

desactivamos el timer relojGeneral y activamos un timer para desplazar lentamente las letras entre la posición actual y la registrada en el servidor (la función moverLetras se dispara cada 5 milisegundos)

La función moverLetra:

function moverLetras()
{
    var cambios=false;
    pasos--;
    for(var f=0;f<datosNuevos.length;f++)
    {
       if (datosNuevos[f].x!=datos[f].x ||
           datosNuevos[f].y!=datos[f].y)
       {
           cambios=true;
           var dx=Math.abs(datosNuevos[f].x-datos[f].x);
           var avancex;
           if ((datosNuevos[f].x-datos[f].x)>0)
             avancex=Math.round(dx/20);
           else
             avancex=Math.round(-dx/20);
           datosMovil[f].x=parseInt(datosMovil[f].x)+avancex;
          
           var dy=Math.abs(datosNuevos[f].y-datos[f].y);
           var avancey;
           if ((datosNuevos[f].y-datos[f].y)>0)
             avancey=Math.round(dy/20);
           else
             avancey=Math.round(-dy/20);
           datosMovil[f].y=parseInt(datosMovil[f].y)+avancey;

           cambios=true;
           if (pasos==0)
           {
             vectorLetras[f].fijarX(datosNuevos[f].x);
             vectorLetras[f].fijarY(datosNuevos[f].y);
           }
           else
           {
             vectorLetras[f].fijarX(datosMovil[f].x);
             vectorLetras[f].fijarY(datosMovil[f].y);
           }
       }
    } 
    if (pasos==0)
    {
      clearInterval(reloj);
      reloj=null;
      relojGeneral=window.setInterval(actualizarCoordenadas, 5000);
    }
}

desplaza las letras que han cambiado de posición. Esta función se ejecuta 20 veces hasta que la variable global pasos almacene el valor 0.


Luego tenemos los dos archivos que se ejecutan en el servidor (pagina1.php):

<?php
$conexion=mysqli_connect("localhost","root","","bdajax") or
    die("Problemas con la conexión");
  
$registros=mysqli_query($conexion,"select letra,x,y,codigo from letras") or die("Problemas en el select".mysqli_error($conexion));

while ($reg=mysqli_fetch_array($registros))
{
  $vec[]=$reg;
}
mysqli_close($conexion);

$cad=json_encode ($vec);
echo $cad;
?>

Recupera de la tabla letras las coordenadas y letras propiamente dichas que serán mostradas en el servidor:

$registros=mysqli_query($conexion,"select letra,x,y,codigo from letras") or die("Problemas en el select".mysqli_error($conexion));

Guardamos los datos en un vector:

while ($reg=mysqli_fetch_array($registros))
{
  $vec[]=$reg;
}

Generamos un archivo con formato JSON para que se envíe al cliente:

$cad=json_encode ($vec);
echo $cad;

Por último nos queda el archivo (pagina2.php) que llamamos cada 5 segundos para indicarle las novedades dentro del navegador (si el usuario desplazó alguna letra) y recuperar las novedades registradas en el servidor:

<?php

$cad=json_decode(stripslashes($_REQUEST['letras']));

$conexion=mysqli_connect("localhost","root","","bdajax") or
    die("Problemas con la conexión");

  
$registros=mysqli_query($conexion,"select letra,x,y,codigo from letras") or die("Problemas en el select".mysqli_error($conexion));

for($f=0;$f<count($cad);$f++)
{
  mysqli_query($conexion,"update letras set  x=".$cad[$f]->x.",y=".$cad[$f]->y." where codigo=".$cad[$f]->codigo) or die("Problemas en el select".mysqli_error($conexion));
}

$registros=mysqli_query($conexion,"select x,y,codigo from letras") or die("Problemas en el select".mysqli_error($conexion));

while ($reg=mysqli_fetch_array($registros))
{
  $vec[]=$reg;
}
mysqli_close($conexion);
$cad=json_encode ($vec);
echo $cad;
?>

Primero recuperamos los datos enviados por el navegador y generamos un vector asociativo en PHP a partir de los datos que llegan en formato JSON:

$cad=json_decode(stripslashes($_REQUEST['letras']));

Modificamos las coordenadas de las letras:

$registros=mysqli_query($conexion,"select letra,x,y,codigo from letras") or die("Problemas en el select".mysqli_error($conexion));

for($f=0;$f<count($cad);$f++)
{
  mysqli_query($conexion,"update letras set  x=".$cad[$f]->x.",y=".$cad[$f]->y." where codigo=".$cad[$f]->codigo) or die("Problemas en el select".mysqli_error($conexion));
}

Por último recuperamos todas las letras y sus coordenadas y las enviamos nuevamente al cliente (navegador) que las solicitó:

$registros=mysqli_query($conexion,"select x,y,codigo from letras") or die("Problemas en el select".mysqli_error($conexion));

while ($reg=mysqli_fetch_array($registros))
{
  $vec[]=$reg;
}
mysqli_close($conexion);
$cad=json_encode ($vec);
echo $cad;


Problema resuelto.


Desarrollaremos una aplicación que muestre un tablero con letras que se puedan mover con el mouse. Lo interesante será que cada un cierto tiempo nos comunicaremos con el servidor e informaremos las letras que se han desplazado dentro de la ventana, esto permitirá que cualquier otro usuario que esté ejecutando en ese momento la misma página verá el desplazamiento que efectuó otra persona.

Para probar si realmente funciona esta característica ejecutarlo con el FireFox y el Chrome en forma simultánea. Podremos observar como se sincronizan las posiciones de las letras dentro de la ventana (si un usuario mueve una letra hacia la derecha, luego de algunos segundos todos los otros usuarios verán reflejado el cambio en sus navegadores)

Si lo ejecuta en dos instancias de navegadores debe quedar en claro que cada uno se comunica con el servidor en forma independiente para enviar y recuperar los cambios de posición.


pagina1.html



Ejecutar ejemplo



funciones.js




pagina1.php




pagina2.php


Retornar

— @INFOUDO.OFICIAL

— Síguenos en Facebook@INFOUDO.OFICIAL

Categorías: #Ajax, #


[0] Atrás | Directorio
« Inicio
Apps Infoudo
Apps Infoudo ¡Descarga el icono directo en el menú de tu equipo!
[»] Las mejores Apps para tu celular
[»] Imágenes Gratis


Comenta o lee lo que otros opinan

COMPÁRTELO:

Indica que te gusta y comparte

Me Gusta :)Facebook Tuiteame :)Twitter .WhatsApp .Telegram . LinkedIn

También te puede interesar:

Validación de la existencia de un nombre de usuario en forma asincrónica (AJAX)
De JSON a PHP (utilizando la función json_decode)
De JSON a JavaScript (utilizando utilizando la función parse)
De JavaScript a JSON (utilizando la función stringify del objeto JSON)
De PHP a JSON (utilizando la función json_encode)
Recuperar datos del servidor en formato JSON
Qué es JSON?
Encuenta con AJAX
Autocompletar un control de tipo text
Mostrar un tooltip con datos recuperados del servidor en forma asincrónica


« De JSON a PHP (utilizando la función json_decode)  |  Captcha en PHP »
 
Apps Infoudo
 
Buscador:
Powered by Google:


Web móvil
Imágenes
La Web

 

Síguenos por RSS


Puedes leerlos mediante el navegador Firefox, lectores de noticias en la computadora o el móvil o usando el servicio de Feedburner de Google para recibir las notificaciones por correo electrónico.
RSS - Suscribirse usando Feedburner de Google

email Recibir las nuevas publicaciones de Infoudo por email

Atom


»Ir a URL
.....
Registra Gratis Tu Negocio
....
Sugerir un nuevo sitio WAP

...
¡Bloguea Ya!

..
Registro de Profesionales(Abogados, escritores, doctores, licenciados, ingenieros, etc.)
.
Soporte

Síguenos en las redes sociales

Síguenos en Facebook facebook.com/INFOUDO.OFICIAL Síguenos en Twitter @infoudomon Síguenos en Instagram @infoudooficial Síguenos en Telegram t.me/Infoudooficial
Síguenos en Facebook facebook.com/tuinfou Síguenos en Twitter @infoudomonagas
Síguenos en WhatsApp INFO UDO Síguenos en YouTube youtube.com/channel/UCuicPxpqv3C0p1qwaO1XSSQ
Síguenos en Facebook facebook.com/SergioAlemanFans Síguenos en Twitter @SergioAleman1 Síguenos en Instagram @sergioalemanfans
Síguenos en WhatsApp wa.me/qr/Y7Q232VLZPR5O1 Síguenos en Tiktok @sergioalemanoficial Síguenos en Tiktok @sergioalemanfans
Síguenos en Telegram t.me/SergioAlemanOficial Síguenos en YouTube youtube.com/channel/UCqcLSYCKx9pamla68nFMDkw
Síguenos en Facebook facebook.com/boludooficial Síguenos en Twitter @bolUDOoficial Síguenos en Instagram @boludooficial Síguenos en Telegram t.me/Boludooficial
Síguenos en WhatsApp BolUDOoficial Síguenos en YouTube youtube.com/channel/UCJDooTJmROzAkBcbRrryvGA

Mis cuentas sociales

FB
Twitter
Pinterest
Instagram
Otras

Móvil: (0426 683 6955) - E-mail: [email protected] - [email protected] - WhatsApp: +58 (0426) 683.69.55


Copyscape
Volver arriba

Protocolo  |  Mapa del Sitio  |  Report Abuse - DMCA  |  Términos y Condiciones  |  Ayuda  |  Privacidad de Datos  |  Política de Cookies  |  Reportar un bug  |  Licencia: CC BY-NC-ND 3.0

Copyright ©2023 Infoudo. Todos los derechos reservados. Diseñado y Desarrollado por Sergio Alemán Mi perfil en GitHub


SUBIR