Contenido

jDigiClock, Reloj HTC Hero con jQuery

15 feb

+ 18

jDigiClock es un plugin jQuery que nos permite conseguir un reloj, inspirado en el HTC Hero, e integrarlo directamente en cualquier página web.

jdigiclock
(Ver Imagen)

Modo de empleo

Como todo plugin jQuery debemos cargar los ficheros Javascript necesarios.

<link rel="stylesheet" type="text/css" href="css/jquery.jdigiclock.css" />
<script type="text/javascript" src="lib/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="lib/jquery.jdigiclock.js"></script>

Una vez cargados ya podemos crear nuestro reloj llamando al plugin indicando el ID del elemento HTML contenedor y especificando una serie de parámetros de configuración.

// HTML
<div id="digiclock"></div>

// Javascript
<script type="text/javascript">
     $(document).ready(function() {
        $('#digiclock').jdigiclock({
            // Aquí la configuración
        });
    });
</script>

Configuración

Disponemos de una serie de parámetros para personalizar nuestro reloj:

  • clockImagesPath: Directorio de imágenes del Reloj
  • weatherImagesPath: Directorio de imágenes del tiempo
  • am_pm: Booleano para especificar AM/PM
  • weatherLocationCode: Código de tu cuidad para el tiempo (Base de datos: WeatherLocationDatabase.txt).
  • weatherMetric: Medición de la temperatura (C/F)
  • weatherUpdate: Tiempo de actualización del tiempo

Actualización (13:02):

Cane nos explica en los comentarios que el aspecto es de HTC Sense, el interface desarrollado por HTC para dispositivos Android, Windows Mobile, …

  • Buenas, simplemente un apunte sin importancia, estaría inspirado en HTC Sense, que es la interfaz que le pone HTC a la mayoría de sus terminales, ya sean Android, WM, etc.

    Saludos!

  • Solo funciona en php 5. Lo he probado en la última web que tengo todavia con el 4 (vergüenza me da ya decirlo xD) y he tenido que cambiar el archivo proxy.php para leer el xml de accuweather.

    Tambien he tenido que editar el plugin en si y el css porque las rutas de algunas imágenes no se pueden cambiar en la configuración.

    Los datos del tiempo llegan en inglés porque el widget de accuweather que utiliza no permite otra cosa. Solo se pueden cambiar los nombres de los dias y los meses editando el plugin y en las primeras lineas poner esto

    regional['en'] = {
                    monthNames: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
                    dayNames: ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab']
                }

    El autor debería corregir estas cosillas, porque por lo demás funciona perfectamente.

    Salu2

    • @TeLiX: Podrías compartir el plugin corregido?

    • @Horacio:
      En el proxy.php pon esto tal cual

      
      <?php
      
      $location = $_GET['location'];
      $metric = (int)$_GET['metric'];
      
      $url = 'http://rainmeter.accu-weather.com/widget/rainmeter/weather-data.asp?location=' . $location . '&metric=' . $metric;
      
      $ch = curl_init();
      $timeout = 0;
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
      $file_contents = curl_exec($ch);
      curl_close($ch);
      
      function GetXMLTree ($xmldata)
      {
      	// we want to know if an error occurs
      	ini_set ('track_errors', '1');
      
      	$xmlreaderror = false;
      
      	$parser = xml_parser_create ('ISO-8859-1');
      	xml_parser_set_option ($parser, XML_OPTION_SKIP_WHITE, 1);
      	xml_parser_set_option ($parser, XML_OPTION_CASE_FOLDING, 0);
      	if (!xml_parse_into_struct ($parser, $xmldata, $vals, $index)) {
      		$xmlreaderror = true;
      		echo "error";
      	}
      	xml_parser_free ($parser);
      
      	if (!$xmlreaderror) {
      		$result = array ();
      		$i = 0;
      		if (isset ($vals [$i]['attributes']))
      			foreach (array_keys ($vals [$i]['attributes']) as $attkey)
      			$attributes [$attkey] = $vals [$i]['attributes'][$attkey];
      
      		$result [$vals [$i]['tag']] = array_merge ($attributes, GetChildren ($vals, $i, 'open'));
      	}
      
      	ini_set ('track_errors', '0');
      	return $result;
      }
      
      function GetChildren ($vals, &$i, $type)
      {
      	if ($type == 'complete') {
      		if (isset ($vals [$i]['value']))
      			return ($vals [$i]['value']);
      		else
      			return '';
      	}
      
      	$children = array (); // Contains node data
      
      	/* Loop through children */
      	while ($vals [++$i]['type'] != 'close') {
      		$type = $vals [$i]['type'];
      		// first check if we already have one and need to create an array
      		if (isset ($children [$vals [$i]['tag']])) {
      			if (is_array ($children [$vals [$i]['tag']])) {
      				$temp = array_keys ($children [$vals [$i]['tag']]);
      				// there is one of these things already and it is itself an array
      				if (is_string ($temp [0])) {
      					$a = $children [$vals [$i]['tag']];
      					unset ($children [$vals [$i]['tag']]);
      					$children [$vals [$i]['tag']][0] = $a;
      				}
      			} else {
      				$a = $children [$vals [$i]['tag']];
      				unset ($children [$vals [$i]['tag']]);
      				$children [$vals [$i]['tag']][0] = $a;
      			}
      
      			$children [$vals [$i]['tag']][] = GetChildren ($vals, $i, $type);
      		} else
      			$children [$vals [$i]['tag']] = GetChildren ($vals, $i, $type);
      		// I don't think I need attributes but this is how I would do them:
      		if (isset ($vals [$i]['attributes'])) {
      			$attributes = array ();
      			foreach (array_keys ($vals [$i]['attributes']) as $attkey)
      			$attributes [$attkey] = $vals [$i]['attributes'][$attkey];
      			// now check: do we already have an array or a value?
      			if (isset ($children [$vals [$i]['tag']])) {
      				// case where there is an attribute but no value, a complete with an attribute in other words
      				if ($children [$vals [$i]['tag']] == '') {
      					unset ($children [$vals [$i]['tag']]);
      					$children [$vals [$i]['tag']] = $attributes;
      				}
      				// case where there is an array of identical items with attributes
      				elseif (is_array ($children [$vals [$i]['tag']])) {
      					$index = count ($children [$vals [$i]['tag']]) - 1;
      					// probably also have to check here whether the individual item is also an array or not or what... all a bit messy
      					if ($children [$vals [$i]['tag']][$index] == '') {
      						unset ($children [$vals [$i]['tag']][$index]);
      						$children [$vals [$i]['tag']][$index] = $attributes;
      					}
      					$children [$vals [$i]['tag']][$index] = array_merge ($children [$vals [$i]['tag']][$index], $attributes);
      				} else {
      					$value = $children [$vals [$i]['tag']];
      					unset ($children [$vals [$i]['tag']]);
      					$children [$vals [$i]['tag']]['value'] = $value;
      					$children [$vals [$i]['tag']] = array_merge ($children [$vals [$i]['tag']], $attributes);
      				}
      			} else
      				$children [$vals [$i]['tag']] = $attributes;
      		}
      	}
      
      	return $children;
      }
      
      
      $xml = GetXMLTree($file_contents);
      $xml=$xml["adc_database"];
      $weather['city']            = (string)$xml["local"]["city"];
      $weather['curr_temp']       = (int)$xml["currentconditions"]["temperature"];
      $weather['curr_text']       = (string)$xml["currentconditions"]["weathertext"];
      $weather['curr_icon']       = (int)$xml["currentconditions"]["weathericon"];
      
      // forecast
      $day = count($xml["forecast"]["day"]);
      for ($i = 0; $i < $day; $i++) {
          $weather['forecast'][$i]['day_date']       = (string)$xml["forecast"]["day"][$i]["obsdate"];
          $weather['forecast'][$i]['day_text']       = (string)$xml["forecast"]["day"][$i]["daytime"]["txtshort"];
          $weather['forecast'][$i]['day_icon']       = (int)$xml["forecast"]["day"][$i]["daytime"]["weathericon"];
          $weather['forecast'][$i]['day_htemp']      = (int)$xml["forecast"]["day"][$i]["daytime"]["hightemperature"];
          $weather['forecast'][$i]['day_ltemp']      = (int)$xml["forecast"]["day"][$i]["daytime"]["lowtemperature"];
      }
      
      
      function json_encode($a=false)
        {
          if (is_null($a)) return 'null';
          if ($a === false) return 'false';
          if ($a === true) return 'true';
          if (is_scalar($a))
          {
            if (is_float($a))
            {
              // Always use "." for floats.
              return floatval(str_replace(",", ".", strval($a)));
            }
      
            if (is_string($a))
            {
              static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
              return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"';
            }
            else
              return $a;
          }
          $isList = true;
          for ($i = 0, reset($a); $i  $v) $result[] = json_encode($k).':'.json_encode($v);
            return '{' . join(',', $result) . '}';
          }
        }
      
      echo json_encode($weather);
      ?>
      

      Simplemente cogí un par de funciones que encontré por ahí y que hacen mas o menos lo mismo que simplexml y json_encode para php5

      En el js pon lo que puse arriba para cambiar el idioma (o si quieres tener ingles y español deberias añadirlo detras del inglés, cambiar el ‘en’ por ‘es’ y hacer la llamada con el idioma que quieras)

      Edita las lineas 55, 56, 289, 299, 308 y 314 para poner la ruta de tus imagenes y en el css las otras 3 rutas que hay para las imagenes.

      Espero que te sirva

    • Muchas gracias por la aportación, pero lo he probado y me da un error en la línea 53, justo en el último for, parece que sobra una llave y algo más.
      ¿Me lo puedes confirmar?
      Gracias

    • @Emi:
      puede ser que al pegar el codigo aqui se haya perdido algo
      ¿que error te da? no creo que sea muy dificil de corregir…

    • @TeLiX:
      Gracias, ya lo veo, linea 153, error sintaxis, llave y variable $k.

  • Muy bueno Andres, la verdad que es sorprendente lo que se puede llegar con Jquery.

  • Estaría genial que Android aceptará por defecto las herramientas web (XHTML, CSS, js) porque esta integración estaría bien.

    La gente de Palm Os, podría utilizarlo en teoría.

  • y el enlace para descargar el plugin?no lo veo en la pagina, perdon

  • Hola.
    Lo he probado en mi web y funciona, pero… hay alguna forma de reducir el tamaño para que quepa en una barra lateral de unos 250px?

    Gracias ;)

  • Hola

    Yo también estoy interesado en reducir el tamaño del reloj para que entre en una barra lateral. Lo que hice fue ir reduciendo las medidas del css a por ejemplo un 50% pero no funciona del todo ya que la animación queda mal.

    Alguna idea de cómo hacer y que quede bien.

    Gracias

  • Hola de nuevo

    Logré reducir el tamaño del reloj. Si quieren ver como queda lo, tengo en mi web (http://www.panuweb.com.ar), en la sidebar. Aquellos que quieran una copia del código pasen por mi web y en la sección contacto me lo piden a través del formulario de contacto así les mando un .zip con las imágenes reducidas por correo.

    Tambien modifique el proxy.php para usar una base de datos de Argentina así puedo tener el pronostico de mi ciudad.

    Saludos

  • Consulta, quisiera tener este diseño de reloj en mi computadora, no en mi web, es posible? Gracias.

  • queria consultar lo siguiente, lo subi en un sitio de prueba y me esta funcionando correctamente, pero solo el reloj! necesito mas que nada el estado del clima. configure en el js los datos de mi ciudad (weatherLocationCode: ‘SAM|AR|AR013|MENDOZA’,) al parecer puede ser el archivo proxy.php el que esta molestando, ya q siguiendo los paso lo puse en una carpeta /php/ pero no esta cargando el clima. Si alguien me puede decir en donde hay que ubicarlo lo agradeceré.

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.