diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
commit | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (patch) | |
tree | 0dd8b084480983cf9f9680e8aedb92782a921b13 /files/es/web/guide | |
parent | 4b1a9203c547c019fc5398082ae19a3f3d4c3efe (diff) | |
download | translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.gz translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.bz2 translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.zip |
initial commit
Diffstat (limited to 'files/es/web/guide')
32 files changed, 5552 insertions, 0 deletions
diff --git a/files/es/web/guide/ajax/comunidad/index.html b/files/es/web/guide/ajax/comunidad/index.html new file mode 100644 index 0000000000..50a91de5a4 --- /dev/null +++ b/files/es/web/guide/ajax/comunidad/index.html @@ -0,0 +1,44 @@ +--- +title: Comunidad +slug: Web/Guide/AJAX/Comunidad +tags: + - AJAX + - Todas_las_Categorías +translation_of: Web/Guide/AJAX/Community +--- +<p> </p> +<p><br> + Si conoces alguna lista de correo, grupo de noticias, foro, o comunidad relacionada con AJAX que pueda ser de interés. Por favor, pon aquí un enlace.</p> +<h3 id="Mozilla" name="Mozilla">Mozilla</h3> +<ul> + <li>La comunidad Mozilla... en inglés</li> +</ul> +<p>{{ DiscussionList("dev-ajax", "mozilla.dev.ajax") }}</p> +<h3 id="Listas_de_correo" name="Listas_de_correo">Listas de correo</h3> +<ul> + <li> </li> +</ul> +<p> </p> +<h3 id="Foros" name="Foros">Foros</h3> +<ul> + <li><a class="external" href="http://www.forosdelweb.com/forumdisplay.php?f=77">AJAX</a> en + <i> + Foros del Web</i> + </li> +</ul> +<h3 id="Bit.C3.A1coras" name="Bit.C3.A1coras">Bitácoras</h3> +<ul> + <li> </li> +</ul> +<p> </p> +<h3 id="Wikis" name="Wikis">Wikis</h3> +<ul> + <li> </li> +</ul> +<p> </p> +<h3 id="Otros_Sitios" name="Otros_Sitios">Otros Sitios</h3> +<ul> + <li> </li> +</ul> +<p> </p> +<p><span class="comment">categorías</span></p> diff --git a/files/es/web/guide/ajax/index.html b/files/es/web/guide/ajax/index.html new file mode 100644 index 0000000000..25c1dba553 --- /dev/null +++ b/files/es/web/guide/ajax/index.html @@ -0,0 +1,90 @@ +--- +title: AJAX +slug: Web/Guide/AJAX +translation_of: Web/Guide/AJAX +--- +<p> </p> + +<div class="callout-box"><strong><a href="es/AJAX/Primeros_Pasos">Primeros Pasos</a></strong><br> +Una introducción a AJAX.</div> + +<p><strong>JavaScript Asíncrono + XML (AJAX)</strong> no es una tecnología por sí misma, es un término que describe un nuevo modo de utilizar conjuntamente varias tecnologías existentes. Esto incluye: <a href="es/HTML">HTML</a> o <a href="es/XHTML">XHTML</a>, <a href="es/CSS">CSS</a>, <a href="es/JavaScript">JavaScript</a>, <a href="es/DOM">DOM</a>, <a href="es/XML">XML</a>, <a href="es/XSLT">XSLT</a>, y lo más importante, el objeto <a href="es/XMLHttpRequest">XMLHttpRequest</a>. Cuando estas tecnologías se combinan en un modelo AJAX, es posible lograr aplicaciones web capaces de actualizarse continuamente sin tener que volver a cargar la página completa. Esto crea aplicaciones más rápidas y con mejor respuesta a las acciones del usuario.</p> + +<table class="topicpage-table"> + <tbody> + <tr> + <td> + <h4 id="Documentaci.C3.B3n" name="Documentaci.C3.B3n"><a href="/Special:Tags?tag=AJAX&language=es" title="Special:Tags?tag=AJAX&language=es">Documentación</a></h4> + + <dl> + <dt><a href="/es/AJAX/Primeros_Pasos" title="es/AJAX/Primeros_Pasos">Primeros pasos con AJAX</a></dt> + <dd><small>Este artículo te guiará por los conceptos básicos de AJAX y te proporcionará dos ejemplos prácticos para que empieces.</small></dd> + </dl> + + <dl> + <dt><a class="external" href="http://www.webreference.com/programming/ajax_tech/">Técnicas Ajax Alternativas</a></dt> + <dd><small>La mayoría de los artículos sobre Ajax se enfocaron en utilizar XMLHttp como el medio para llevar a cabo dicha comunicación, pero las técnicas Ajax no están limitadas solo a XMLHttp. Existen otros métodos más.</small></dd> + </dl> + + <dl> + <dt><a class="external" href="http://thinkcoderepeat.blogspot.com/2006/02/tutorial-de-ajax-con-php-y-json.html">Ajax con PHP, JSON y CSS</a></dt> + <dd><small>Con este tutorial puedes programar con AJAX utilizando PHP y JSON, un nuevo estándar más simple que XML. Programarás en AJAX, PHP y CSS de forma simple y natural.</small></dd> + </dl> + + <dl> + <dt><a class="external" href="http://webdev20.blogspot.com/2006/02/ajax-upload-file.html">Ajax Upload File</a></dt> + <dd><small>Artículo en el que se explica la carga de archivos de un formulario usando AJAX y PHP, además de otros ejemplos en los que se puede visualizar la barra de progreso de la carga.</small></dd> + </dl> + + <dl> + <dt><a class="external" href="http://www.baluart.net/articulo/346/edicion-in-situ-con-ajax.php">Creando formulario editables in situ</a></dt> + <dd><small>Breve tutorial que nos muestra como crear nuestros formularios editables in situ con AJAX, PHP y MySQL, al estilo Flickr.</small></dd> + </dl> + + <dl> + <dt><a class="external" href="http://thinkcoderepeat.blogspot.com/2006/08/arquitectura-cliente-servidor-con-ajax.html">Arquitectura Cliente Servidor con AJAX</a></dt> + <dd><small>Artículo avanzado que muestra un patrón de diseño para desarrollar con AJAX, haciendo el modelo de la aplicación como web-services, la interface (view) con HTML y el controlador (controller) en Javascript, para crear aplicaciones siguiendo el paradigma MVC. Herramientas: Prototype, JSON y CSS.</small></dd> + </dl> + + <p><span class="alllinks"><a href="/Special:Tags?tag=AJAX&language=es" title="Special:Tags?tag=AJAX&language=es">Ver todos</a></span></p> + </td> + <td> + <h4 id="Comunidad" name="Comunidad">Comunidad</h4> + + <ul> + <li><a class="external" href="http://groups.google.es/group/Ajax-es?lnk=sg&hl=es">Ajax-es</a>. Foro sobre AJAX.</li> + </ul> + + <ul> + <li>Foros sobre AJAX en la comunidad Mozilla en inglés:</li> + </ul> + + <p>{{ DiscussionList("dev-ajax", "mozilla.dev.ajax") }}</p> + + <p><span class="alllinks"><a href="es/AJAX/Comunidad">Ver todos</a></span></p> + + <h4 id="Herramientas" name="Herramientas">Herramientas</h4> + + <ul> + <li><a class="external" href="http://www.ajaxprojects.com">Toolkits y Frameworks</a></li> + <li><a class="external" href="http://www.getfirebug.com/">Firebug - Herramienta de Desarrollo Ajax/Web</a></li> + <li><a class="external" href="http://blog.monstuff.com/archives/000252.html">Herramienta de Depuración de AJAX</a></li> + <li><a class="external" href="http://www.osflash.org/doku.php?id=flashjs">Kit de Integración Flash/AJAX</a></li> + <li><a class="external" href="http://xkr.us/code/javascript/XHConn/">Una Simple Librería de Interfaz XMLHTTP</a></li> + </ul> + + <p><span class="alllinks"><a href="/Special:Tags?tag=AJAX:Herramientas&language=es" title="Special:Tags?tag=AJAX:Herramientas&language=es">Ver todos</a></span></p> + + <h4 id="Temas_relacionados" name="Temas_relacionados">Temas relacionados</h4> + + <dl> + <dd><a href="es/HTML">HTML</a> · <a href="es/XHTML">XHTML</a> · <a href="es/CSS">CSS</a> · <a href="es/DOM">DOM</a> · <a href="es/JavaScript">JavaScript</a> · <a href="es/XML">XML</a> · <a href="es/XMLHttpRequest">XMLHttpRequest</a> · <a href="es/XSLT">XSLT</a> · <a href="es/DHTML">DHTML</a></dd> + </dl> + </td> + </tr> + </tbody> +</table> + +<div class="noinclude"> </div> + +<p>{{ languages( { "ca": "ca/AJAX", "cs": "cs/AJAX", "en": "en/AJAX", "fr": "fr/AJAX", "it": "it/AJAX", "ja": "ja/AJAX", "ko": "ko/AJAX", "nl": "nl/AJAX", "pl": "pl/AJAX", "pt": "pt/AJAX", "ru": "ru/AJAX", "zh-cn": "cn/AJAX", "zh-tw": "zh_tw/AJAX" } ) }}</p> diff --git a/files/es/web/guide/ajax/primeros_pasos/index.html b/files/es/web/guide/ajax/primeros_pasos/index.html new file mode 100644 index 0000000000..ed2bbbc33f --- /dev/null +++ b/files/es/web/guide/ajax/primeros_pasos/index.html @@ -0,0 +1,231 @@ +--- +title: Primeros Pasos +slug: Web/Guide/AJAX/Primeros_Pasos +tags: + - AJAX + - API + - Avanzado + - Todas_las_Categorías + - XMLHttpRequest +translation_of: Web/Guide/AJAX/Getting_Started +--- +<p> </p> + +<p>Este artículo es una guía básica sobre AJAX e incluye dos ejemplos.</p> + +<h3 id=".C2.BFQu.C3.A9_es_AJAX.3F" name=".C2.BFQu.C3.A9_es_AJAX.3F">¿Qué es AJAX?</h3> + +<p>AJAX (JavaScript Asíncrono y XML) es un término nuevo para describir dos capacidades de los navegadores que han estado presentes por años, pero que habían sido ignoradas por muchos desarrolladores Web, hasta hace poco que surgieron aplicaciones como Gmail, Google suggest y Google Maps.</p> + +<p>Las dos capacidades en cuestión son:</p> + +<ul> + <li>La posibilidad de hacer peticiones al servidor sin tener que volver a cargar la página.</li> + <li>La posibilidad de analizar y trabajar con documentos XML.</li> +</ul> + +<h3 id="Primer_Paso_.E2.80.93_C.C3.B3mo_realizar_una_petici.C3.B3n_HTTP_al_servidor" name="Primer_Paso_.E2.80.93_C.C3.B3mo_realizar_una_petici.C3.B3n_HTTP_al_servidor">Primer Paso – Cómo realizar una petición HTTP al servidor</h3> + +<p>Para realizar una petición HTTP usando JavaScript, es necesario crear una instancia de una clase que provea esta funcionalidad. Esta clase fue inicialmente introducida en Internet Explorer como un objeto ActiveX, llamado <code>XMLHTTP</code>. Después Mozilla, Safari y otros navegadores lo siguieron, implementando una clase <code>XMLHttpRequest</code> que soportaba los métodos y las propiedades del objeto ActiveX original.</p> + +<p>Como resultado, para crear una instancia de la clase requerida que funcione en todos los navegadores, es necesario poner:</p> + +<pre>if (window.XMLHttpRequest) { // Mozilla, Safari, ... + http_request = new XMLHttpRequest(); +} else if (window.ActiveXObject) { // IE + http_request = new ActiveXObject("Microsoft.XMLHTTP"); +} +</pre> + +<p>(El código mostrado es una versión simplificada con fines ilustrativos. Para un ejemplo más realista ver el paso 3 de este artículo.)</p> + +<p>Algunas versiones de los navegadores Mozilla no funcionan correctamente si la respuesta del servidor no tiene la cabecera mime de tipo XML. En ese caso es posible usar un método extra que sobreescriba la cabecera enviada por el servidor, en caso que no sea <code>text/xml</code>.</p> + +<pre>http_request = new XMLHttpRequest(); +http_request.overrideMimeType('text/xml'); +</pre> + +<p>El próximo paso es decidir qué se hará después de recibir la respuesta del servidor a la petición enviada. A estas alturas sólo es necesario decirle al objeto HTTPrequest qué función de JavaScript se encargará de procesar la respuesta. Para esto se asigna la propiedad <code>onreadystatechange</code> del objeto al nombre de la función de JavaScript que se va a utilizar:</p> + +<p><code>http_request.onreadystatechange = nameOfTheFunction;</code></p> + +<p>Es importante notar que no hay paréntesis después del nombre de la función y no se pasa ningún parámetro. También es posible definir la función en ese momento, y poner en seguida las acciones que procesarán la respuesta:</p> + +<pre>http_request.onreadystatechange = function(){ + // procesar la respuesta +}; +</pre> + +<p>Después de especificar qué pasará al recibir la respuesta es necesario hacer la petición. Para esto se utilizan los métodos <code>open()</code> y <code>send()</code> de la clase HTTP request, como se muestra a continuación:</p> + +<pre>http_request.open('GET', 'http://www.example.org/algun.archivo', true); +http_request.send(); +</pre> + +<ul> + <li>El primer parámetro de la llamada a <code>open()</code> es el método HTTP request – GET, POST, HEAD o cualquier otro método que se quiera usar y sea aceptado por el servidor. El nombre del método se escribe en mayúsculas, sino algunos navegadores (como Firefox) podrían no procesar la petición. Para más información sobre los métodos HTTP request visitar <a class="external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">W3C specs</a></li> + <li>El segundo parámetro es el URL de la página que se esta pidiendo. Por medida de seguridad no es posible llamar páginas en dominios de terceras personas. Se debe saber el dominio exacto de todas las páginas o se obtendrá un error de 'permiso denegado' al llamar open(). Una falla común es acceder al sitio por domain.tld e intentar llamar las páginas como www.domain.tld.</li> + <li>El tercer parámetro establece si la petición es asíncrona. Si se define <code>TRUE</code>, la ejecución de la función de JavaScript continuará aún cuando la respuesta del servidor no haya llegado. Por esta capacidad es la A en AJAX.</li> +</ul> + +<p>El parámetro en el método <code>send()</code>puede ser cualquier información que se quiera enviar al servidor si se usa POST para la petición. La información se debe enviar en forma de cadena, por ejemplo:</p> + +<p><code>name=value&anothername=othervalue&so=on</code></p> + +<p>Si se quiere enviar información de esta forma, es necesario cambiar el tipo MIME de la petición usando la siguiente línea:</p> + +<pre>http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); +</pre> + +<p>De otro modo el servidor descartará la información.</p> + +<h3 id="Segundo_Paso_.E2.80.93_Procesando_la_respuesta_del_servidor" name="Segundo_Paso_.E2.80.93_Procesando_la_respuesta_del_servidor">Segundo Paso – Procesando la respuesta del servidor</h3> + +<p>Al enviar la petición HTTP es necesario indicar el nombre de la función JavaScript que procesará la respuesta.</p> + +<p><code>http_request.onreadystatechange = nameOfTheFunction;</code></p> + +<p>A continuación se verá lo que esta función realiza. En primer lugar necesita revisar el estado de la petición. Si el estado tiene el valor 4, significa que la respuesta completa del servidor ha sido recibida y es posible continuar procesándola.</p> + +<pre>if (http_request.readyState == 4) { + // todo va bien, respuesta recibida +} else { + // aun no esta listo +} +</pre> + +<p>La lista completa de valores para la propiedad <code>readyState</code> es:</p> + +<ul> + <li>0 (no inicializada)</li> + <li>1 (leyendo)</li> + <li>2 (leido)</li> + <li>3 (interactiva)</li> + <li>4 (completo)</li> +</ul> + +<p>(<a class="external" href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/readystate_1.asp">Source</a>)</p> + +<p>Ahora es necesario revisar el código de status de la respuesta HTTP. La lista completa de códigos aparece en el <a class="external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">sitio de la W3C</a>. Para el próposito de este artículo sólo es importante el código <code>200 OK</code>.</p> + +<pre>if (http_request.status == 200) { + // perfect! +} else { + // hubo algún problema con la petición, + // por ejemplo código de respuesta 404 (Archivo no encontrado) + // o 500 (Internal Server Error) +} +</pre> + +<p>Después de haber revisado el estado de la petición y el código de status de la respuesta, depende de uno hacer cualquier cosa con la información que el servidor ha entregado. Existen dos opciones para tener acceso a esa información:</p> + +<ul> + <li><code>http_request.responseText</code> – regresará la respuesta del servidor como una cadena de texto.</li> + <li><code>http_request.responseXML</code> – regresará la respuesta del servidor como un objeto <code>XMLDocument</code> que se puede recorrer usando las funciones de JavaScript DOM.</li> +</ul> + +<h3 id="Tercer_Paso_.E2.80.93_.22.C2.A1Ahora_todo_junto.21.22_-_Un_sencillo_ejemplo" name="Tercer_Paso_.E2.80.93_.22.C2.A1Ahora_todo_junto.21.22_-_Un_sencillo_ejemplo">Tercer Paso – "¡Ahora todo junto!" - Un sencillo ejemplo</h3> + +<p>En este ejemplo se utilizará todo lo que se ha visto para hacer una petición HTTP. Se pedirá un documento HTML llamado <code>test.html</code>, que contiene el texto "Esto es una prueba." y después usaremos la función <code>alert()</code> con el contenido del archivo <code>test.html</code> .</p> + +<pre><script type="text/javascript" language="javascript"> + + var http_request = false; + + function makeRequest(url) { + + http_request = false; + + if (window.XMLHttpRequest) { // Mozilla, Safari,... + http_request = new XMLHttpRequest(); + if (http_request.overrideMimeType) { + http_request.overrideMimeType('text/xml'); + // Ver nota sobre esta linea al final + } + } else if (window.ActiveXObject) { // IE + try { + http_request = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + http_request = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (e) {} + } + } + + if (!http_request) { + alert('Falla :( No es posible crear una instancia XMLHTTP'); + return false; + } + http_request.onreadystatechange = alertContents; + http_request.open('GET', url, true); + http_request.send(); + + } + + function alertContents() { + + if (http_request.readyState == 4) { + if (http_request.status == 200) { + alert(http_request.responseText); + } else { + alert('Hubo problemas con la petición.'); + } + } + + } +</script> +<span + style="cursor: pointer; text-decoration: underline" + onclick="makeRequest('test.html')"> + Hacer una petición +</span> +</pre> + +<p>En este ejemplo:</p> + +<ul> + <li>El usuario presiona el vínculo "Hacer una petición" en el navegador;</li> + <li>Esto llama la función <code>makeRequest()</code> que tiene como parámetro <code>test.html</code> que es un archivo HTML localizado en el mismo directorio;</li> + <li>La petición es realizada y después (<code>onreadystatechange</code>) la ejecución pasa a <code>alertContents()</code>;</li> + <li><code>alertContents()</code> verifica si la respuesta fue recibida y si es OK, si es así utiliza <code>alert()</code> con el contenido de <code>test.html</code>.</li> +</ul> + +<p>Puedes probar el ejemplo <a class="external" href="http://www.w3clubs.com/mozdev/httprequest_test.html">aquí</a> y puedes ver el archivo de prueba <a class="external" href="http://www.w3clubs.com/mozdev/test.html">aquí</a>.</p> + +<p><strong>Nota</strong>: La línea <code> http_request.overrideMimeType('text/xml');</code> arriba causaría problemas en la consola de Javascript de Firefox 1.5b, como esta descrito en <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=311724" rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=311724</a>, si la página llamada por XMLHttpRequest no es XML válido (por ejemplo, si es texto).</p> + +<p>Si se obtiene Syntax Error o Not Well Formed Error en el navegador, y no se está intentando cargar una página XML con XMLHttpRequest, se puede eliminar esa línea del código.</p> + +<h3 id="Cuarto_Paso_.E2.80.93_Trabajando_con_la_respuesta_XML" name="Cuarto_Paso_.E2.80.93_Trabajando_con_la_respuesta_XML">Cuarto Paso – Trabajando con la respuesta XML</h3> + +<p>En el ejemplo anterior se utilizo la propiedad <code>reponseText</code> del objeto pedido para mostrar el contenido de <code>test.html</code> una vez que la respuesta HTTP había sido recibida. En éste se utilizará la propiedad <code>responseXML</code>.</p> + +<p>Primero hay que crear un documento de XML válido. El documento (test.xml) contiene lo siguiente:</p> + +<pre><?xml version="1.0" ?> +<root> + Esto es una prueba. +</root> +</pre> + +<p>Para que funcione el script solo es necesario cambiar la línea de petición por:</p> + +<pre>... +onclick="makeRequest('test.xml')"> +... +</pre> + +<p>Y en <code>alertContents()</code> es necerario remplazar la línea donde aparece <code>alert(http_request.responseText);</code> por:</p> + +<pre>var xmldoc = http_request.responseXML; +var root_node = xmldoc.getElementsByTagName('root').item(0); +alert(root_node.firstChild.data); +</pre> + +<p>De esta manera se utiliza el objeto <code>XMLDocument</code> dado por <code>responseXML</code> y se usan métodos del DOM para acceder a la información contenida en el documento XML. El archivo <code>test.xml</code> se encuentra <a class="external" href="http://www.w3clubs.com/mozdev/test.xml">aquí</a> y el script actualizado está <a class="external" href="http://www.w3clubs.com/mozdev/httprequest_test_xml.html">aquí</a>.</p> + +<p>Para más información sobre los metodos del DOM, visita los documentos de la <a class="external" href="http://www.mozilla.org/docs/dom/">implementación del DOM de Mozilla</a>.</p> + +<div class="noinclude"> </div> + +<p>{{ languages( { "ca": "ca/AJAX/Primers_passos", "de": "de/AJAX/Getting_Started", "en": "en/AJAX/Getting_Started", "fr": "fr/AJAX/Premiers_pas", "it": "it/AJAX/Iniziare", "ja": "ja/AJAX/Getting_Started", "ko": "ko/AJAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Como_come\u00e7ar", "ru": "ru/AJAX/\u0421_\u0447\u0435\u0433\u043e_\u043d\u0430\u0447\u0430\u0442\u044c", "zh-cn": "cn/AJAX/\u5f00\u59cb", "zh-tw": "zh_tw/AJAX/\u4e0a\u624b\u7bc7" } ) }}</p> diff --git a/files/es/web/guide/api/camera/index.html b/files/es/web/guide/api/camera/index.html new file mode 100644 index 0000000000..e3d291bfc3 --- /dev/null +++ b/files/es/web/guide/api/camera/index.html @@ -0,0 +1,244 @@ +--- +title: Introducción a la API de Cámara +slug: Web/Guide/API/Camera +tags: + - DOM + - Intermedio + - Medios + - NecesitaActualización + - Referencia DOM Gecko + - Web API + - cámara +translation_of: Archive/B2G_OS/API/Camera_API/Introduction +--- +<p><span class="seoSummary">Mediante la <a class="link-https" href="https://wiki.mozilla.org/Platform/Features/Camera_API">API de Cámara</a>, es posible tomar fotografías con la cámara de su dispositivo y subirlas a una página web.</span> Esto se logra a través de un elemento <code>input</code> con los atributos <code>type="file"</code> y <code>accept</code> para declarar que el elemento acepta imágenes. El HTML se parece a esto:</p> + +<pre class="brush: html"><input type="file" id="take-picture" accept="image/*"> +</pre> + +<p>Cuando los usuarios eligen activar este elemento HTML, se les presenta la opción de seleccionar un fichero, donde la cámara del dispositivo es una de las opciones. Si seleccionan la cámara, se accede al modo de toma de fotografía. Tras realizar la fotografía, al usuario se le presenta la posibilidad de aceptarla o rechazarla. Si se acepta, es enviada al elemento <code><input type="file"></code> y se lanza su evento <code>onchange</code>.</p> + +<h2 id="Obtener_una_referencia_a_la_fotografía_tomada">Obtener una referencia a la fotografía tomada</h2> + +<p>Con la ayuda de la <a href="/en/Using_files_from_web_applications" title="en/Using_files_from_web_applications">API de Fichero</a> usted puede acceder a la fotografía tomada o el fichero elegido:</p> + +<pre class="brush: js">var takePicture = document.querySelector("#take-picture"); +takePicture.onchange = function (event) { + // Obtener una referencia a la fotografía tomada o fichero seleccionado + var files = event.target.files, + file; + if (files && files.length > 0) { + file = files[0]; + } +}; +</pre> + +<h2 id="Presentando_la_fotografía_en_la_página_web">Presentando la fotografía en la página web</h2> + +<p>Una vez que tiene una referencia a la fotografía tomada (ej.: fichero), puede entonces usar {{ domxref("window.URL.createObjectURL()") }} para crear una URL referenciando la fotografía y estableciéndola como <code>src</code> de una imagen:</p> + +<pre class="brush: js">// Referencia de la imagen +var showPicture = document.querySelector("#show-picture"); + +// Crear ObjectURL +var imgURL = window.URL.createObjectURL(file); + +// Establecer ObjectURL como img src +showPicture.src = imgURL; + +// Por razones de rendimiento, revocar los ObjectURL usados +URL.revokeObjectURL(imgURL); +</pre> + +<p>Si <code>createObjectURL()</code> no es soportado, una alternativa es retroceder a {{ domxref("FileReader") }}:</p> + +<pre class="brush: js">// Retroceder a FileReader si createObjectURL no está soportado +var fileReader = new FileReader(); +fileReader.onload = function (event) { + showPicture.src = event.target.result; +}; +fileReader.readAsDataURL(file); +</pre> + +<h2 id="Ejemplo_completo">Ejemplo completo</h2> + +<p>Si desea verlo en acción, eche un vistazo al <a class="external" href="http://robnyman.github.com/camera-api/">ejemplo completo de la API de Cámara funcionando</a>.</p> + +<p>Aquí está el código usado para esa demostración:</p> + +<h3 id="Página_HTML">Página HTML</h3> + +<pre class="brush: html"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Camera API</title> + <link rel="stylesheet" href="css/base.css" type="text/css" media="screen"> + </head> + + <body> + + <div class="container"> + <h1>Camera API</h1> + + <section class="main-content"> + <p>A demo of the Camera API, currently implemented in Firefox and Google Chrome on Android. Choose to take a picture with your device's camera and a preview will be shown through createObjectURL or a FileReader object (choosing local files supported too).</p> + + <p> + <input type="file" id="take-picture" accept="image/*"> + </p> + + <h2>Preview:</h2> + <p> + <img src="about:blank" alt="" id="show-picture"> + </p> + + <p id="error"></p> + + </section> + + <p class="footer">All the code is available in the <a href="https://github.com/robnyman/robnyman.github.com/tree/master/camera-api">Camera API repository on GitHub</a>.</p> + </div> + + + <script src="js/base.js"></script> + + + </body> +</html> +</pre> + +<h3 id="Fichero_JavaScript">Fichero JavaScript</h3> + +<pre class="brush: js">(function () { + var takePicture = document.querySelector("#take-picture"), + showPicture = document.querySelector("#show-picture"); + + if (takePicture && showPicture) { + // Establecer eventos + takePicture.onchange = function (event) { + // Obtener una referencia a la fotografía tomada o fichero seleccionado + var files = event.target.files, + file; + if (files && files.length > 0) { + file = files[0]; + try { + // Crear ObjectURL + var imgURL = window.URL.createObjectURL(file); + + // Establecer ObjectURL como img src + showPicture.src = imgURL; + + // Revocar ObjectURL + URL.revokeObjectURL(imgURL); + } + catch (e) { + try { + // Regresar a FileReader si createObjectURL no está soportado + var fileReader = new FileReader(); + fileReader.onload = function (event) { + showPicture.src = event.target.result; + }; + fileReader.readAsDataURL(file); + } + catch (e) { + // + var error = document.querySelector("#error"); + if (error) { + error.innerHTML = "Neither createObjectURL or FileReader are supported"; + } + } + } + } + }; + } +})(); +</pre> + +<h2 id="Compatibilidad_con_navegadores">Compatibilidad con navegadores</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Camera API</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + </tr> + <tr> + <td><code><a href="/en-US/docs/DOM/window.URL.createObjectURL" title="/en-US/docs/DOM/window.URL.createObjectURL">createObjectURL()</a></code></td> + <td>16</td> + <td>{{CompatGeckoDesktop("8.0")}}</td> + <td>10+</td> + <td>{{CompatNo()}}</td> + <td>{{CompatNo()}}</td> + </tr> + <tr> + <td>{{domxref("FileReader")}}</td> + <td>16</td> + <td>{{CompatGeckoDesktop("1.9.2")}}</td> + <td>10+</td> + <td>11.6+</td> + <td>{{CompatNo()}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Camera API</td> + <td>3.0</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatGeckoMobile("10.0") }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + </tr> + <tr> + <td><code><a href="/en-US/docs/DOM/window.URL.createObjectURL" title="/en-US/docs/DOM/window.URL.createObjectURL">createObjectURL()</a></code></td> + <td>4</td> + <td>{{CompatVersionUnknown()}}</td> + <td>{{CompatGeckoMobile("10.0")}}</td> + <td>{{CompatNo()}}</td> + <td>{{CompatNo()}}</td> + <td>{{CompatNo()}}</td> + </tr> + <tr> + <td>{{domxref("FileReader")}}</td> + <td>3</td> + <td>{{CompatVersionUnknown()}}</td> + <td>{{CompatGeckoMobile("10.0")}}</td> + <td>{{CompatNo()}}</td> + <td>11.1</td> + <td>{{CompatNo()}}</td> + </tr> + </tbody> +</table> +</div> + +<p> </p> diff --git a/files/es/web/guide/api/dom/events/orientation_and_motion_data_explained/orientation_and_motion_data_explained/index.html b/files/es/web/guide/api/dom/events/orientation_and_motion_data_explained/orientation_and_motion_data_explained/index.html new file mode 100644 index 0000000000..7f8fe2155c --- /dev/null +++ b/files/es/web/guide/api/dom/events/orientation_and_motion_data_explained/orientation_and_motion_data_explained/index.html @@ -0,0 +1,48 @@ +--- +title: Explicación de los datos de orientación y movimiento +slug: >- + Web/Guide/API/DOM/Events/Orientation_and_motion_data_explained/Orientation_and_motion_data_explained +translation_of: Web/Guide/Events/Orientation_and_motion_data_explained +--- +<p>{{ Draft() }}</p> +<h2 id="Sumario">Sumario</h2> +<p>Cuando se utiliza la orientación y los eventos de movimiento, es importante entender cuáles son los significados de los valores en el navegador. En este artículo se proporciona información acerca de los sistemas de coordenadas en el juego y la forma de usarlos.</p> +<div class="warning"> + <p><strong>Atención:</strong> Actualmente, Firefox y Chrome no soporta la orientación de la misma forma. Ten cuidado con esto cuando sea imprementado en un navegador u otro.</p> +</div> +<h2 id="Acerca_de_los_marcos_de_coordenadas">Acerca de los marcos de coordenadas</h2> +<p>Un marco de coordenadas en un sistema en el que la orientacion de los tres ejers (X, Y y Z) se definen en referencia a un objeto. Hay dos marcos de coordenadas a considerar cuando se utiliza eventos de orientación y el movimiento:</p> +<h3 id="Marco_de_coordenadas_terrestres">Marco de coordenadas terrestres</h3> +<p>El marco de coordenadas de terrestres es el sistema de coordenadas fijado en el centro de la Tierra, es decir, los ejes están alineados sobre la base de la fuerza de la gravedad y la orientación norte magnético estándar. Utilizamos las letras mayúsculas ("X", "Y" y "Z") para describir los ejes del sistema de coordenadas terrestre.</p> +<ul> + <li>El eje <strong>X</strong> sigue a lo largo (profuncidad) del plano de tierra, perpendicular al eje Y y positiva hacia el este (y por lo tanto negativa hacia el oeste).</li> + <li>El eje <strong>Y</strong> sigue a lo largo(ancho) del plano de tierra, y es positivo hacia el norte verdadero (es decir, el Polo Norte, el norte no es magnético) y negativo hacia la verdadera sur.</li> + <li>El eje <strong>Z</strong> es perpendicular al plano de tierra, piensa en él como una línea trazada entre el dispositivo y el centro de la Tierra. El valor de la coordenada Z es positivo hacia arriba (distancia desde el centro de la Tierra) y negativo hacia abajo (hacia el centro de la Tierra).</li> +</ul> +<p> </p> +<p><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/f/f6/Cartesian_xyz.png" style="width: 200px; height: 153px;"></p> +<p> </p> +<h3 id="Marco_de_coordenadas_del_dispositivo">Marco de coordenadas del dispositivo</h3> +<p>El marco de coordenadas del dispositivo es el marco de la coordinación fijada en el centro del dispositivo. Utilizamos letras minúsculas ("x", "y" y "z") para describir los ejes de las coordenadas del del dispositivo</p> +<p><img alt="axes.png" class="internal default" src="/@api/deki/files/5694/=axes.png" style=""></p> +<ul> + <li>El eje <strong>x</strong> está en el plano de la pantalla y es positiva hacia la derecha y negativa hacia la izquierda.</li> + <li>El eje <strong>y</strong> está en el plano de la pantalla y es positiva hacia la parte superior y negativa hacia la parte inferior.</li> + <li>El eje <strong>z</strong> es perpendicular a la pantalla o teclado, y es positivo que se extiende hacia fuera de la pantalla.</li> +</ul> +<div class="note"> + <strong>Nota:</strong> En un teléfono o tableta, la orientación del dispositivo siempre se considera en relación con la orientación estándar de la pantalla, lo que es la orientación "retrato" en la mayoría de los dispositivos. En una computadora portátil, la orientación se considera en relación con el teclado. Si desea detectar cambios en la orientación del dispositivo con el fin de compensar, se puede utilizar el evento orientationChange.</div> +<h2 id="Sobre_la_rotación">Sobre la rotación</h2> +<p>La rotación se describe alrededor de cualquier eje dado en términos del número de grados de diferencia entre el marco de coordenadas del dispositivo y el marco de coordenadas de la Tierra, y se mide en grados.</p> +<h3 id="Alpha">Alpha</h3> +<p>Rotación alrededor del eje z - es decir, girando el dispositivo - hace que el ángulo de rotación alfa cambie:</p> +<p><img alt="alpha.png" class="internal default" src="/@api/deki/files/5695/=alpha.png" style=""></p> +<p>El ángulo alfa es de 0 °, cuando la parte superior del dispositivo se apunta directamente hacia el polo norte de la Tierra, y aumenta a medida que el dispositivo se gira hacia la izquierda.</p> +<h3 id="Beta">Beta</h3> +<p>Rotación alrededor del eje X - es decir, inclinando el dispositivo desde o hacia el usuario - hace que el ángulo de giro beta cambie:</p> +<p><img alt="beta.png" class="internal default" src="/@api/deki/files/5696/=beta.png"></p> +<p>El ángulo beta es de 0 ° en la parte superior e inferior del dispositivo son la misma distancia de la superficie de la Tierra, y aumenta hacia 180 ° como el dispositivo se inclina hacia adelante y disminuye hacia -180 ° como el dispositivo se inclina hacia atrás.</p> +<h3 id="Gamma">Gamma</h3> +<p>Rotación alrededor del eje Y - es decir, la inclinación del dispositivo hacia la izquierda o hacia la derecha - hace que el ángulo de giro gamma cambie:</p> +<p><img alt="gamma.png" class="internal default" src="/@api/deki/files/5697/=gamma.png"></p> +<p>El ángulo gamma es 0 °, cuando los lados izquierdo y derecho del dispositivo son la misma distancia de la superficie de la Tierra, y aumenta hacia 90 ° como el dispositivo se inclina hacia la derecha, y hacia -90 ° como el dispositivo se inclina hacia el izquierda.</p> diff --git a/files/es/web/guide/api/index.html b/files/es/web/guide/api/index.html new file mode 100644 index 0000000000..c2ef8cbe1f --- /dev/null +++ b/files/es/web/guide/api/index.html @@ -0,0 +1,24 @@ +--- +title: Guide to Web APIs +slug: Web/Guide/API +tags: + - API + - Guía + - Landing + - TopicStub + - Web +translation_of: Web/Guide/API +--- +<p>Aquí encontrarás links a cada una de las guías introduciendo y explicando cada una de las APIs que conforman la la arquitectura del desarrollo web.</p> + + +<p>{{ListGroups}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/API">Web API interface reference</a> (an index of all of the interfaces comprising all of these APIs)</li> + <li><a href="/en-US/docs/Web/API/Document_Object_Model">Document Object Model</a> (DOM)</li> + <li><a href="/en-US/docs/Web/Events">Web API event reference</a></li> + <li><a href="/en-US/docs/Learn">Learning web development</a></li> +</ul> diff --git a/files/es/web/guide/api/vibration/index.html b/files/es/web/guide/api/vibration/index.html new file mode 100644 index 0000000000..8c9c7b5f06 --- /dev/null +++ b/files/es/web/guide/api/vibration/index.html @@ -0,0 +1,155 @@ +--- +title: Vibración API +slug: Web/Guide/API/Vibration +tags: + - API + - Firefox OS + - Mobile + - Principiante + - Vibración + - Vibrado + - Vibrar + - WebAPI +translation_of: Web/API/Vibration_API +--- +<p>La mayoría de los dispositivos modernos pueden vibrar a través del hardware, esto permite que a través del código de software se pueda emitir estas vibraciones. La <strong>Vibration API</strong> ofrece a las aplicaciones web la capacidad de acceder a este hardware en caso este lo soporte, caso contrario el dispositivo no hace nada.</p> + +<h2 id="Describiendo_vibraciones">Describiendo vibraciones</h2> + +<p>Vibración se puede describir como un patrón de prender y apagar pulsos, los cuales pueden variar en longitud. El patrón puede consistir de un sólo número que indica cuantos milisegundos vibrará, o un arreglo de enteros describiendo un patrón de vibraciones y pausas. La vibración es controlada por un solo método:</p> + +<p><span style="font-size: 13.63636302948px; line-height: 19.0909080505371px;">{{domxref("window.navigator.vibrate()")}}.</span></p> + +<h3 id="Vibración_simple">Vibración simple</h3> + +<p>Puedes iniciar una sola vibración del hardware pasando como argumento un sólo número, o un arreglo de un sólo número:</p> + +<pre class="brush:js">window.navigator.vibrate(200); +window.navigator.vibrate([200]); +</pre> + +<p>Ambos ejemplos hacen vibrar el dispositivo por 200 ms.</p> + +<h3 id="Patrones_de_vibración">Patrones de vibración</h3> + +<p>Un arreglo de valores describen que las vibraciones serán por períodos alternados, es decir, el dispositivo vibrará luego no lo hará, así según la secuencia definida. Cada valor en el arreglo es convertido a entero para luego ser interpretado alternadamente como el tiempo que el dispositivo debe vibrar y el tiempo que no debe vibrar. Ejemplo:</p> + +<pre class="brush: js">window.navigator.vibrate([200, 100, 200]); +</pre> + +<p>Según este ejemplo el dispositivo vibrará por 200ms, luego se detiene por 100ms y luego vibra 200ms.</p> + +<p>Puedes especificar cuantas vibraciones/pausas desees, y el arreglo puede tener un tamaño par o impar. No importa que agregues una pausa como el último valor del arreglo, ya que el celular dejará de vibrar de todas formas al final de cada vibración.</p> + +<h3 id="Cancelar_vibraciones_existentes">Cancelar vibraciones existentes</h3> + +<p>Llamar {{domxref("window.navigator.vibrate()")}} con un valor de <code>0</code>, arreglo vació, o arreglo que contenga 0's detendrá cualquier vibración en curso.</p> + +<h3 id="Vibraciones_continuas">Vibraciones continuas</h3> + +<p style="margin: 0px 0px 0.8em; padding: 0px; border: 0px; font-family: 'Open Sans', Arial, sans-serif; line-height: 1.6em; font-size: 16px; vertical-align: baseline;">Algunas básicas acciones son <code style="margin: 0px; padding: 2px 7px; border: 0px; font-family: monospace, sans-serif; font-style: inherit; font-variant: inherit; font-weight: bold; line-height: inherit; font-size: 16px; vertical-align: baseline; background-color: rgb(248, 248, 248); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px;">setInterval</code> y <code style="margin: 0px; padding: 2px 7px; border: 0px; font-family: monospace, sans-serif; font-style: inherit; font-variant: inherit; font-weight: bold; line-height: inherit; font-size: 16px; vertical-align: baseline; background-color: rgb(248, 248, 248); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px;">clearInterval</code> que nos permitirán crear vibraciones persistentes:</p> + +<pre class="js language-js" style="margin-top: 0.5em; margin-bottom: 0.5em; padding: 1em; border: 0px; font-family: Consolas, Monaco, 'Andale Mono', monospace; line-height: 1.6em; font-size: 0.8em; vertical-align: baseline; background-color: rgb(245, 242, 240); color: black; text-shadow: white 0px 1px; direction: ltr;"><code class="language-js" style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Monaco, 'Andale Mono', monospace; font-style: inherit; font-variant: inherit; line-height: inherit; font-size: 13px; vertical-align: baseline; text-shadow: white 0px 1px; direction: ltr;"><span class="token keyword" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(0, 119, 170);">var</span> intervaloDeVibrado<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">;</span> +<span class="token comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(112, 128, 144);"> +// Iniciar la vibración +</span><span class="token keyword" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(0, 119, 170);">function</span> <span class="token function" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline;">iniciarVibrado<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span></span>duracion<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">{</span> + navigator<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">.</span><span class="token function" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline;">vibrate<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span></span>duracion)<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">;</span> +<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">}</span> +<span class="token comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(112, 128, 144);"> +// Detiene la vibración +</span><span class="token keyword" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(0, 119, 170);">function</span> <span class="token function" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline;">detenerVibrado<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span></span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">{</span> +<span class="token comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(112, 128, 144);"> // Limpiar el intervalo y detener las vibraciones existentes +</span> <span class="token keyword" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(0, 119, 170);">if</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span>intervaloDeVibrado<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span> <span class="token function" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline;">clearInterval<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span></span>intervaloDeVibrado<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">;</span> + navigator<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">.</span><span class="token function" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline;">vibrate<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span></span><span class="token number" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 0, 85);">0</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">;</span> +<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">}</span> +<span class="token comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(112, 128, 144);"> +// Iniciar las vibraciones con una determinado tiempo e intervalo +</span><span class="token comment" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(112, 128, 144);">// Asumir que el valor recibido es un entero +</span><span class="token keyword" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(0, 119, 170);">function</span> iniciarVibradoPersistente<span class="token function" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline;"><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span></span>duracion<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">,</span> intervalo<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">{</span> + intervaloDeVibrado <span class="token operator" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039);">=</span> <span class="token function" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline;">setInterval<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span></span><span class="token keyword" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(0, 119, 170);">function</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">{</span> + <span class="token function" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline;">iniciarVibrado<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">(</span></span>duracion<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">;</span> + <span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">}</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">,</span> intervalo<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">;</span> +<span class="token punctuation" style="margin: 0px; padding: 0px; border: 0px; font-family: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; vertical-align: baseline; color: rgb(153, 153, 153);">}</span></code></pre> + +<p style="margin: 0px 0px 0.8em; padding: 0px; border: 0px; font-family: 'Open Sans', Arial, sans-serif; line-height: 1.6em; font-size: 16px; vertical-align: baseline;">Claro que el código de arriba no toma en cuenta el método de utilizar un arreglo de vibración, utilizar un arreglo para vibración persistente necesitaría recalcular la suma de los elementos del arregloo y crear un intervalo basado en esos números (agregando adicionalmente las pausas)</p> + +<h3 id="¿Por_qué_utilizar_Vibration_API">¿Por qué utilizar Vibration API?</h3> + +<p style="margin: 0px 0px 0.8em; padding: 0px; border: 0px; font-family: 'Open Sans', Arial, sans-serif; line-height: 1.6em; font-size: 16px; vertical-align: baseline;">Esta API es claramente accesible a través de dispositivos móbiles. Vibration API puede servir para alertas en las aplicaciones web del celular, y sería es asombrosa cuando se utiliza en juegos o en aplicaciones pesadas. Imagínate mirando un video en tu celular y durante la escena de explosión,tu teléfono vibra un poco. O la sensación que tendría tu usuario al sentir el estallido de una bomba en el juego Bomberman.</p> + +<h2 id="Especificaciones">Especificaciones</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Especificación</th> + <th scope="col">Estado</th> + <th scope="col">Comentario</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('Vibration API')}}</td> + <td>{{Spec2('Vibration API')}}</td> + <td>Especificación inicial.</td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilidad_entre_navegadores">Compatibilidad entre navegadores</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Caracteŕistica</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Soporte básico</td> + <td>{{CompatVersionUnknown}} {{property_prefix("webkit")}}</td> + <td>11.0 {{property_prefix("moz")}}<br> + 16 (no prefix)</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Característica</th> + <th>Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Soporte básico</td> + <td>{{CompatVersionUnknown}} {{property_prefix("webkit")}}</td> + <td>11.0 {{property_prefix("moz")}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Ver_También">Ver También</h2> + +<ul> + <li>{{domxref("window.navigator.vibrate()")}}</li> + <li><a href="http://davidwalsh.name/vibration-api">Vibration API - David Walsh</a></li> +</ul> diff --git a/files/es/web/guide/css/block_formatting_context/index.html b/files/es/web/guide/css/block_formatting_context/index.html new file mode 100644 index 0000000000..a3edd4220f --- /dev/null +++ b/files/es/web/guide/css/block_formatting_context/index.html @@ -0,0 +1,45 @@ +--- +title: Contexto de formato de bloque +slug: Web/Guide/CSS/Block_formatting_context +tags: + - CSS + - Guía + - Necesita ejemplos + - Referencia + - Web +translation_of: Web/Guide/CSS/Block_formatting_context +--- +<p>{{ CSSRef() }}</p> + +<h2 id="Summary" name="Summary">Resumen</h2> + +<p>Un <strong>contexto de formato de bloque</strong> es parte del renderizado CSS visual de una página web. Es la región en que ocurre la disposición de las cajas de bloque y en la cuál los elementos flotantes interactúan los unos con los otros.</p> + +<p>Un contexto de formato de bloque es creado por uno de los siguientes casos:</p> + +<ul> + <li>El elemento raiz o algo que lo contiene</li> + <li>flotantes (elementos donde {{ cssxref("float") }} es diferente de none)</li> + <li>elementos con posición absoluta (elementos donde {{ cssxref("position") }} es absolute o fixed)</li> + <li>bloques en línea (elementos con {{ cssxref("display") }}<code>: inline-block</code>)</li> + <li>Celdas de tabla (elementos con {{ cssxref("display") }}<code>: table-cell</code>, que es la propiedad por defecto de las celdas de una tabla HTML)</li> + <li>subtítulos de tabla (elementos con {{ cssxref("display") }}<code>: table-caption</code>, que es la propiedad por defecto de los subtítulos de tablas HTML)</li> + <li>elementos donde {{ cssxref("overflow") }} tiene un valor distinto a <code>visible</code></li> + <li>cajas flexibles (elementos con {{ cssxref("display") }}<code>: flex</code> or <code>inline-flex</code>)</li> +</ul> + +<p>Un contexto de formato de bloque contiene todo dentro del elemento que lo crea que, al mismo tiempo, no se encuentra dentro de un elemento descendiente que crea un nuevo contexto de formato de bloque.</p> + +<p>Los contextos de formato de bloque son importantes para el posicionamiento (revisa {{ cssxref("float") }} y {{ cssxref("clear") }}) de flotantes. Las reglas para el posicionamiento y limpiado de flotantes aplican solo a elementos dentro del mismo contexto de formato de bloque. Los flotantes no afectan la disposición de los elementos en otros contexto de formato de bloque, y clear solo limpia flotantes pasados en el mismo contexto de formato de bloque.</p> + +<h2 id="Specifications" name="Specifications">Especificaciones</h2> + +<ul> + <li><a class="external" href="http://www.w3.org/TR/CSS21/visuren.html#block-formatting">CSS 2.1</a></li> +</ul> + +<h2 id="See_Also" name="See_Also">También puedes ver</h2> + +<ul> + <li>{{ cssxref("float") }}, {{ cssxref("clear") }}</li> +</ul> diff --git a/files/es/web/guide/css/probando_media_queries/index.html b/files/es/web/guide/css/probando_media_queries/index.html new file mode 100644 index 0000000000..dac4330054 --- /dev/null +++ b/files/es/web/guide/css/probando_media_queries/index.html @@ -0,0 +1,93 @@ +--- +title: Probando media queries +slug: Web/Guide/CSS/probando_media_queries +translation_of: Web/CSS/Media_Queries/Testing_media_queries +--- +<p>{{SeeCompatTable}}</p> +<p>El DOM proporciona características que hacen posible probar los resultados de un media query estructuradamente. Esto es hecho usando la interfaz {{domxref("MediaQueryList") }} y sus métodos y propiedades. Una vez que hayas creado el objeto {{domxref("MediaQueryList") }}, puedes revisar el resultado del query o, como alternativa, recibir notificaciones automáticamente cuando el resultado cambie.</p> +<h2 id="Creating_a_media_query_list" name="Creating_a_media_query_list">Creando una media query list</h2> +<p>Before you can evaluate the results of a query, you need to create the {{domxref("MediaQueryList") }} object representing the media query. To do this, use the {{domxref("window.matchMedia") }} method.</p> +<p>For example, if you want to set up a query list that determines whether the device is in landscape or portrait orientation, you can do so like this:</p> +<pre>var mql = window.matchMedia("(orientation: portrait)"); +</pre> +<h2 id="Checking_the_result_of_a_query" name="Checking_the_result_of_a_query">Revisando el resultado de un query</h2> +<p>Once your media query list has been created, you can check the result of the query by looking at the value of its <code>matches</code> property, which reflects the result of the query:</p> +<pre class="brush: js">if (mql.matches) { + /* The device is currently in portrait orientation */ +} else { + /* The device is currently in landscape orientation */ +} +</pre> +<h2 id="Receiving_query_notifications" name="Receiving_query_notifications">Recibiendo notificaciones query</h2> +<p>If you need to be aware of changes to the evaluated result of the query on an ongoing basis, it's more efficient to register a listener than to poll the query's result. To do this, you can call the <code>addListener()</code> method on the {{domxref("MediaQueryList") }} object, specifying an observer that implements the {{domxref("MediaQueryListListener") }} interface:</p> +<pre class="brush: js">var mql = window.matchMedia("(orientation: portrait)"); +mql.addListener(handleOrientationChange); +handleOrientationChange(mql); +</pre> +<p>This code creates the orientation testing media query list, <code>mql</code>, then adds a listener to it. Note that after adding the listener, we actually invoke the listener directly once. This lets our listener perform initial adjustments based on the current device orientation (otherwise, if our code assumes the device is in portrait mode but it's actually in landscape mode at startup, we could have inconsistencies).</p> +<p>The <code>handleOrientationChange()</code> method we implement then would look at the result of the query and handle whatever we need to do on an orientation change:</p> +<pre class="brush: js">function handleOrientationChange(mql) { + if (mql.matches) { + /* The device is currently in portrait orientation */ + } else { + /* The device is currently in landscape orientation */ + } +} +</pre> +<h2 id="Ending_query_notifications" name="Ending_query_notifications">Terminando con las notificaciones query </h2> +<p>Cuando ya no vayas a necesitar recibir las notificaciones sobre los cambios de valro de tu media query, simplemente llama al <code>removeListener()</code> en el {{domxref("MediaQueryList") }}:</p> +<pre>mql.removeListener(handleOrientationChange); +</pre> +<h2 id="Browser_compatibility" name="Browser_compatibility">Compatibilidad con los navegadores</h2> +<p>{{CompatibilityTable}}</p> +<div id="compat-desktop"> + <table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Soporte básico</td> + <td>9</td> + <td>{{CompatGeckoDesktop("6.0") }}</td> + <td>10</td> + <td>12.1</td> + <td>5.1</td> + </tr> + </tbody> + </table> +</div> +<div id="compat-mobile"> + <table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Soporte básico</td> + <td>3.0</td> + <td>{{CompatUnknown}}</td> + <td>10</td> + <td>12.1</td> + <td>5</td> + </tr> + </tbody> + </table> +</div> +<h2 id="See_also" name="See_also">Ver también</h2> +<ul> + <li><a href="/en-US/docs/CSS/Media_queries" title="CSS/Media queries">Media queries</a></li> + <li>{{domxref("window.matchMedia()") }}</li> + <li>{{domxref("MediaQueryList") }}</li> + <li>{{domxref("MediaQueryListListener") }}</li> +</ul> diff --git a/files/es/web/guide/dom/events/creacion_y_activación_eventos/index.html b/files/es/web/guide/dom/events/creacion_y_activación_eventos/index.html new file mode 100644 index 0000000000..0038e12c74 --- /dev/null +++ b/files/es/web/guide/dom/events/creacion_y_activación_eventos/index.html @@ -0,0 +1,144 @@ +--- +title: Creación y activación de eventos (Event) +slug: Web/Guide/DOM/Events/Creacion_y_Activación_Eventos +tags: + - DOM + - Guía + - JavaScript + - Sintetico + - eventos +translation_of: Web/Guide/Events/Creating_and_triggering_events +--- +<p>En este artículo se muestra cómo crear y activar eventos DOM. Estos eventos son comunmente llamados eventos sinteticos, a diferencia de los eventos gatillados por el navegador.</p> + +<h2 id="Crear_eventos_personalizados">Crear eventos personalizados</h2> + +<p> Los eventos pueden ser creados con el constructor de eventos de la siguiente manera:</p> + +<pre class="brush: js">var event = new Event('build'); + +// Escucha para el evento. +elem.addEventListener('build', function (e) { ... }, false); + +// Disparar event. +elem.dispatchEvent(event);</pre> + +<p>El codigo de ejemplo de arriba usa el metodo <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent">EventTarget.dispatchEvent()</a>. </p> + +<p>Este constructor es compatible con la mayoría de los navegadores modernos (con Internet Explorer es la excepción). Para un enfoque más detallado, ver la manera antigua de abajo.</p> + +<h3 id="Adición_de_datos_personalizados_con_CustomEvent_()">Adición de datos personalizados con CustomEvent ()</h3> + +<p> Para añadir más datos al objeto de evento, existe la interfaz CustomEvent y la propiedad detalle se puede utilizar para pasar los datos personalizados.<br> + <span style="line-height: 1.5;">Por Ejemplo, </span>el evento se puede crear de la siguiente manera<span style="line-height: 1.5;">:</span></p> + +<pre class="brush: js">var event = new CustomEvent('build', { 'detail': elem.dataset.time });</pre> + +<p> Esto permitirá tener acceso a los datos adicionales en el escuchador de eventos (<span style="line-height: 19.0909080505371px;">event listener</span>):</p> + +<pre class="brush: js">function eventHandler(e) { + log('The time is: ' + e.detail); +} +</pre> + +<h3 id="La_Forma_Antigua">La Forma Antigua</h3> + +<p> El enfoque más para la creación de eventos utiliza APIs inspirados en Java. A continuación se muestra un ejemplo:</p> + +<pre class="brush: js">// Creamos el evento. +var event = document.createEvent('Event'); + +/* Definimos el nombre del evento que es 'build'.*/ +event.initEvent('build', true, true); + +// Asignamos el evento. +document.addEventListener('build', function (e) { + // e.target matches document from above +}, false); + +// target can be any Element or other EventTarget. +document.dispatchEvent(event); + +</pre> + +<h2 id="El_disparo_incorporado_eventos">El disparo incorporado eventos</h2> + +<p> Comunmente es deseable disparar un evento desde un elemento hijo, y lograr que el padre lo capture: opcionalmente con datos: </p> + +<pre class="brush: js">function simulateClick() { + var event = new MouseEvent('click', { + 'view': window, + 'bubbles': true, + 'cancelable': true + }); + var cb = document.getElementById('checkbox'); + var canceled = !cb.dispatchEvent(event); + if (canceled) { + // A handler called preventDefault. + alert("canceled"); + } else { + // None of the handlers called preventDefault. + alert("not canceled"); + } +}</pre> + +<h2 id="Browser_compatibility" name="Browser_compatibility" style="line-height: 30px; font-size: 2.14285714285714rem;">Compatibilidad con los Navegadores</h2> + +<h2 id="sect1"> </h2> + +<p>{{CompatibilityTable()}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th style="line-height: 16px;">Feature</th> + <th style="line-height: 16px;">Chrome</th> + <th style="line-height: 16px;">Firefox (Gecko)</th> + <th style="line-height: 16px;">Internet Explorer</th> + <th style="line-height: 16px;">Opera</th> + <th style="line-height: 16px;">Safari (WebKit)</th> + </tr> + <tr> + <td><code>Event()</code> constructor</td> + <td>15</td> + <td>11</td> + <td>{{ CompatNo() }}</td> + <td>11.60</td> + <td>6</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th style="line-height: 16px;">Feature</th> + <th style="line-height: 16px;">Android</th> + <th style="line-height: 16px;">Firefox Mobile (Gecko)</th> + <th style="line-height: 16px;">IE Phone</th> + <th style="line-height: 16px;">Opera Mobile</th> + <th style="line-height: 16px;">Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>6</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{domxref("document.createEvent()")}}</li> + <li>{{domxref("Event.initEvent()")}}</li> + <li>{{domxref("EventTarget.dispatchEvent()")}}</li> + <li>{{domxref("EventTarget.addEventListener()")}}</li> +</ul> diff --git a/files/es/web/guide/dom/events/eventos_controlador/index.html b/files/es/web/guide/dom/events/eventos_controlador/index.html new file mode 100644 index 0000000000..836b287123 --- /dev/null +++ b/files/es/web/guide/dom/events/eventos_controlador/index.html @@ -0,0 +1,132 @@ +--- +title: Manejadores de eventos en el DOM +slug: Web/Guide/DOM/Events/eventos_controlador +translation_of: Web/Guide/Events/Event_handlers +--- +<p><span class="seoSummary">La plataforma Web provee varias formas de recibir notificaciones de los eventos del <a href="/en-US/docs/Web/Events">DOM</a>. Dos de las formas más comunes son: la general {{domxref("EventTarget.addEventListener", "addEventListener()")}} y un conjunto específico de controladores de eventos específicos.</span> Esta página se enfoca en los detalles de cómo funcionan estos.</p> + +<h3 id="Registering_on-event_handlers">Registering <em>on-event</em> handlers</h3> + +<p>Los controladores <em><strong>on-event</strong></em> son un grupo de propiedades ofrecidas por los elementos del DOM para ayudar a manejar cómo los elementos reaccionan a los eventos. Los elementos pueden ser interactivos (por ejemplo: enlaces, botones, imagenes, formularios) or non-interactive (e.g. the base document). Los eventos pueden ser cuando se haga un click, detectar cuando se presione una tecla, enfocarse, entre otros. Los handlers on-event son comunmente denominados como el evento al cual deben reaccionar, como ser <code>onclick</code>, <code>onkeypress</code>, <code>onfocus</code>, etc.</p> + +<p>Pueden especificar un controlador de evento <code>on<...></code> para un evento en particular (como {{event("click")}}) como un opbjeto determinado de diferentes formas:</p> + +<ul> + <li>Usando el HTML {{Glossary("atributo")}} llamados <code>on<em>{eventtype}</em></code> en un elemento, por ejemplo:<br> + <code><button <u>onclick="return handleClick(event);"</u>></code>,</li> + <li>O seteandolo {{Glossary("property/JavaScript", "property")}} desde JavaScript, por ejemplo:<br> + <code>document.getElementById("mybutton")<u>.onclick = function(event) { ... }</u></code>.</li> +</ul> + +<p>Un controlador onevent</p> + +<p>Notese que cada objeto puede tener sólo un controlador <em>on-event</em> para un evento dado (though that handler could call multiple sub-handlers). This is why {{domxref("EventTarget.addEventListener", "addEventListener()")}} is often the better way to get notified of events, especially when wishing to apply various event handlers independently from each other, even for the same event and/or to the same element.</p> + +<p>Also note that <em>on-event</em> handlers are called automatically, not at the programmer's will (although you can, like <code>mybutton.onclick(myevent); ) </code>since they serve more as placeholders to which a real handler function can be <strong>assigned</strong>.</p> + +<h3 id="Non-element_objects">Non-element objects</h3> + +<p>Event handlers can also be set using properties on many non-element objects that generate events, including {{ domxref("window") }}, {{ domxref("document") }}, {{ domxref("XMLHttpRequest") }}, and others, for example:</p> + +<pre class="notranslate">xhr.onprogress = function() { ... }</pre> + +<h2 id="Details">Details</h2> + +<h3 id="The_value_of_HTML_on<...>_attributes_and_corresponding_JavaScript_properties">The value of HTML on<...> attributes and corresponding JavaScript properties</h3> + +<p>A handler registered via an <code>on<...></code> attribute will be available via the corresponding <code>on<...></code> property, but not the other way around:</p> + +<pre class="brush: html notranslate"><div id="a" onclick="alert('old')">Open the Developer Tools Console to see the output.</div> + +<script> +window.onload = function () { + var div = document.getElementById("a"); + console.log("Attribute reflected as a property: ", div.onclick.toString()); + // Prints: function onclick(event) { alert('old') } + div.onclick = function() { alert('new') }; + console.log("Changed property to: ", div.onclick.toString()); + // Prints: function () { alert('new') } + console.log("Attribute value is unchanged: ", div.getAttribute("onclick")); + // Prints: alert('old') +} +</script></pre> + +<p>For historical reasons, some attributes/properties on the {{HTMLElement("body")}} and {{HTMLElement("frameset")}} elements actually set event handlers on their parent {{domxref("Window")}} object. (The HTML specification names these: <code>onblur</code>, <code>onerror</code>, <code>onfocus</code>, <code>onload</code>, <code>onscroll</code>.)</p> + +<h3 id="Event_handlers_parameters_this_binding_and_the_return_value">Event handler's parameters, <code>this</code> binding, and the return value</h3> + +<p>When the event handler is specified as <strong>an HTML attribute</strong>, the specified code is wrapped into a function with <strong>the following parameters</strong>:</p> + +<ul> + <li><code>event</code> - for all event handlers, except {{domxref("GlobalEventHandlers.onerror", "onerror")}}.</li> + <li><code>event</code>, <code>source</code>, <code>lineno</code>, <code>colno</code>, and <code>error</code> for the {{domxref("GlobalEventHandlers.onerror", "onerror")}} event handler. Note that the <code>event</code> parameter actually contains the error message as string.</li> +</ul> + +<p>When the event handler is invoked, the <code>this</code> keyword inside the handler is set to the DOM element on which the handler is registered. For more details see <a href="/en-US/docs/Web/JavaScript/Reference/Operators/this#In_an_in%E2%80%93line_event_handler">the this keyword documentation</a>.</p> + +<p>The return value from the handler determines if the event is canceled. The specific handling of the return value depends on the kind of event, for details see <a href="https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm">"The event handler processing algorithm" in the HTML specification</a>.</p> + +<h3 id="When_the_event_handler_is_invoked">When the event handler is invoked</h3> + +<p>TBD (non-capturing listener)</p> + +<h3 id="Terminology">Terminology</h3> + +<p>The term <strong>event handler</strong> may be used to refer to:</p> + +<ul> + <li>any function or object registered to be notified of events,</li> + <li>or, more specifically, to the mechanism of registering event listeners via <code>on...</code> attributes in HTML or properties in web APIs, such as <code><button onclick="alert(this)"></code> or <code>window.onload = function() { /* ... */ }</code>.</li> +</ul> + +<p>When discussing the various methods of listening to events,</p> + +<ul> + <li><strong>event listener</strong> refers to a function or object registered via {{domxref("EventTarget.addEventListener()")}},</li> + <li>whereas <strong>event handler</strong> refers to a function registered via <code>on...</code> attributes or properties.</li> +</ul> + +<h2 id="Specifications" name="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('HTML WHATWG', 'webappapis.html#event-handler-attributes', 'event handlers')}}</td> + <td>{{Spec2('HTML WHATWG')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('HTML5 W3C', 'webappapis.html#event-handler-attributes', 'event handlers')}}</td> + <td>{{Spec2('HTML5 W3C')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_Compatibility" name="Browser_Compatibility">Browser compatibility</h2> + +<h3 id="Event_handler_changes_in_Firefox_9">Event handler changes in Firefox 9</h3> + +<p>In order to better match the specifications, and improve cross-browser compatibility, the way event handlers were implemented at a fundamental level changed in Gecko 9.0 {{ geckoRelease("9.0") }}.</p> + +<p>Specifically, in the past, event handlers were not correctly implemented as standard IDL attributes. In Gecko 9.0, this was changed. Because of this, certain behaviors of event handlers in Gecko have changed. In particular, they now behave in all the ways standard IDL attributes behave. In most cases, this shouldn't affect web or add-on content at all; however, there are a few specific things to watch out for.</p> + +<h4 id="Detecting_the_presence_of_event_handler_properties">Detecting the presence of event handler properties</h4> + +<p>You can now detect the presence of an event handler property (that is, for example, <code>onload</code>), using the JavaScript <a href="/en-US/JavaScript/Reference/Operators/in" title="en/JavaScript/Reference/Operators/in"><code>in</code></a> operator. For example:</p> + +<pre class="brush: js notranslate">if ("onsomenewfeature" in window) { + /* do something amazing */ +} +</pre> + +<h4 id="Event_handlers_and_prototypes">Event handlers and prototypes</h4> + +<p>You can't set or access the values of any IDL-defined attributes on DOM prototype objects; that means you can't, for example, change <code>Window.prototype.onload</code> anymore. In the past, event handlers (<code>onload</code>, etc.) weren't implemented as IDL attributes in Gecko, so you were able to do this for those. Now you can't. This improves compatibility.</p> diff --git a/files/es/web/guide/dom/events/index.html b/files/es/web/guide/dom/events/index.html new file mode 100644 index 0000000000..241f94e866 --- /dev/null +++ b/files/es/web/guide/dom/events/index.html @@ -0,0 +1,16 @@ +--- +title: Event developer guide +slug: Web/Guide/DOM/Events +tags: + - DOM + - Event + - Guide + - NeedsTranslation + - TopicStub + - events +translation_of: Web/Guide/Events +--- +<p>{{draft()}}</p> +<p>Everything you need to know about events will go under here. We're working on cleanup here now.</p> +<h2 id="Docs">Docs</h2> +<p>{{LandingPageListSubpages}}</p> diff --git a/files/es/web/guide/dom/index.html b/files/es/web/guide/dom/index.html new file mode 100644 index 0000000000..997730a412 --- /dev/null +++ b/files/es/web/guide/dom/index.html @@ -0,0 +1,21 @@ +--- +title: DOM developer guide +slug: Web/Guide/DOM +tags: + - API + - DOM + - Guide + - NeedsTranslation + - TopicStub +translation_of: Web/API/Document_Object_Model +--- +<p>{{draft}}</p> +<p>The <a href="/docs/DOM">Document Object Model</a> is an API for <a href="/en-US/docs/HTML">HTML</a> and <a href="/en-US/docs/XML">XML</a> documents. It provides a structural representation of the document, enabling the developer to modify its content and visual presentation. Essentially, it connects web pages to scripts or programming languages.</p> +<p>All of the properties, methods, and events available to the web developer for manipulating and creating web pages are organized into <a href="/en-US/docs/Gecko_DOM_Reference">objects</a> (e.g., the document object that represents the document itself, the table object that represents a HTML table element, and so forth). Those objects are accessible via scripting languages in most recent web browsers.</p> +<p>The DOM is most often used in conjunction with <a href="/en-US/docs/JavaScript">JavaScript</a>. However, the DOM was designed to be independent of any particular programming language, making the structural representation of the document available from a single, consistent API. Though we focus on JavaScript throughout this site, implementations of the DOM can be built for <a href="http://www.w3.org/DOM/Bindings">any language</a>.</p> +<p>The <a href="http://www.w3.org/">World Wide Web Consortium</a> establishes a <a href="http://www.w3.org/DOM/">standard for the DOM</a>, called the W3C DOM. It should, now that the most important browsers correctly implement it, enable powerful cross-browser applications.</p> +<h2 id="Why_is_the_DOM_support_in_Mozilla_important.3F" name="Why_is_the_DOM_support_in_Mozilla_important.3F">Why is the DOM important?</h2> +<p>"Dynamic HTML" (<a href="/en-US/docs/DHTML">DHTML</a>) is a term used by some vendors to describe the combination of HTML, style sheets and scripts that allows documents to be animated. The W3C DOM Working Group is working hard to make sure interoperable and language-neutral solutions are agreed upon (see also the <a href="http://www.w3.org/DOM/faq.html">W3C FAQ</a>). As Mozilla claims the title of "Web Application Platform", support for the DOM is one of the most requested features, and a necessary one if Mozilla wants to be a viable alternative to the other browsers.</p> +<p>Even more important is the fact that the user interface of Mozilla (also Firefox and Thunderbird) is built using <a href="/en-US/docs/XUL" title="/en-US/docs/XUL">XUL</a>, using the DOM to <a href="/en-US/docs/Dynamically_modifying_XUL-based_user_interface">manipulate its own UI</a>.</p> +<h2 id="More_about_the_DOM">More about the DOM</h2> +<p>{{LandingPageListSubpages}}</p> diff --git a/files/es/web/guide/graphics/index.html b/files/es/web/guide/graphics/index.html new file mode 100644 index 0000000000..bacd15f6e9 --- /dev/null +++ b/files/es/web/guide/graphics/index.html @@ -0,0 +1,53 @@ +--- +title: Gráficas en la web +slug: Web/Guide/Graphics +tags: + - 2D + - 3D + - 3ra Dimensión + - Canvas + - Gráficas + - Gráficos(2) + - HTML5 + - Líneas + - RTCWeb + - SVG + - WebGL + - WebRTC + - graficos +translation_of: Web/Guide/Graphics +--- +<p> </p> + + + +<p>Los sitios web modernos a menudo necesitan aplicaciones para presentar y/o visualizar gráficos . Se</p> + +<div class="row topicpage-table"> +<div class="section"> +<dl> + <dt><a href="/en-US/docs/Web/Guide/Graphics/Drawing_graphics_with_canvas" title="/en-US/docs/Web/Reference">Dibujando gráficas con canvas</a></dt> + <dd>Una guía inicial para usar el elemento {{HTMLElement("canvas")}} para dibujar gráficos en 2D.</dd> + <dt><a href="/en-US/docs/SVG" title="/en-US/docs/SVG">SVG</a></dt> + <dd> + <p>Scalable Vector Graphics ( SVG ), Gráficos Vectoriales Escalables, le permite utilizar líneas , curvas y otras formas geométricas para representar gráficos . Al evitar el uso de mapas de bits , puede crear imágenes que se escalan sin falla a cualquier tamaño.</p> + </dd> +</dl> + +<p><span class="alllinks"><a href="/en-US/docs/tag/Graphics">View All...</a></span></p> +</div> + +<div class="section"> +<h2 class="Documentation" id="Docs_for_add-on_developers" name="Docs_for_add-on_developers">Gráficas en 3D</h2> + +<dl> + <dt><a href="/en-US/docs/Web/WebGL" title="/en-US/docs/WebGL">WebGL</a></dt> + <dd> + <p>Una guía de cómo empezar con WebGL , la API (bibliteca de contenidos) de gráficos 3D para la Web. Esta tecnología le permite utilizar estándar OpenGL ES en el contenido Web .</p> + </dd> +</dl> + +<dl> +</dl> +</div> +</div> diff --git a/files/es/web/guide/html/canvas_tutorial/advanced_animations/index.html b/files/es/web/guide/html/canvas_tutorial/advanced_animations/index.html new file mode 100644 index 0000000000..15ab72ee7f --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/advanced_animations/index.html @@ -0,0 +1,380 @@ +--- +title: Advanced animations +slug: Web/Guide/HTML/Canvas_tutorial/Advanced_animations +tags: + - Canvas + - Tutoria + - graficos +translation_of: Web/API/Canvas_API/Tutorial/Advanced_animations +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}</div> + +<div class="summary"> +<p>En el último capítulo hicimos unas <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations">animaciones básicas</a> y nos familiarizamos con varias maneras de mover cosas. En esta parte examinaremos la moción misma y agregaremos la física para hacer nuestras animaciones más avanzadas.</p> +</div> + +<h2 id="Dibujar_una_bola">Dibujar una bola</h2> + +<p>Vamos a usar una bola para nuestro estudio de la animación, entonces primero dibujamos la bola dentro del canvas. El siguente código lo configurará.</p> + +<pre class="brush: html"><canvas id="canvas" width="600" height="300"></canvas> +</pre> + +<p>Como siempre, necesitamos un entorno para dibujar. Para dibujar la bola, creamos un contenido <code>ball</code> lo cual contiene propiedades y un método <code>draw()</code>.</p> + +<pre class="brush: js">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); + +var ball = { + x: 100, + y: 100, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +ball.draw();</pre> + +<p>Nada especial aquí; la bola es en realidad un circulo sencillo y se dibuja con el método {{domxref("CanvasRenderingContext2D.arc()", "arc()")}}.</p> + +<h2 id="Agregar_velocidad">Agregar velocidad</h2> + +<p>Ya que tenemos una bola, estamos listos agregar una animación básica así como aprendimos en el <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations">último capítulo</a> de esta tutoría. De nuevo, {{domxref("window.requestAnimationFrame()")}} nos ayuda controlar la animación. La bola empieza moverse por agregar un vector de velocidad a la posición. Para cada fotograma, también {{domxref("CanvasRenderingContext2D.clearRect", "clear", "", 1)}} el canvas para quitar los circulos viejos de los fotogramas anteriores.</p> + +<pre class="brush: js; highlight:[8,9,24,25]">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 2, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function draw() { + ctx.clearRect(0,0, canvas.width, canvas.height); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mouseover', function(e) { + raf = window.requestAnimationFrame(draw); +}); + +canvas.addEventListener('mouseout', function(e) { + window.cancelAnimationFrame(raf); +}); + +ball.draw(); +</pre> + +<h2 id="Límites">Límites</h2> + +<p>Si no probamos los límites, de repente nuestra bola se agota el canvas. Necesitamos verificar si las posiciones <code>x</code> e <code>y</code> están fuera de las dimensiones del canvas y invertir la direción de los vectores de velocidad. Para hacer eso, agregamos los siguentes pasos al método <code>draw</code>:</p> + +<pre class="brush: js">if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { + ball.vy = -ball.vy; +} +if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { + ball.vx = -ball.vx; +}</pre> + +<h3 id="Primera_demo">Primera demo</h3> + +<p>Veamos como se ve en acción hasta este punto. Dirige el ratón dentro del canvas para empezar la animación.</p> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas></pre> + +<pre class="brush: js">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 2, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function draw() { + ctx.clearRect(0,0, canvas.width, canvas.height); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + + if (ball.y + ball.vy > canvas.height || + ball.y + ball.vy < 0) { + ball.vy = -ball.vy; + } + if (ball.x + ball.vx > canvas.width || + ball.x + ball.vx < 0) { + ball.vx = -ball.vx; + } + + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mouseover', function(e) { + raf = window.requestAnimationFrame(draw); +}); + +canvas.addEventListener('mouseout', function(e) { + window.cancelAnimationFrame(raf); +}); + +ball.draw();</pre> +</div> + +<p>{{EmbedLiveSample("First_demo", "610", "310")}}</p> + +<h2 id="Aceleración">Aceleración</h2> + +<p>Para convertir la moción en más auténtica, puedes jugar con la velocidad, así por ejemplo:</p> + +<pre class="brush: js">ball.vy *= .99; +ball.vy += .25;</pre> + +<p>Esto reduce el vector vertical de velocidad para cada fotograma para que la bola termina rebotando en el suelo.</p> + +<div class="hidden"> +<h6 id="Second_demo">Second demo</h6> + +<pre class="brush: html"><canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas></pre> + +<pre class="brush: js">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 2, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function draw() { + ctx.clearRect(0,0, canvas.width, canvas.height); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + ball.vy *= .99; + ball.vy += .25; + + if (ball.y + ball.vy > canvas.height || + ball.y + ball.vy < 0) { + ball.vy = -ball.vy; + } + if (ball.x + ball.vx > canvas.width || + ball.x + ball.vx < 0) { + ball.vx = -ball.vx; + } + + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mouseover', function(e) { + raf = window.requestAnimationFrame(draw); +}); + +canvas.addEventListener('mouseout', function(e) { + window.cancelAnimationFrame(raf); +}); + +ball.draw();</pre> +</div> + +<p>{{EmbedLiveSample("Second_demo", "610", "310")}}</p> + +<h2 id="Efecto_de_rezagar">Efecto de rezagar</h2> + +<p>Hasta este punto hemos limpiado los fotogramas anteriores con el método {{domxref("CanvasRenderingContext2D.clearRect", "clearRect")}}. Si reemplazas este método con un semi-transparente {{domxref("CanvasRenderingContext2D.fillRect", "fillRect")}}, puedes facilmente crear un efecto de rezagar.</p> + +<pre class="brush: js">ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; +ctx.fillRect(0, 0, canvas.width, canvas.height);</pre> + +<div class="hidden"> +<h6 id="Third_demo">Third demo</h6> + +<pre class="brush: html"><canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas></pre> + +<pre class="brush: js">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 2, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function draw() { + ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + ball.vy *= .99; + ball.vy += .25; + + if (ball.y + ball.vy > canvas.height || + ball.y + ball.vy < 0) { + ball.vy = -ball.vy; + } + if (ball.x + ball.vx > canvas.width || + ball.x + ball.vx < 0) { + ball.vx = -ball.vx; + } + + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mouseover', function(e) { + raf = window.requestAnimationFrame(draw); +}); + +canvas.addEventListener('mouseout', function(e) { + window.cancelAnimationFrame(raf); +}); + +ball.draw();</pre> +</div> + +<p>{{EmbedLiveSample("Third_demo", "610", "310")}}</p> + +<h2 id="Agregar_control_de_ratón">Agregar control de ratón</h2> + +<p>Para controlar la bola, podemos hacerla seguir nuestro ratón usando el evento <code><a href="/en-US/docs/Web/Reference/Events/mousemove">mousemove</a></code>, por ejemplo. El evento <code><a href="/en-US/docs/Web/Events/click">click</a></code> solta la bola y la deja rebotar de nuevo.</p> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas></pre> +</div> + +<pre class="brush: js">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; +var running = false; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 1, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function clear() { + ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; + ctx.fillRect(0,0,canvas.width,canvas.height); +} + +function draw() { + clear(); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + + if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { + ball.vy = -ball.vy; + } + if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { + ball.vx = -ball.vx; + } + + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mousemove', function(e) { + if (!running) { + clear(); + ball.x = e.clientX; + ball.y = e.clientY; + ball.draw(); + } +}); + +canvas.addEventListener('click', function(e) { + if (!running) { + raf = window.requestAnimationFrame(draw); + running = true; + } +}); + +canvas.addEventListener('mouseout', function(e) { + window.cancelAnimationFrame(raf); + running = false; +}); + +ball.draw(); +</pre> + +<p>Mueve la bola usando el ratón y suéltala haciendo click.</p> + +<p>{{EmbedLiveSample("Adding_mouse_control", "610", "310")}}</p> + +<h2 id="Breakout">Breakout</h2> + +<p>Este capítulo corto sólo explica algunas técnicas para crear animaciones más avanzadas. ¡Hay muchos más! ¿Qué tal agregar una raqueta, algunos ladrillos, y convertir esta demo en un partido <a href="http://en.wikipedia.org/wiki/Breakout_%28video_game%29">Breakout</a>? Visita nuestra área de <a href="/en-US/docs/Games">Game development</a> para mayor información.</p> + +<h2 id="Vea_también">Vea también</h2> + +<ul> + <li>{{domxref("window.requestAnimationFrame()")}}</li> + <li><a href="/en-US/docs/Games/Techniques/Efficient_animation_for_web_games">Efficient animation for web games</a></li> +</ul> + +<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}</p> diff --git a/files/es/web/guide/html/canvas_tutorial/applying_styles_and_colors/index.html b/files/es/web/guide/html/canvas_tutorial/applying_styles_and_colors/index.html new file mode 100644 index 0000000000..ab76918132 --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/applying_styles_and_colors/index.html @@ -0,0 +1,726 @@ +--- +title: Applying styles and colors +slug: Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors +translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}</div> + +<div class="summary"> +<p>En el capítulo acerca de dibujar formas, usamos unicamente los estilos de linea y de relleno por defecto. Aqui exploraremos las opciones del canvas que tenemos a nuestra disposición para hacer los dibujos un tanto más atractivos. Aprenderas como agregar diferentes colores, estilos de linea, gradiantes, patrones y sombras a tus dibujos.</p> +</div> + +<h2 id="Colors" name="Colors">Colors</h2> + +<p>Hasta ahrora nosotros solo me hemos visto metodos en el contexto de dibujo. Si quisieramos aplicar colores a las formas, hay dos importantes propiedades que podemos usar: <code>fillStyle</code> y <code>strokeStyle</code>.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}</dt> + <dd>Configura el estilo cuando se rellenan las formas.</dd> + <dt>{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}</dt> + <dd>Configura el estilo al contorno perimetral de las formas.</dd> +</dl> + +<p><code>color</code> es una cadena que representa un CSS {{cssxref("<color>")}}, un objeto gradiante, o un objeto patron. Miraremos en objetos de gradientes y patrones mas tarde. Por defecto, el color del trazo y del relleno son configurados en negro (valor de color CSS <code>#000000</code>).</p> + +<div class="note"> +<p><strong>Nota: </strong> Cuando configuras la propiedad <code>strokeStyle</code> y/o <code>fillStyle</code>, el nuevo valor llega a ser el vador por defecto para los dibujos posteriores. Para cada forma que tu quieras en un color difrente, necesitaras reasignar las propiedades anteriores.</p> +</div> + +<p>Las cadenas validas que tu pueden entrar deberian, segun la especificación, ser valores de {{cssxref("<color>")}} CSS. En el siguiente ejemplo, describimos en mismo color.</p> + +<pre class="brush: js">// these all set the fillStyle to 'orange' + +ctx.fillStyle = 'orange'; +ctx.fillStyle = '#FFA500'; +ctx.fillStyle = 'rgb(255, 165, 0)'; +ctx.fillStyle = 'rgba(255, 165, 0, 1)'; +</pre> + +<h3 id="A_fillStyle_example" name="A_fillStyle_example">A <code>fillStyle</code> example</h3> + +<p>En este ejemplo, usamos dos bucles for para dibujar una cuadrícula de rectangulos, cada uno de diferente color. La imagen resultante deberia ser similar a la de la screenhot. No hay nada demasiado espectacular en el proceso. Usamos dos variables i y j para generar un unico color RGB para cada celda cuadrada, modificando las componentes rojo y verde. El canal azul tiene un valor fijo. Modificando los canales, puedes generar todo tipo de paletas. Incrementando los paos, puedes lograr algo similar que se parezca a las paletas de colores que Photoshop usa.</p> + +<pre class="brush: js;highlight[5,6]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + for (var i = 0; i < 6; i++) { + for (var j = 0; j < 6; j++) { + ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ', ' + + Math.floor(255 - 42.5 * j) + ', 0)'; + ctx.fillRect(j * 25, i * 25, 25, 25); + } + } +}</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>The result looks like this:</p> + +<p>{{EmbedLiveSample("A_fillStyle_example", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}</p> + +<h3 id="A_strokeStyle_example" name="A_strokeStyle_example">A <code>strokeStyle</code> example</h3> + +<p>Este ejemplo es similar al de arriba, pero usa la propiedad <code>strokeStyle</code> para cambiar el color del contorno de las formas. Usamos el método <code>arc()</code> para dibujar circulos en lugar de celdas cuadradas.</p> + +<pre class="brush: js;highlight[5,6]"> function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + for (var i = 0; i < 6; i++) { + for (var j = 0; j < 6; j++) { + ctx.strokeStyle = 'rgb(0, ' + Math.floor(255 - 42.5 * i) + ', ' + + Math.floor(255 - 42.5 * j) + ')'; + ctx.beginPath(); + ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true); + ctx.stroke(); + } + } + } +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>The result looks like this:</p> + +<p>{{EmbedLiveSample("A_strokeStyle_example", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}</p> + +<h2 id="Transparency" name="Transparency">Transparency</h2> + +<p>Ademas de dibujar formas opacas en el canvas, podemos dibujar formas semi-transparentes(o translucidas). Esto se logra bien configurando la propiedad <code>globalAlpha</code> o asignando un color semi-transparente al estilo del trazo u u/y al de relleno.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}</dt> + <dd>Applies the specified transparency value to all future shapes drawn on the canvas. The value must be between 0.0 (fully transparent) to 1.0 (fully opaque). This value is 1.0 (fully opaque) by default.</dd> +</dl> + +<p>The <code>globalAlpha</code> property can be useful if you want to draw a lot of shapes on the canvas with similar transparency, but otherwise it's generally more useful to set the transparency on individual shapes when setting their colors.</p> + +<p>Debido qaque las propiedades <code>strokeStyle</code> y <code>fillStyle</code> aceptan valores de color rgba de CSS, podemos usar la siguiente notacion para asignar una color transparente a ellos.</p> + +<pre class="brush: js">// Assigning transparent colors to stroke and fill style + +ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)'; +ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; +</pre> + +<p>The <code>rgba()</code> function is similar to the <code>rgb()</code> function but it has one extra parameter. The last parameter sets the transparency value of this particular color. The valid range is again between 0.0 (fully transparent) and 1.0 (fully opaque).</p> + +<h3 id="A_globalAlpha_example" name="A_globalAlpha_example">A <code>globalAlpha</code> example</h3> + +<p>In this example, we'll draw a background of four different colored squares. On top of these, we'll draw a set of semi-transparent circles. The <code>globalAlpha</code> property is set at <code>0.2</code> which will be used for all shapes from that point on. Every step in the <code>for</code> loop draws a set of circles with an increasing radius. The final result is a radial gradient. By overlaying ever more circles on top of each other, we effectively reduce the transparency of the circles that have already been drawn. By increasing the step count and in effect drawing more circles, the background would completely disappear from the center of the image.</p> + +<pre class="brush: js;highlight[15]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + // draw background + ctx.fillStyle = '#FD0'; + ctx.fillRect(0, 0, 75, 75); + ctx.fillStyle = '#6C0'; + ctx.fillRect(75, 0, 75, 75); + ctx.fillStyle = '#09F'; + ctx.fillRect(0, 75, 75, 75); + ctx.fillStyle = '#F30'; + ctx.fillRect(75, 75, 75, 75); + ctx.fillStyle = '#FFF'; + + // set transparency value + ctx.globalAlpha = 0.2; + + // Draw semi transparent circles + for (var i = 0; i < 7; i++) { + ctx.beginPath(); + ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true); + ctx.fill(); + } +}</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>{{EmbedLiveSample("A_globalAlpha_example", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}</p> + +<h3 id="An_example_using_rgba" name="An_example_using_rgba()">An example using <code>rgba()</code></h3> + +<p>In this second example, we do something similar to the one above, but instead of drawing circles on top of each other, I've drawn small rectangles with increasing opacity. Using <code>rgba()</code> gives you a little more control and flexibility because we can set the fill and stroke style individually.</p> + +<pre class="brush: js;highlight[16]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + // Draw background + ctx.fillStyle = 'rgb(255, 221, 0)'; + ctx.fillRect(0, 0, 150, 37.5); + ctx.fillStyle = 'rgb(102, 204, 0)'; + ctx.fillRect(0, 37.5, 150, 37.5); + ctx.fillStyle = 'rgb(0, 153, 255)'; + ctx.fillRect(0, 75, 150, 37.5); + ctx.fillStyle = 'rgb(255, 51, 0)'; + ctx.fillRect(0, 112.5, 150, 37.5); + + // Draw semi transparent rectangles + for (var i = 0; i < 10; i++) { + ctx.fillStyle = 'rgba(255, 255, 255, ' + (i + 1) / 10 + ')'; + for (var j = 0; j < 4; j++) { + ctx.fillRect(5 + i * 14, 5 + j * 37.5, 14, 27.5); + } + } +}</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>{{EmbedLiveSample("An_example_using_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}</p> + +<h2 id="Line_styles" name="Line_styles">Line styles</h2> + +<p>There are several properties which allow us to style lines.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}</dt> + <dd>Sets the width of lines drawn in the future.</dd> + <dt>{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}</dt> + <dd>Sets the appearance of the ends of lines.</dd> + <dt>{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}</dt> + <dd>Sets the appearance of the "corners" where lines meet.</dd> + <dt>{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}</dt> + <dd>Establishes a limit on the miter when two lines join at a sharp angle, to let you control how thick the junction becomes.</dd> + <dt>{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}</dt> + <dd>Returns the current line dash pattern array containing an even number of non-negative numbers.</dd> + <dt>{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}</dt> + <dd>Sets the current line dash pattern.</dd> + <dt>{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}</dt> + <dd>Specifies where to start a dash array on a line.</dd> +</dl> + +<p>You'll get a better understanding of what these do by looking at the examples below.</p> + +<h3 id="A_lineWidth_example" name="A_lineWidth_example">A <code>lineWidth</code> example</h3> + +<p>This property sets the current line thickness. Values must be positive numbers. By default this value is set to 1.0 units.</p> + +<p>The line width is the thickness of the stroke centered on the given path. In other words, the area that's drawn extends to half the line width on either side of the path. Because canvas coordinates do not directly reference pixels, special care must be taken to obtain crisp horizontal and vertical lines.</p> + +<p>In the example below, 10 straight lines are drawn with increasing line widths. The line on the far left is 1.0 units wide. However, the leftmost and all other odd-integer-width thickness lines do not appear crisp, because of the path's positioning.</p> + +<pre class="brush: js;highlight[4]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + for (var i = 0; i < 10; i++) { + ctx.lineWidth = 1 + i; + ctx.beginPath(); + ctx.moveTo(5 + i * 14, 5); + ctx.lineTo(5 + i * 14, 140); + ctx.stroke(); + } +} +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>{{EmbedLiveSample("A_lineWidth_example", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}</p> + +<p>Obtaining crisp lines requires understanding how paths are stroked. In the images below, the grid represents the canvas coordinate grid. The squares between gridlines are actual on-screen pixels. In the first grid image below, a rectangle from (2,1) to (5,5) is filled. The entire area between them (light red) falls on pixel boundaries, so the resulting filled rectangle will have crisp edges.</p> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/201/Canvas-grid.png"></p> + +<p>If you consider a path from (3,1) to (3,5) with a line thickness of <code>1.0</code>, you end up with the situation in the second image. The actual area to be filled (dark blue) only extends halfway into the pixels on either side of the path. An approximation of this has to be rendered, which means that those pixels being only partially shaded, and results in the entire area (the light blue and dark blue) being filled in with a color only half as dark as the actual stroke color. This is what happens with the <code>1.0</code> width line in the previous example code.</p> + +<p>To fix this, you have to be very precise in your path creation. Knowing that a <code>1.0</code> width line will extend half a unit to either side of the path, creating the path from (3.5,1) to (3.5,5) results in the situation in the third image—the <code>1.0</code> line width ends up completely and precisely filling a single pixel vertical line.</p> + +<div class="note"> +<p><strong>Note:</strong> Be aware that in our vertical line example, the Y position still referenced an integer gridline position—if it hadn't, we would see pixels with half coverage at the endpoints (but note also that this behavior depends on the current <code>lineCap</code> style whose default value is <code>butt</code>; you may want to compute consistent strokes with half-pixel coordinates for odd-width lines, by setting the <code>lineCap</code> style to <code>square</code>, so that the outer border of the stroke around the endpoint will be automatically extended to cover the whole pixel exactly).</p> + +<p>Note also that only start and final endpoints of a path are affected: if a path is closed with <code>closePath()</code>, there's no start and final endpoint; instead, all endpoints in the path are connected to their attached previous and next segment using the current setting of the <code>lineJoin</code> style, whose default value is <code>miter</code>, with the effect of automatically extending the outer borders of the connected segments to their intersection point, so that the rendered stroke will exactly cover full pixels centered at each endpoint if those connected segments are horizontal and/or vertical). See the next two sections for demonstrations of these additional line styles.</p> +</div> + +<p>For even-width lines, each half ends up being an integer amount of pixels, so you want a path that is between pixels (that is, (3,1) to (3,5)), instead of down the middle of pixels.</p> + +<p>While slightly painful when initially working with scalable 2D graphics, paying attention to the pixel grid and the position of paths ensures that your drawings will look correct regardless of scaling or any other transformations involved. A 1.0-width vertical line drawn at the correct position will become a crisp 2-pixel line when scaled up by 2, and will appear at the correct position.</p> + +<h3 id="A_lineCap_example" name="A_lineCap_example">A <code>lineCap</code> example</h3> + +<p>The <code>lineCap</code> property determines how the end points of every line are drawn. There are three possible values for this property and those are: <code>butt</code>, <code>round</code> and <code>square</code>. By default this property is set to <code>butt</code>.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/236/Canvas_linecap.png" style="float: right; height: 190px; width: 190px;"></p> + +<dl> + <dt><code>butt</code></dt> + <dd>The ends of lines are squared off at the endpoints.</dd> + <dt><code>round</code></dt> + <dd>The ends of lines are rounded.</dd> + <dt><code>square</code></dt> + <dd>The ends of lines are squared off by adding a box with an equal width and half the height of the line's thickness.</dd> +</dl> + +<p>In this example, we'll draw three lines, each with a different value for the <code>lineCap</code> property. I also added two guides to see the exact differences between the three. Each of these lines starts and ends exactly on these guides.</p> + +<p>The line on the left uses the default <code>butt</code> option. You'll notice that it's drawn completely flush with the guides. The second is set to use the <code>round</code> option. This adds a semicircle to the end that has a radius half the width of the line. The line on the right uses the <code>square</code> option. This adds a box with an equal width and half the height of the line thickness.</p> + +<pre class="brush: js;highlight[18]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + var lineCap = ['butt', 'round', 'square']; + + // Draw guides + ctx.strokeStyle = '#09f'; + ctx.beginPath(); + ctx.moveTo(10, 10); + ctx.lineTo(140, 10); + ctx.moveTo(10, 140); + ctx.lineTo(140, 140); + ctx.stroke(); + + // Draw lines + ctx.strokeStyle = 'black'; + for (var i = 0; i < lineCap.length; i++) { + ctx.lineWidth = 15; + ctx.lineCap = lineCap[i]; + ctx.beginPath(); + ctx.moveTo(25 + i * 50, 10); + ctx.lineTo(25 + i * 50, 140); + ctx.stroke(); + } +} +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>{{EmbedLiveSample("A_lineCap_example", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}</p> + +<h3 id="A_lineJoin_example" name="A_lineJoin_example">A <code>lineJoin</code> example</h3> + +<p>The <code>lineJoin</code> property determines how two connecting segments (of lines, arcs or curves) with non-zero lengths in a shape are joined together (degenerate segments with zero lengths, whose specified endpoints and control points are exactly at the same position, are skipped).</p> + +<p>There are three possible values for this property: <code>round</code>, <code>bevel</code> and <code>miter</code>. By default this property is set to <code>miter</code>. Note that the <code>lineJoin</code> setting has no effect if the two connected segments have the same direction, because no joining area will be added in this case.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/237/Canvas_linejoin.png" style="float: right; height: 190px; width: 190px;"></p> + +<dl> + <dt><code>round</code></dt> + <dd>Rounds off the corners of a shape by filling an additional sector of disc centered at the common endpoint of connected segments. The radius for these rounded corners is equal to half the line width.</dd> + <dt><code>bevel</code></dt> + <dd>Fills an additional triangular area between the common endpoint of connected segments, and the separate outside rectangular corners of each segment.</dd> + <dt><code>miter</code></dt> + <dd>Connected segments are joined by extending their outside edges to connect at a single point, with the effect of filling an additional lozenge-shaped area. This setting is effected by the <code>miterLimit</code> property which is explained below.</dd> +</dl> + +<p>The example below draws three different paths, demonstrating each of these three <code>lineJoin</code> property settings; the output is shown above.</p> + +<pre class="brush: js;highlight[6]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + var lineJoin = ['round', 'bevel', 'miter']; + ctx.lineWidth = 10; + for (var i = 0; i < lineJoin.length; i++) { + ctx.lineJoin = lineJoin[i]; + ctx.beginPath(); + ctx.moveTo(-5, 5 + i * 40); + ctx.lineTo(35, 45 + i * 40); + ctx.lineTo(75, 5 + i * 40); + ctx.lineTo(115, 45 + i * 40); + ctx.lineTo(155, 5 + i * 40); + ctx.stroke(); + } +} +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>{{EmbedLiveSample("A_lineJoin_example", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}</p> + +<h3 id="A_demo_of_the_miterLimit_property" name="A_demo_of_the_miterLimit_property">A demo of the <code>miterLimit</code> property</h3> + +<p>As you've seen in the previous example, when joining two lines with the <code>miter</code> option, the outside edges of the two joining lines are extended up to the point where they meet. For lines which are at large angles with each other, this point is not far from the inside connection point. However, as the angles between each line decreases, the distance (miter length) between these points increases exponentially.</p> + +<p>The <code>miterLimit</code> property determines how far the outside connection point can be placed from the inside connection point. If two lines exceed this value, a bevel join gets drawn instead. Note that the maximum miter length is the product of the line width measured in the current coordinate system, by the value of this <code>miterLimit</code> property (whose default value is 10.0 in the HTML {{HTMLElement("canvas")}}), so the <code>miterLimit</code> can be set independently from the current display scale or any affine transforms of paths: it only influences the effectively rendered shape of line edges.</p> + +<p>More exactly, the miter limit is the maximum allowed ratio of the extension length (in the HTML canvas, it is measured between the outside corner of the joined edges of the line and the common endpoint of connecting segments specified in the path) to half the line width. It can equivalently be defined as the maximum allowed ratio of the distance between the inside and outside points of jonction of edges, to the total line width. It is then equal to the cosecant of half the minimum inner angle of connecting segments below which no miter join will be rendered, but only a bevel join:</p> + +<ul> + <li><code>miterLimit</code> = <strong>max</strong> <code>miterLength</code> / <code>lineWidth</code> = 1 / <strong>sin</strong> ( <strong>min</strong> <em>θ</em> / 2 )</li> + <li>The default miter limit of 10.0 will strip all miters for sharp angles below about 11 degrees.</li> + <li>A miter limit equal to √2 ≈ 1.4142136 (rounded up) will strip miters for all acute angles, keeping miter joins only for obtuse or right angles.</li> + <li>A miter limit equal to 1.0 is valid but will disable all miters.</li> + <li>Values below 1.0 are invalid for the miter limit.</li> +</ul> + +<p>Here's a little demo in which you can set <code>miterLimit</code> dynamically and see how this effects the shapes on the canvas. The blue lines show where the start and endpoints for each of the lines in the zig-zag pattern are.</p> + +<p>If you specify a <code>miterLimit</code> value below 4.2 in this demo, none of the visible corners will join with a miter extension, but only with a small bevel near the blue lines; with a <code>miterLimit</code> above 10, most corners in this demo should join with a miter far away from the blue lines, and whose height is decreasing between corners from left to right because they connect with growing angles; with intermediate values, the corners on the left side will only join with a bevel near the blue lines, and the corners on the right side with a miter extension (also with a decreasing height).</p> + +<pre class="brush: js;highlight[18]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + // Clear canvas + ctx.clearRect(0, 0, 150, 150); + + // Draw guides + ctx.strokeStyle = '#09f'; + ctx.lineWidth = 2; + ctx.strokeRect(-5, 50, 160, 50); + + // Set line styles + ctx.strokeStyle = '#000'; + ctx.lineWidth = 10; + + // check input + if (document.getElementById('miterLimit').value.match(/\d+(\.\d+)?/)) { + ctx.miterLimit = parseFloat(document.getElementById('miterLimit').value); + } else { + alert('Value must be a positive number'); + } + + // Draw lines + ctx.beginPath(); + ctx.moveTo(0, 100); + for (i = 0; i < 24 ; i++) { + var dy = i % 2 == 0 ? 25 : -25; + ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy); + } + ctx.stroke(); + return false; +} +</pre> + +<div class="hidden"> +<pre class="brush: html"><table> + <tr> + <td><canvas id="canvas" width="150" height="150"></canvas></td> + <td>Change the <code>miterLimit</code> by entering a new value below and clicking the redraw button.<br><br> + <form onsubmit="return draw();"> + <label>Miter limit</label> + <input type="number" size="3" id="miterLimit"/> + <input type="submit" value="Redraw"/> + </form> + </td> + </tr> +</table></pre> + +<pre class="brush: js">document.getElementById('miterLimit').value = document.getElementById('canvas').getContext('2d').miterLimit; +draw();</pre> +</div> + +<p>{{EmbedLiveSample("A_demo_of_the_miterLimit_property", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}</p> + +<h3 id="Using_line_dashes">Using line dashes</h3> + +<p>The <code>setLineDash</code> method and the <code>lineDashOffset</code> property specify the dash pattern for lines. The <code>setLineDash</code> method accepts a list of numbers that specifies distances to alternately draw a line and a gap and the <code>lineDashOffset</code> property sets an offset where to start the pattern.</p> + +<p>In this example we are creating a marching ants effect. It is an animation technique often found in <span class="new">selection</span> tools of computer graphics programs. It helps the user to distinguish the selection border from the image background by animating the border. In a later part of this tutorial, you can learn how to do this and other <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations">basic animations</a>.</p> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="110" height="110"></canvas></pre> +</div> + +<pre class="brush: js;highlight[6]">var ctx = document.getElementById('canvas').getContext('2d'); +var offset = 0; + +function draw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.setLineDash([4, 2]); + ctx.lineDashOffset = -offset; + ctx.strokeRect(10, 10, 100, 100); +} + +function march() { + offset++; + if (offset > 16) { + offset = 0; + } + draw(); + setTimeout(march, 20); +} + +march();</pre> + +<p>{{EmbedLiveSample("Using_line_dashes", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}</p> + +<h2 id="Gradients" name="Gradients">Gradients</h2> + +<p>Just like any normal drawing program, we can fill and stroke shapes using linear and radial gradients. We create a {{domxref("CanvasGradient")}} object by using one of the following methods. We can then assign this object to the <code>fillStyle</code> or <code>strokeStyle</code> properties.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}</dt> + <dd>Creates a linear gradient object with a starting point of (<code>x1</code>, <code>y1</code>) and an end point of (<code>x2</code>, <code>y2</code>).</dd> + <dt>{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}</dt> + <dd>Creates a radial gradient. The parameters represent two circles, one with its center at (<code>x1</code>, <code>y1</code>) and a radius of <code>r1</code>, and the other with its center at (<code>x2</code>, <code>y2</code>) with a radius of <code>r2</code>.</dd> +</dl> + +<p>For example:</p> + +<pre class="brush: js">var lineargradient = ctx.createLinearGradient(0, 0, 150, 150); +var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100); +</pre> + +<p>Once we've created a <code>CanvasGradient</code> object we can assign colors to it by using the <code>addColorStop()</code> method.</p> + +<dl> + <dt>{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}</dt> + <dd>Creates a new color stop on the <code>gradient</code> object. The <code>position</code> is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the <code>color</code> argument must be a string representing a CSS {{cssxref("<color>")}}, indicating the color the gradient should reach at that offset into the transition.</dd> +</dl> + +<p>You can add as many color stops to a gradient as you need. Below is a very simple linear gradient from white to black.</p> + +<pre class="brush: js">var lineargradient = ctx.createLinearGradient(0, 0, 150, 150); +lineargradient.addColorStop(0, 'white'); +lineargradient.addColorStop(1, 'black'); +</pre> + +<h3 id="A_createLinearGradient_example" name="A_createLinearGradient_example">A <code>createLinearGradient</code> example</h3> + +<p>In this example, we'll create two different gradients. As you can see here, both the <code>strokeStyle</code> and <code>fillStyle</code> properties can accept a <code>canvasGradient</code> object as valid input.</p> + +<pre class="brush: js;highlight[5,11]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + // Create gradients + var lingrad = ctx.createLinearGradient(0, 0, 0, 150); + lingrad.addColorStop(0, '#00ABEB'); + lingrad.addColorStop(0.5, '#fff'); + lingrad.addColorStop(0.5, '#26C000'); + lingrad.addColorStop(1, '#fff'); + + var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95); + lingrad2.addColorStop(0.5, '#000'); + lingrad2.addColorStop(1, 'rgba(0, 0, 0, 0)'); + + // assign gradients to fill and stroke styles + ctx.fillStyle = lingrad; + ctx.strokeStyle = lingrad2; + + // draw shapes + ctx.fillRect(10, 10, 130, 130); + ctx.strokeRect(50, 50, 50, 50); + +} +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>The first is a background gradient. As you can see, we assigned two colors at the same position. You do this to make very sharp color transitions—in this case from white to green. Normally, it doesn't matter in what order you define the color stops, but in this special case, it does significantly. If you keep the assignments in the order you want them to appear, this won't be a problem.</p> + +<p>In the second gradient, we didn't assign the starting color (at position 0.0) since it wasn't strictly necessary, because it will automatically assume the color of the next color stop. Therefore, assigning the black color at position 0.5 automatically makes the gradient, from the start to this stop, black.</p> + +<p>{{EmbedLiveSample("A_createLinearGradient_example", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}</p> + +<h3 id="A_createRadialGradient_example" name="A_createRadialGradient_example">A <code>createRadialGradient</code> example</h3> + +<p>In this example, we'll define four different radial gradients. Because we have control over the start and closing points of the gradient, we can achieve more complex effects than we would normally have in the "classic" radial gradients we see in, for instance, Photoshop (that is, a gradient with a single center point where the gradient expands outward in a circular shape).</p> + +<pre class="brush: js;highlight[5,10,15,20]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + // Create gradients + var radgrad = ctx.createRadialGradient(45, 45, 10, 52, 50, 30); + radgrad.addColorStop(0, '#A7D30C'); + radgrad.addColorStop(0.9, '#019F62'); + radgrad.addColorStop(1, 'rgba(1, 159, 98, 0)'); + + var radgrad2 = ctx.createRadialGradient(105, 105, 20, 112, 120, 50); + radgrad2.addColorStop(0, '#FF5F98'); + radgrad2.addColorStop(0.75, '#FF0188'); + radgrad2.addColorStop(1, 'rgba(255, 1, 136, 0)'); + + var radgrad3 = ctx.createRadialGradient(95, 15, 15, 102, 20, 40); + radgrad3.addColorStop(0, '#00C9FF'); + radgrad3.addColorStop(0.8, '#00B5E2'); + radgrad3.addColorStop(1, 'rgba(0, 201, 255, 0)'); + + var radgrad4 = ctx.createRadialGradient(0, 150, 50, 0, 140, 90); + radgrad4.addColorStop(0, '#F4F201'); + radgrad4.addColorStop(0.8, '#E4C700'); + radgrad4.addColorStop(1, 'rgba(228, 199, 0, 0)'); + + // draw shapes + ctx.fillStyle = radgrad4; + ctx.fillRect(0, 0, 150, 150); + ctx.fillStyle = radgrad3; + ctx.fillRect(0, 0, 150, 150); + ctx.fillStyle = radgrad2; + ctx.fillRect(0, 0, 150, 150); + ctx.fillStyle = radgrad; + ctx.fillRect(0, 0, 150, 150); +} +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>In this case, we've offset the starting point slightly from the end point to achieve a spherical 3D effect. It's best to try to avoid letting the inside and outside circles overlap because this results in strange effects which are hard to predict.</p> + +<p>The last color stop in each of the four gradients uses a fully transparent color. If you want to have a nice transition from this to the previous color stop, both colors should be equal. This isn't very obvious from the code because it uses two different CSS color methods as a demonstration, but in the first gradient <code>#019F62 = rgba(1,159,98,1)</code>.</p> + +<p>{{EmbedLiveSample("A_createRadialGradient_example", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}</p> + +<h2 id="Patterns" name="Patterns">Patterns</h2> + +<p>In one of the examples on the previous page, we used a series of loops to create a pattern of images. There is, however, a much simpler method: the <code>createPattern()</code> method.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}</dt> + <dd>Creates and returns a new canvas pattern object. <code>image</code> is a {{domxref("CanvasImageSource")}} (that is, an {{domxref("HTMLImageElement")}}, another canvas, a {{HTMLElement("video")}} element, or the like. <code>type</code> is a string indicating how to use the image.</dd> +</dl> + +<p>The type specifies how to use the image in order to create the pattern, and must be one of the following string values:</p> + +<dl> + <dt><code>repeat</code></dt> + <dd>Tiles the image in both vertical and horizontal directions.</dd> + <dt><code>repeat-x</code></dt> + <dd>Tiles the image horizontally but not vertically.</dd> + <dt><code>repeat-y</code></dt> + <dd>Tiles the image vertically but not horizontally.</dd> + <dt><code>no-repeat</code></dt> + <dd>Doesn't tile the image. It's used only once.</dd> +</dl> + +<p>We use this method to create a {{domxref("CanvasPattern")}} object which is very similar to the gradient methods we've seen above. Once we've created a pattern, we can assign it to the <code>fillStyle</code> or <code>strokeStyle</code> properties. For example:</p> + +<pre class="brush: js">var img = new Image(); +img.src = 'someimage.png'; +var ptrn = ctx.createPattern(img, 'repeat'); +</pre> + +<div class="note"> +<p><strong>Note:</strong> Like with the <code>drawImage()</code> method, you must make sure the image you use is loaded before calling this method or the pattern may be drawn incorrectly.</p> +</div> + +<h3 id="A_createPattern_example" name="A_createPattern_example">A <code>createPattern</code> example</h3> + +<p>In this last example, we'll create a pattern to assign to the <code>fillStyle</code> property. The only thing worth noting is the use of the image's <code>onload</code> handler. This is to make sure the image is loaded before it is assigned to the pattern.</p> + +<pre class="brush: js;highlight[10]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + // create new image object to use as pattern + var img = new Image(); + img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png'; + img.onload = function() { + + // create pattern + var ptrn = ctx.createPattern(img, 'repeat'); + ctx.fillStyle = ptrn; + ctx.fillRect(0, 0, 150, 150); + + } +} +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js">draw();</pre> + +<p>The result looks like this:</p> +</div> + +<p>{{EmbedLiveSample("A_createPattern_example", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}</p> + +<h2 id="Shadows">Shadows</h2> + +<p>Using shadows involves just four properties:</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}</dt> + <dd>Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.</dd> + <dt>{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}</dt> + <dd>Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.</dd> + <dt>{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}</dt> + <dd>Indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.</dd> + <dt>{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}</dt> + <dd>A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.</dd> +</dl> + +<p>The properties <code>shadowOffsetX</code> and <code>shadowOffsetY</code> indicate how far the shadow should extend from the object in the X and Y directions; these values aren't affected by the current transformation matrix. Use negative values to cause the shadow to extend up or to the left, and positive values to cause the shadow to extend down or to the right. These are both 0 by default.</p> + +<p>The <code>shadowBlur</code> property indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.</p> + +<p>The <code>shadowColor</code> property is a standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.</p> + +<div class="note"> +<p><strong>Note:</strong> Shadows are only drawn for <code>source-over</code> <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing" title="Web/Guide/HTML/Canvas_tutorial/Compositing">compositing operations</a>.</p> +</div> + +<h3 id="A_shadowed_text_example">A shadowed text example</h3> + +<p>This example draws a text string with a shadowing effect.</p> + +<pre class="brush: js;highlight[4,5,6,7]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + ctx.shadowOffsetX = 2; + ctx.shadowOffsetY = 2; + ctx.shadowBlur = 2; + ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'; + + ctx.font = '20px Times New Roman'; + ctx.fillStyle = 'Black'; + ctx.fillText('Sample String', 5, 30); +} +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="80"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>{{EmbedLiveSample("A_shadowed_text_example", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}</p> + +<p>We will look at the <code>font</code> property and <code>fillText</code> method in the next chapter about <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text">drawing text</a>.</p> + +<h2 id="Canvas_fill_rules">Canvas fill rules</h2> + +<p>When using <code>fill</code> (or {{domxref("CanvasRenderingContext2D.clip", "clip")}} and {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}}) you can optionally provide a fill rule algorithm by which to determine if a point is inside or outside a path and thus if it gets filled or not. This is useful when a path intersects itself or is nested.<br> + <br> + Two values are possible:</p> + +<ul> + <li><code><strong>"nonzero</strong></code>": The <a class="external external-icon" href="http://en.wikipedia.org/wiki/Nonzero-rule">non-zero winding rule</a>, which is the default rule.</li> + <li><code><strong>"evenodd"</strong></code>: The <a class="external external-icon" href="http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule">even-odd winding rule</a>.</li> +</ul> + +<p>In this example we are using the <code>evenodd</code> rule.</p> + +<pre class="brush: js;highlight[6]">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + ctx.beginPath(); + ctx.arc(50, 50, 30, 0, Math.PI * 2, true); + ctx.arc(50, 50, 15, 0, Math.PI * 2, true); + ctx.fill('evenodd'); +}</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="100" height="100"></canvas></pre> + +<pre class="brush: js">draw();</pre> +</div> + +<p>{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}</p> + +<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}</p> diff --git a/files/es/web/guide/html/canvas_tutorial/basic_animations/index.html b/files/es/web/guide/html/canvas_tutorial/basic_animations/index.html new file mode 100644 index 0000000000..94c66fb05d --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/basic_animations/index.html @@ -0,0 +1,333 @@ +--- +title: Animaciones básicas +slug: Web/Guide/HTML/Canvas_tutorial/Basic_animations +tags: + - Canvas + - HTML5 + - Intermedio + - Tutorial + - graficos +translation_of: Web/API/Canvas_API/Tutorial/Basic_animations +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}</div> + +<div class="summary"> +<p>Ya que estamos usando JavaScript para controlar elementos {{HTMLElement("canvas")}} , también es muy fácil hacer animaciones (interactivas). En este capitulo veremos como hacer algunas animaciones básicas.</p> +</div> + +<p>Probablemente la mayor limitación es que una vez que se dibuja una forma, se mantiene de esa manera. Si necesitamos moverlo tenemos que volver a dibujarlo y todo lo que se dibujó antes. Se necesita mucho tiempo para volver a dibujar estructuras complejas y el rendimiento depende en gran medida de la velocidad de la computadora en la que se ejecuta.</p> + +<h2 id="Basic_animation_steps" name="Basic_animation_steps">Pasos básicos de animación</h2> + +<p>Estos son los pasos que necesitas para dibujar un cuadro:</p> + +<ol> + <li><strong>Limpiar el canvas</strong><br> + A menos que las formas que vas a dibujar llenen el canvas completo (por ejemplo, una imagen de fondo), debes borrar cualquier forma que haya dibujado previamente. La forma más fácil de hacerlo es usar el método {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}.</li> + <li><strong>Guardar el estado del canvas</strong><br> + Si estás cambiando alguna configuración (como estilos, transformaciones, etc.) que afecte el estado del canvas y deseas asegurarte de que se utiliza el estado original cada vez que se dibuja una figura, debes guardar ese estado original. </li> + <li><strong>Dibujar formas animadas</strong><br> + El paso en el que realizas el renderizado del cuadro actual.</li> + <li><strong>Restaurar el estado del canvas</strong><br> + Si has guardado el estado, restáuralo antes de dibujar un nuevo cuadro.</li> +</ol> + +<h2 id="Controlling_an_animation" name="Controlling_an_animation">Controlando una animación</h2> + +<p>Las formas se dibujan en el canvas utilizando los métodos de canvas directamente o llamando a funciones personalizadas. En circunstancias normales, solo vemos que estos resultados aparecen en el canvas cuando el script termina de ejecutarse. Por ejemplo, no es posible hacer una animación desde un bucle <code>for</code>.</p> + +<p>Eso significa que necesitamos una forma de ejecutar nuestras funciones de dibujo durante un período de tiempo. Hay dos formas de controlar una animación como esta.</p> + +<h3 id="Actualizaciones_Programadas">Actualizaciones Programadas</h3> + +<p>Primero {{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}}, y {{domxref("window.requestAnimationFrame()")}} son funciones que pueden ser usadas para llamar una función especifica en un periodo de tiempo establecido.</p> + +<dl> + <dt>{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}</dt> + <dd>Ejecuta una función especificada por <code>function</code> cada <code>delay</code> milisegundos.</dd> + <dt>{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}</dt> + <dd>Ejecuta una función especificada por <code>function</code> dentro de <code>delay</code> milisegundos.</dd> + <dt>{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}</dt> + <dd>Comunica al navegador que deseas iniciar una animación y requieres que el navegador llame a las funciones especificas para actualizar la misma antes de la siguiente escena.</dd> +</dl> + +<p>Si no quieres ninguna interacción del usuario puedes usar la función <code>setInterval()</code> que repite la ejecución del código suministrado. Si lo que queremos es hacer un juego, podríamos usar eventos de teclado o el mouse para controlar la animación y usar <code>setTimeout()</code>. Al establecer los {{domxref("EventListener")}}, capturamos cualquier interacción del usuario y ejecutamos nuestras funciones de animación.</p> + +<div class="note"> +<p>En los siguiente ejemplo,usaremos el método para controlar animaciones {{domxref("window.requestAnimationFrame()")}}. El método <code>requestAnimationFrame</code> provee formas amigables y mas eficientes para animar llamando cada marco de animación cuando el sistema esta listo para dibujar. La cantidad de devoluciones de llamadas suele ser 60 veces por segundo y podría ser reducido a menor periodo cuando se corre en un segundo plano. Para mas información acerca de los ciclos de animación, especialmente para juegos, Ver el Articulo <a href="/es/docs/Games/Anatomy">Anatomía de un videojuego</a> en nuestra <a href="/en-US/docs/Games">GameZona de desarrollo de Juegos</a>.</p> +</div> + +<h2 id="Un_sistema_solar_animado">Un sistema solar animado</h2> + +<p>Este ejemplo animado es un pequeño modelo de nuestro sistema solar.</p> + +<pre class="brush: js">var sun = new Image(); +var moon = new Image(); +var earth = new Image(); +function init(){ + sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png'; + moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png'; + earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png'; + window.requestAnimationFrame(draw); +} + +function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + ctx.globalCompositeOperation = 'destination-over'; + ctx.clearRect(0,0,300,300); // limpiar canvas + + ctx.fillStyle = 'rgba(0,0,0,0.4)'; + ctx.strokeStyle = 'rgba(0,153,255,0.4)'; + ctx.save(); + ctx.translate(150,150); + + // La tierra + var time = new Date(); + ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() ); + ctx.translate(105,0); + ctx.fillRect(0,-12,50,24); // Sombra + ctx.drawImage(earth,-12,-12); + + // La luna + ctx.save(); + ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() ); + ctx.translate(0,28.5); + ctx.drawImage(moon,-3.5,-3.5); + ctx.restore(); + + ctx.restore(); + + ctx.beginPath(); + ctx.arc(150,150,105,0,Math.PI*2,false); // Órbita terrestre + ctx.stroke(); + + ctx.drawImage(sun,0,0,300,300); + + window.requestAnimationFrame(draw); +} + +init(); +</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="300" height="300"></canvas></pre> +</div> + +<p>{{EmbedLiveSample("Un_sistema_solar_animado", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}</p> + +<h2 id="Un_reloj_animado">Un reloj animado</h2> + +<p>Este ejemplo dibuja una reloj animado, mostrando la hora actual.</p> + +<pre class="brush: js">function clock(){ + var now = new Date(); + var ctx = document.getElementById('canvas').getContext('2d'); + ctx.save(); + ctx.clearRect(0,0,150,150); + ctx.translate(75,75); + ctx.scale(0.4,0.4); + ctx.rotate(-Math.PI/2); + ctx.strokeStyle = "black"; + ctx.fillStyle = "white"; + ctx.lineWidth = 8; + ctx.lineCap = "round"; + + // Aguja de la hora + ctx.save(); + for (var i=0;i<12;i++){ + ctx.beginPath(); + ctx.rotate(Math.PI/6); + ctx.moveTo(100,0); + ctx.lineTo(120,0); + ctx.stroke(); + } + ctx.restore(); + + // Aguja del minuto + ctx.save(); + ctx.lineWidth = 5; + for (i=0;i<60;i++){ + if (i%5!=0) { + ctx.beginPath(); + ctx.moveTo(117,0); + ctx.lineTo(120,0); + ctx.stroke(); + } + ctx.rotate(Math.PI/30); + } + ctx.restore(); + + var sec = now.getSeconds(); + var min = now.getMinutes(); + var hr = now.getHours(); + hr = hr>=12 ? hr-12 : hr; + + ctx.fillStyle = "black"; + + // Escribimos la hora + ctx.save(); + ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec ) + ctx.lineWidth = 14; + ctx.beginPath(); + ctx.moveTo(-20,0); + ctx.lineTo(80,0); + ctx.stroke(); + ctx.restore(); + + // escribimos los minutos + ctx.save(); + ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec ) + ctx.lineWidth = 10; + ctx.beginPath(); + ctx.moveTo(-28,0); + ctx.lineTo(112,0); + ctx.stroke(); + ctx.restore(); + + // escribimos los segundos + ctx.save(); + ctx.rotate(sec * Math.PI/30); + ctx.strokeStyle = "#D40000"; + ctx.fillStyle = "#D40000"; + ctx.lineWidth = 6; + ctx.beginPath(); + ctx.moveTo(-30,0); + ctx.lineTo(83,0); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(0,0,10,0,Math.PI*2,true); + ctx.fill(); + ctx.beginPath(); + ctx.arc(95,0,10,0,Math.PI*2,true); + ctx.stroke(); + ctx.fillStyle = "rgba(0,0,0,0)"; + ctx.arc(0,0,3,0,Math.PI*2,true); + ctx.fill(); + ctx.restore(); + + ctx.beginPath(); + ctx.lineWidth = 14; + ctx.strokeStyle = '#325FA2'; + ctx.arc(0,0,142,0,Math.PI*2,true); + ctx.stroke(); + + ctx.restore(); + + window.requestAnimationFrame(clock); +} + +window.requestAnimationFrame(clock);</pre> + +<div class="hidden"> +<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre> +</div> + +<p>{{EmbedLiveSample("Un_reloj_animado", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}</p> + +<h2 id="Un_panorama_en_bucle">Un panorama en bucle</h2> + +<p>En este ejemplo, una foto panorámica avanza de izquierda a derecha. Donde usaremos <a href="http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg" title="http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg">una imagen del Parque Nacional de Yosemite</a> que tomamos de Wikipedia, pero tu podrías usar cualquier imagen que sea mas grande que el canvas.</p> + +<pre class="brush: js">var img = new Image(); + +// Variables de usuario - personalizar estas para cambiar la imagen cuando inicie el desplazamiento +// dirección y velocidad. + +img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg'; +var CanvasXSize = 800; +var CanvasYSize = 200; +var speed = 30; //más bajo es más rápido +var scale = 1.05; +var y = -4.5; //desplazamiento vertical + +// Programa principal + +var dx = 0.75; +var imgW; +var imgH; +var x = 0; +var clearX; +var clearY; +var ctx; + +img.onload = function() { + imgW = img.width * scale; + imgH = img.height * scale; + + if (imgW > CanvasXSize) { + // imagen más grande que canvas + x = CanvasXSize - imgW; + } + if (imgW > CanvasXSize) { + // ancho de imagen más grande que canvas + clearX = imgW; + } else { + clearX = CanvasXSize; + } + if (imgH > CanvasYSize) { + // altura de la imagen más grande que canvas + clearY = imgH; + } else { + clearY = CanvasYSize; + } + + // obtener contexto de canvas + ctx = document.getElementById('canvas').getContext('2d'); + + // establecer frecuencia de actualización + return setInterval(draw, speed); +} + +function draw() { + ctx.clearRect(0, 0, clearX, clearY); // clear the canvas + + // si la imagen es <= tamaño de Canvas + if (imgW <= CanvasXSize) { + // reiniciar, comenzar desde el principio + if (x > CanvasXSize) { + x = -imgW + x; + } + // dibujar image1 adicional + if (x > 0) { + ctx.drawImage(img, -imgW + x, y, imgW, imgH); + } + // dibujar image2 adicional + if (x - imgW > 0) { + ctx.drawImage(img, -imgW * 2 + x, y, imgW, imgH); + } + } + + // la imagen es > tamaño de Canvas + else { + // reiniciar, comenzar desde el principio + if (x > (CanvasXSize)) { + x = CanvasXSize - imgW; + } + // dibujar image adicional + if (x > (CanvasXSize-imgW)) { + ctx.drawImage(img, x - imgW + 1, y, imgW, imgH); + } + } + // dibujar imagen + ctx.drawImage(img, x, y,imgW, imgH); + // cantidad para moverse + x += dx; +}</pre> + +<p>Debajo esta el elemento {{HTMLElement("canvas")}} en el cual va la imagen se va ha desplazar. Nota que el ancho y el alto especificado aquí son las variables <code>CanvasXZSize</code> y <code>CanvasYSize</code>.</p> + +<pre class="brush: html"><canvas id="canvas" width="800" height="200"></canvas></pre> + +<p>{{EmbedLiveSample("Un_panorama_en_bucle", "830", "230")}}</p> + +<h2 id="Other_examples" name="Other_examples">Otros ejemplos</h2> + +<dl> + <dt><a href="/es/docs/Web/API/Canvas_API/A_basic_ray-caster" title="/en-US/docs/Web/Guide/HTML/A_basic_ray-caster">Un ray-caster básico</a></dt> + <dd>Un buen ejemplo de como hacer animaciones usando como control el teclado.</dd> + <dt><a href="/es/docs/Web/API/Canvas_API/Tutorial/Advanced_animations">Animaciones avanzadas</a></dt> + <dd>Vamos a echar un vistazo a algunas técnicas de animación avanzadas y física en el próximo capítulo.</dd> +</dl> + +<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}</p> diff --git a/files/es/web/guide/html/canvas_tutorial/basic_usage/index.html b/files/es/web/guide/html/canvas_tutorial/basic_usage/index.html new file mode 100644 index 0000000000..17136d7a7e --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/basic_usage/index.html @@ -0,0 +1,146 @@ +--- +title: Uso básico de Canvas +slug: Web/Guide/HTML/Canvas_tutorial/Basic_usage +translation_of: Web/API/Canvas_API/Tutorial/Basic_usage +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Dibujando_formas")}}</div> + +<div class="summary"> +<p>Comenzamos este tutorial observando el elemento {{HTMLElement("canvas")}}. Al final de esta página, sabrás como configurar el entorno 2D de canvas y habrás dibujado el primer ejemplo en tu navegador.</p> +</div> + +<h2 id="El_elemento_<canvas>">El elemento <code><canvas></code></h2> + +<pre class="brush: html"><canvas id="tutorial" width="150" height="150"></canvas> +</pre> + +<p>A primera vista, un elemento {{HTMLElement("canvas")}} es parecido al elemento {{HTMLElement("img")}}, con la diferencia que este no tiene los atributos <code>src</code> y <code>alt</code>. El elemento <code><canvas></code> tiene solo dos atributos - {{htmlattrxref("width", "canvas")}} y {{htmlattrxref("height", "canvas")}}. Ambos son opcionales y pueden ser definidos usando propiedades <a href="/en-US/docs/DOM" rel="internal" title="en/DOM">DOM</a>. Cuando los atributos ancho y alto no estan especificados, el lienzo se inicializara con <strong>300 pixels</strong> ancho y <strong>150 pixels</strong> de alto. El elemento puede ser arbitrariamente redimensionado por CSS, pero durante el renderizado la imagen es escalada para ajustarse al tamaño de su layout. Si el tamaño del CSS no respeta el ratio del canvas inicial, este aparecerá distorsionado.</p> + +<div class="note"> +<p><strong>Nota:</strong> Si su renderizado se ve distorsionado, pruebe especificar los atributos width y height explícitamente en los atributos del <code><canvas></code> , y no usando CSS.</p> +</div> + +<p>El atributo <a href="/es/docs/Web/HTML/Atributos_Globales/id">id</a> no está especificado para el elemento <code><canvas></code> pero es uno de los <a href="/es/docs/Web/HTML/Atributos_Globales">atributos globales de HTML</a> el cual puede ser aplicado a cualquier elemento HTML (como <a href="en-US/docs/Web/HTML/Global_attributes/class">class</a> por ejemplo). Siempre es buena idea proporcionar un <code>id</code> porque esto hace más fácil identificarlo en un script.</p> + +<p>El elemento <code><canvas></code> puede ser estilizado como a cualquier imagen normal (margin, border, background, etc). Estas reglas, sin embargo, no afectan a lo dibujado sobre el canvas. Mas adelante veremos cómo se hace esto en un <a href="en-US/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors">capítulo dedicado</a> en este tutorial. Cuando no tenemos reglas de estilo aplicadas al canvas, este será completamente transparente.</p> + +<div id="section_2"> +<h3 id="Contenido_alternativo">Contenido alternativo</h3> + +<p>El elemento <canvas> se diferencia de un tag {{HTMLElement("img")}} en que, como los elementos {{HTMLElement("video")}}, {{HTMLElement("audio")}} o {{HTMLElement("picture")}}, es fácil definir contenido alternativo (fallback content) para mostrarse en navegadores viejos que no soporten el elemento <canvas>, como versiones de Internet Explorer previas a la versión 9 o navegadores de texto. Siempre debes proporcionar contenido alternativo para mostrar en estos navegadores.</p> + +<p>Proporcionar contenido alternativo es muy explicito: solo debemos insertar el contenido alterno dentro del elemento <canvas>. Los navegadores que no soporten <code><canvas></code> ignoraran el contenedor y mostrarán el contenido indicado dentro de este. Navegadores que soporten <code><canvas></code> ignorarán el contenido en su interior (de las etiquetas), y mostrarán el canvas normalmente.</p> + +<p>Por ejemplo, podremos proporcionar un texto descriptivo del contenido del canvas o proveer una imagen estática del contenido rederizado. Nos podría quedar algo así:</p> + +<pre class="brush: html"><canvas id="stockGraph" width="150" height="150"> + current stock price: $3.15 +0.15 +</canvas> + +<canvas id="clock" width="150" height="150"> + <img src="images/clock.png" width="150" height="150" alt=""/> +</canvas> +</pre> + +<h2 id="Etiqueta_<canvas>_requerida">Etiqueta <code></canvas></code> requerida</h2> + +<p>De manera distinta al elemento {{HTMLElement("img")}}, el elemento {{HTMLElement("canvas")}} requiere cerrar la etiqueta (<code></canvas></code>).</p> + +<div class="note"> +<p><strong>Note:</strong> Aunque las versiones anteriores del navegador Safari de Apple no requeria el cierre de la etiqueta, la especificacion indica que es necesaria, asi que tu deberias incluir esta para asegurarte la compatibilidad. Aquellas versiones de Safari (anteriores versiones a 2.0) renderizaran el contenido de regreso agregandolo al canvas mismo a no ser que utilice trucos de CSS para enmascararlo. Afortunadamente, los usuarios de aquellas versiones de Safari son raros hoy en dia.</p> +</div> + +<p>Si el contenido alternativo no se necesita, un simple <code><canvas id="foo" ...></canvas></code> es completamente compatible con todos los navegadores que soportan canvas.</p> + +<h2 id="El_contexto_de_renderización">El contexto de renderización</h2> + +<p>{{HTMLElement("canvas")}} crea un lienzo de dibujo fijado que expone uno o mas contextos renderizados, los cuales son usados para crear y manipular el contenido mostrado. Nos enfocaremos en renderizacion de contextos 2D. Otros contextos deberan proveer diferentes tipos de renderizaciones; por ejemplo, <a href="/en-US/docs/Web/WebGL" title="/en-US/docs/Web/WebGL">WebGL</a> usa un 3D contexto ("experimental-webgl") basado sobre <a class="external" href="http://www.khronos.org/opengles/" rel="external" title="http://en.wikipedia.org/wiki/OpenGL_ES">OpenGL ES</a>.</p> + +<p>El canvas esta inicialmente en blanco. Para mostrar alguna cosa, un script primero necesita acceder al contexto a renderizar y dibujar sobre este. El elemento {{HTMLElement("canvas")}} tiene un <a href="/en-US/docs/Web/API/HTMLCanvasElement#Methods" title="/en-US/docs/Web/API/HTMLCanvasElement#Methods">method</a> llamado <code>getContext()</code>, usado para obtener el contexto a renderizar y sus funciones de dibujo. <code>getContext()</code> toma un parametro, el tipo de contexto. Para graficos 2D, como los que cubre este tutorial, su especificacion es "2d".</p> + +<pre class="brush: js">var canvas = document.getElementById('tutorial'); +var ctx = canvas.getContext('2d'); +</pre> + +<p>La primera linea regresa el nodo DOM para el elemento {{HTMLElement("canvas")}} llamando al metodo {{domxref("document.getElementById()")}}. Una vez tu tienes el elemento nodo, tu puedes acceder al contexto de dibujo usando su metodo <code>getContext()</code>.</p> + +<div id="section_5"> +<h2 id="Comprobando_soporte">Comprobando soporte</h2> + +<p>El contenido de regreso que es mostrado en navegadores los cuales no soportan {{HTMLElement("canvas")}}. Para los Scripts puede tambien comprobarse su soporte desde la programacion por un simple test para la presencia del metodo <code>getContext()</code>. Con un trozo de codigo parecido al que viene debajo:</p> + +<pre class="brush: js">var canvas = document.getElementById('tutorial'); + +if (canvas.getContext){ + var ctx = canvas.getContext('2d'); + // drawing code here +} else { + // canvas-unsupported code here +} +</pre> +</div> +</div> + +<h2 id="Un_esqueleto_de_plantilla">Un esqueleto de plantilla</h2> + +<p>Aqui esta una plantilla minimalista, la cual usaremos como punto de partida para posteriores ejemplos.</p> + +<pre class="brush: html"><html> + <head> + <title>Canvas tutorial</title> + <script type="text/javascript"> + function draw(){ + var canvas = document.getElementById('tutorial'); + if (canvas.getContext){ + var ctx = canvas.getContext('2d'); + } + } + </script> + <style type="text/css"> + canvas { border: 1px solid black; } + </style> + </head> + <body onload="draw();"> + <canvas id="tutorial" width="150" height="150"></canvas> + </body> +</html> +</pre> + +<p>El script incluye una funcion llamada draw(), la cual es ejecutada una vez finalizada la carga de la pagina; este esta hecho usando el evento load del documento. Esta funcion, o una parecida, podria tambien ser llamada usando {{domxref("window.setTimeout()")}}, {{domxref("window.setInterval()")}}, o cualquier otro manejador de evento, a lo largo de que la pagina esta siendo cargada la primera vez.</p> + +<p>Aqui esta como la plantilla se ve en acción:</p> + +<p>{{EmbedLiveSample("Un_esqueleto_de_plantilla", 160, 160)}}</p> + +<h2 id="Un_simple_ejemplo">Un simple ejemplo</h2> + +<p>Para comenzar, daremos un vistazo a un simple ejemplo que dibuja dos rectangulos que se intersectan, uno de los cuales tiene alpha transparencia. Exploraremos como esto trabaja en mas detalle en posteriores ejemplos.</p> + +<pre class="brush: html"><html> + <head> + <script type="application/javascript"> + function draw() { + var canvas = document.getElementById("canvas"); + if (canvas.getContext) { + var ctx = canvas.getContext("2d"); + + ctx.fillStyle = "rgb(200,0,0)"; + ctx.fillRect (10, 10, 55, 50); + + ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; + ctx.fillRect (30, 30, 55, 50); + } + } + </script> + </head> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> + +<p>Este ejemplo quedaría así:</p> + +<p>{{EmbedLiveSample("Un_simple_ejemplo", 160, 160, "https://mdn.mozillademos.org/files/228/canvas_ex1.png")}}</p> + +<p>{{PreviousNext("Web/Guide/HTML/Canvas_tutorial", "Web/Guide/HTML/Canvas_tutorial/Dibujando_formas")}}</p> diff --git a/files/es/web/guide/html/canvas_tutorial/dibujando_formas/index.html b/files/es/web/guide/html/canvas_tutorial/dibujando_formas/index.html new file mode 100644 index 0000000000..3467533e93 --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/dibujando_formas/index.html @@ -0,0 +1,513 @@ +--- +title: Dibujando formas con canvas +slug: Web/Guide/HTML/Canvas_tutorial/Dibujando_formas +tags: + - Canvas + - HTML + - HTML Canvas + - HTML5 + - Intermedio + - Tutorial + - graficos +translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}</div> + +<div class="summary"> +<p>Ahora que hemos preparado nuestro <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_usage">entorno canvas</a>, podemos entrar en detalles de como dibujar en el canvas. Al final de este artículo, habrás aprendido como dibujar rectángulos, triángulos, líneas, arcos y curvas, dándote familiaridad con algunas figuras básicas. Trabajar con rutas es esencial cuando dibujamos objetos sobre el canvas y veremos como se puede hacer eso.</p> +</div> + +<h2 id="La_cuadrícula">La cuadrícula</h2> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/224/Canvas_default_grid.png" style="float: right; height: 220px; width: 220px;">Antes de que podamos empezar a dibujar, necesitamos hablar sobre la cuadrícula del canvas o el <strong>espacio de coordenadas</strong>. La plantilla HTML de la página anterior tenía un elemento canvas con un 'height' y un 'width' de 150 píxeles. A la derecha, puedes ver este canvas con la cuadrícula por defecto superpuesta. Normalmente una unidad en la cuadrícula corresponde a un píxel en el elemento canvas. El origen de esta cuadrícula está posicionado en la esquina superior izquierda (coordenada (0,0)). Todos los elementos estan posicionados de manera relativa a este punto, así que la posición de la esquina superior izquierda del cuadrado azul es de 'x' pixeles desde la izquierda y 'y' pixeles desde arriba (coordenada (x,y)). Mas tarde en este tutorial veremos como trasladar el punto de origen a una posicion diferente, girar la cuadrícula e incluso darle una escala diferente. Por ahora nos dedicaremos a lo mas común.</p> + +<h2 id="Dibujando_rectángulos">Dibujando rectángulos</h2> + +<p>A diferencia de <a href="/en-US/docs/SVG" rel="internal" title="en/SVG">SVG</a>, {{HTMLElement("canvas")}} solo soporta una forma primitiva: rectangulos. Todas las otras formas deben ser creadas por la combinación de uno o más trazos, listas de puntos conectados por líneas. Afortunadamente, tenemos una variedad de funciones para dibujar trazos que hacen posible componer formas muy complejas.</p> + +<div id="section_3"> +<p>Primero veamos el rectángulo. Aquí hay tres funciones que podemos usar en el canvas para dibujarlos:</p> + +<dl> + <dt><code>fillRect(<em>x</em>, <em>y</em>, <em>width</em>, <em>height</em>)</code></dt> + <dd>Dibuja un rectángulo relleno.</dd> + <dt><code>strokeRect(<em>x</em>, <em>y</em>, <em>width</em>, <em>height</em>)</code></dt> + <dd>Dibuja el contorno de un rectángulo.</dd> + <dt><code>clearRect(<em>x</em>, <em>y</em>, <em>width</em>, <em>height</em>)</code></dt> + <dd>Borra un área rectangular especificada, dejándola totalmente transparente.</dd> +</dl> + +<p>Cada una de estas tres funciones toma los mismos parámetros. X e Y especifican la posición del canvas (en relación con el origen) desde la esquina superior izquierda del rectángulo. Tambien especifica los parámetros de anchura y altura que proporcionan el tamaño del rectángulo.</p> + +<p>A continuación se muestra la función draw() de la página anterior, pero ahora haciendo uso de estas tres funciones.</p> + +<h3 id="Ejemplo_de_forma_rectangular">Ejemplo de forma rectangular</h3> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + ctx.fillRect(25,25,100,100); + ctx.clearRect(45,45,60,60); + ctx.strokeRect(50,50,50,50); + } +}</pre> + +<p>El resultado de este ejemplo se muestra a continuación.</p> + +<p>{{EmbedLiveSample("Rectangular_shape_example", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}</p> + +<p>La función fillRect() dibuja un cuadrado grande negro de 100 píxeles en cada lado. La función clearRect() luego borra un cuadrado de 60x60 píxeles del centro, y luego strokeRect() es llamado para crear un contorno rectangular de 50x50 píxeles dentro del cuadrado borrado.</p> + +<p>En las próximas páginas veremos dos métodos alternativos para clearRect(), y también veremos cómo cambiar el color y el trazo de diferentes formas.</p> + +<p>A diferencia de las funciones de trazo que veremos en la próxima sección, las tres funciones del rectángulo dibujan inmediatamente en el canvas.</p> + +<h2 id="Dibujando_trazos">Dibujando trazos</h2> + +<p>Crear formas mediante trazos requiere algunos pasos adicionales.</p> + +<ol> + <li>Primero, se crea el trazo.</li> + <li>A continuación, se usan <a href="/es/docs/Web/API/CanvasRenderingContext2D#Paths">comandos de dibujo</a> para dibujar dentro del trazo.</li> + <li>Después, se cierra el trazo.</li> + <li>Una vez el trazo ha sido creado, se le puede dar contorno o relleno para renderizarlo.</li> +</ol> + +<p>Estas son las funciones que se usan para llevar a cabo estos pasos:</p> + +<dl> + <dt><code>beginPath()</code></dt> + <dd>Crea un nuevo trazo. Una vez creado, los comandos de dibujo futuros son aplicados dentro del trazo y usados para construir el nuevo trazo hacia arriba.</dd> + <dt><code>closePath()</code></dt> + <dd>Cierra el trazo de tal forma que los comandos de dibujo futuros son, una vez más redireccionados al contexto.</dd> + <dt><code>stroke()</code></dt> + <dd>Dibuja el contorno de la forma.</dd> + <dt><code>fill()</code></dt> + <dd>Dibuja una forma solida rellenando el área del trazo.</dd> +</dl> + +<p>El primer paso para crear un trazo es llamar la función <code>beginPath()</code>. Internamente, los trazos son guardados como una lista de subtrazos (lineas, arcos, etc) los cuales juntos crean una forma. Todo tiempo que sea llamado este método la lista es reseteada y podemos empezar a dibujar nuevas formas.</p> + +<div class="note"><strong>Nota:</strong> Cuando el trazo actual este vacio, como aparece inmediatamente despues de llamar la función <code>beginPath()</code>, o en un canvas nuevo, el primer comando para la construcción del trazo es siempre tratada como un <code>moveTo()</code>, independientemente de cual es el trazo actual. Por esta razón casi siempre querrás específicamente setear tu posición de inicio despues de resetear un trazo.</div> + +<p>El segundo paso es llamar los métodos que específican los trazos a crear. Los veremos en seguida.</p> + +<p>El tercero, y un paso opcional, es llamar a la función <code>closePath()</code>. Este método trata de cerrar la forma dibujando una linea recta desde el punto actual al inicio. Si la forma ya ha sido cerrada o hay solamente un punto en la lista, la función hace nada.</p> + +<div class="note"><strong>Nota:</strong> Cuando llamas a la función <code>fill()</code>, cualquier forma abierta es cerrada automaticamente, de tal forma que no tendrás que llamar a la función <code>closePath()</code>. Este no es el caso cuando llamas a la función <code>stroke()</code>.</div> + +<h3 id="Dibujando_un_triangulo">Dibujando un triangulo</h3> + +<p>Por ejemplo, el código para dibujar un triangulo luciría como el siguiente:</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext){ + var ctx = canvas.getContext('2d'); + + ctx.beginPath(); + ctx.moveTo(75,50); + ctx.lineTo(100,75); + ctx.lineTo(100,25); + ctx.closePath(); + ctx.fill(); + } +} +</pre> + +<p>El resultado lucirá así:</p> + +<p>{{EmbedLiveSample("Drawing_a_triangle", 160, 160)}}</p> + +<h3 id="Moviendo_la_pluma">Moviendo la pluma</h3> + +<p>Una función muy útil, la cual realmente no dibuja algo pero convierte parte de la lista de trazos descrita arriba, es la función <code>moveTo()</code>. Puedes, probablemente, pensar mejor de esta como levantar el lápiz o la pluma de un punto en un pedazo de papel y ponerlo en el siguiente punto.</p> + +<dl> + <dt><code>moveTo(<em>x</em>, <em>y</em>)</code></dt> + <dd>Mueve la pluma a las coordenadas específicadas por <code>x</code> e <code>y</code>.</dd> +</dl> + +<p>Cuando el canvas es inicializado ó la función <code>beginPath()</code> es llamada, querrás usar la función <code>moveTo()</code> para colocar el punto de inicio en alguna otra parte. Podríamos usar <code>moveTo()</code> para dibujar trazos sin conectar. Toma un vistazo a la cara sonriente de abajo. He marcado los lugares donde use el método <code>moveTo()</code> (las líneas rojas).</p> + +<p>Para intentar esto por tí mismo, puedes usar el pequeño código de abajo. Solo pégalo dentro de la función <code>draw()</code> que vimos antes.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext){ + var ctx = canvas.getContext('2d'); + + ctx.beginPath(); + ctx.arc(75,75,50,0,Math.PI*2,true); // Círculo externo + ctx.moveTo(110,75); + ctx.arc(75,75,35,0,Math.PI,false); // Boca (contra reloj) + ctx.moveTo(65,65); + ctx.arc(60,65,5,0,Math.PI*2,true); // Ojo izquierdo + ctx.moveTo(95,65); + ctx.arc(90,65,5,0,Math.PI*2,true); // Ojo derecho + ctx.stroke(); + } +} +</pre> + +<p>El resultado luce así:</p> + +<p>{{EmbedLiveSample("Moving_the_pen", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}</p> + +<p>Si quisieras ver las líneas conectadas, puedes remover las líneas de código que llaman <code>moveTo()</code>.</p> + +<div class="note"> +<p><strong>Nota:</strong> Para aprender más sobre la función <code>arc()</code>, vea los {{anch("Arcs")}} a continuación.</p> +</div> + +<h3 id="Líneas">Líneas</h3> + +<p>Para dibujar lineas rectas usa el método <code>lineTo()</code>.</p> + +<dl> + <dt><code>lineTo(<em>x</em>, <em>y</em>)</code></dt> + <dd>Dibuja una línea desde la posición actual del dibujo a la posición específicada por <code>x</code> e <code>y</code>.</dd> +</dl> + +<p>Este método toma dos argumentos <code>x</code> e <code>y</code>, los cuales son las coordenadas del punto final de la linea. El punto de inicio es dependiente de los trazos previamente dibujados, donde el punto final del trazo anterior es el punto inicial para el siguiente, etc. El punto de inicio también puede ser cambiado usando el método <code>moveTo()</code>.</p> + +<p>El ejemplo siguiente dibuja dos triángulos, uno rellenado y el otro contorneado.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext){ + var ctx = canvas.getContext('2d'); + + // Triángulo rellenado + ctx.beginPath(); + ctx.moveTo(25,25); + ctx.lineTo(105,25); + ctx.lineTo(25,105); + ctx.fill(); + + // Triángulo contorneado + ctx.beginPath(); + ctx.moveTo(125,125); + ctx.lineTo(125,45); + ctx.lineTo(45,125); + ctx.closePath(); + ctx.stroke(); + } +} +</pre> + +<p>Esto comienza llamando a <code>beginPath()</code> para empezar una nueva forma. Entonces usamos el método <code>moveTo()</code> para mover el punto de inicio a la posición deseada. Debajo de esto dos líneas son dibujadas lo cual pinta dos lados del triángulo.</p> + +<p>{{EmbedLiveSample("Lines", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}</p> + +<p>Te darás cuenta de la diferencia entre el triángulo rellenado y el contorneado. Esto es, como se menciona arriba, porque las formas son automáticamente cerradas cuando un trazo es rellenado, pero no cuando esta contorneado. Si sacamos el <code>closePath()</code> para el triángulo contorneado, solamente dos líneas serian dibujadas, no un triángulo completo.</p> + +<h3 id="Arcos">Arcos</h3> + +<p>Para dibujar arcos o circulos usamos el método <code>arc()</code>. También puedes usar <code>arcTo()</code>, pero su implementación es un poco menos confiable, así que no lo cubriremos aquí.</p> + +<dl> + <dt><code>arc(<em>x</em>, <em>y</em>, <em>radius</em>, <em>startAngle</em>, <em>endAngle</em>, <em>anticlockwise</em>)</code></dt> + <dd>Dibuja un arco.</dd> +</dl> + +<p>Este método toma cinco parámetros: <code>x</code> e <code>y</code> son las coordenadas del centro del círculo en el cual el arco debería ser dibujado. <code>radius</code> se explica por sí solo. Los parámetros <code>startAngle</code> y <code>endAngle</code> definen el punto de inicio y punto final del arco en radianes a lo largo de la curva del círculo. Estos son medidos desde el eje x. El parámetro <code>anticlockwise</code> es un valor Booleano el cual cuando es verdadero (<code>true</code>) dibuja el arco al contrario de las manecillas del reloj, de lo contrario el arco es dibujado al sentido de las manecillas del reloj.</p> + +<div class="note"> +<p><strong>Nota</strong>: Los ángulos en la función del arco (<code>arc</code>) son medidos en radianes, no en grados. Para convertir grados a radianes puedes usar la siguiente expresión en Javascript: <code>radians = (Math.PI/180)*degrees</code>.</p> +</div> + +<p>El siguiente ejemplo es un poco más complejo que otros que hemos visto arriba. Esto dibuja 12 diferentes arcos, todos con diferentes ángulos y rellenos.</p> + +<p>Las dos sentencias <code>for</code> son para iterar a través de las filas y columnas de los arcos. Para cada arco, empezamos un nuevo trazo llamando <code>beginPath()</code>. En el código, cada uno de los parámetros para el arco estan en una variable para su entendimiento, pero no es necesario esto en la vida real.</p> + +<p>Las coordenadas <code>x</code> e <code>y</code> deberían ser suficientemente claras. <code>radius</code> y <code>startAngle</code> estan arreglados. El <code>endAngle</code> inicia en 180 grados (la mitad de un círculo) en la primera columna y es incrementado por pasos de 90 grados, culminando en un círculo completo en la última columna.</p> + +<p>El parámetro <code>clockwise</code> resulta, en la primera y tercera fila siendo dibujado como un arco al sentido de las manecillas de reloj y la segunda y cuarta fila como arcos al contrario de las manecillas de reloj. Finalmente, la estructura <code>if</code> hace los arcos contorneados a la mitad desde arriba y los arcos hacia abajorellenados a la mitad.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="200"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext){ + var ctx = canvas.getContext('2d'); + + for(var i=0;i<4;i++){ + for(var j=0;j<3;j++){ + ctx.beginPath(); + var x = 25+j*50; // Coordenada x + var y = 25+i*50; // Coordenada y + var radius = 20; // Radio del arco + var startAngle = 0; // Punto inicial del círculo + var endAngle = Math.PI+(Math.PI*j)/2; // Punto final del círculo + var anticlockwise = i%2==0 ? false : true; // Sentido de las manecillas del reloj y contrario a ellas + + ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise); + + if (i>1){ + ctx.fill(); + } else { + ctx.stroke(); + } + } + } + } +} +</pre> +{{EmbedLiveSample("Arcs", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}} + +<h3 id="Curvas_Bezier_curvas_cuadráticas">Curvas Bezier curvas cuadráticas</h3> + +<p>El siguiente tipo de trazos disponibles son las <a class="external" href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve" rel="external" title="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">curvas Bézier</a>, en sus dos variantes, cúbicas y cuadráticas. Son usadas generalmente para dibujar complejas formas orgánicas.</p> + +<dl> + <dt><code>quadraticCurveTo(cp1x, cp1y, x, y)</code></dt> + <dd><span id="result_box" lang="es"><span>Dibuja una curva cuadrática de Bézier desde la posición actual de la pluma hasta el punto final especificado por <code>x</code> e <code>y</code>, utilizando el punto de control especificado por <code>cp1x</code> y <code>cp1y</code>.</span></span></dd> + <dt><code>bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)</code></dt> + <dd>Dibuja una curva cúbica de Bézier desde la posición actual de la pluma hasta el punto final especificado por <code>x</code> e <code>y</code>, utilizando los puntos de control especificados por (<code>cp1x</code>, <code>cp1y</code>) y (<code>cp2x</code>, <code>cp2y</code>).</dd> +</dl> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/223/Canvas_curves.png" style="float: right; height: 190px; width: 190px;">La diferencia entre estos puede describirse mejor utilizando la imagen de la derecha. Una curva cuadrática de Bézier tiene un punto inicial y un punto final (puntos azules) y un solo <strong>punto de control</strong> (indicado por el punto rojo), mientras que una curva cúbica de Bézier utiliza dos puntos de control.</p> + +<p>Los parámetros <code>x</code> e <code>y</code> de ambos métodos son las coordenadas del punto final. <code>cp1x</code> y <code>cp1y</code> son las coordenadas del primer punto de control, y <code>cp2x</code> y <code>cp2y</code> son las coordenadas del segundo punto de control.</p> + +<p>El uso de curvas cuadráticas y cúbicas Bézier puede ser bastante difícil, ya que a diferencia del software de dibujo vectorial como Adobe Illustrator, no tenemos respuesta visual directa en cuanto a lo que estamos haciendo. Esto hace bastante difícil dibujar formas complejas. En el siguiente ejemplo, vamos a dibujar algunas formas orgánicas simples, pero si tienes el tiempo y, sobre todo, la paciencia, se pueden crear formas mucho más complejas.</p> + +<p>No hay nada muy difícil en estos ejemplos. En ambos casos vemos una sucesión de curvas que se dibujan que finalmente dan lugar a una forma completa.</p> + +<h4 id="Curvas_de_Bezier_cuadraticas">Curvas de Bezier cuadraticas</h4> + +<p>Este ejemplo usa multiples curvas cuadraticas de Bézier para renderizar un globo de voz.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + // Quadratric curves example + ctx.beginPath(); + ctx.moveTo(75,25); + ctx.quadraticCurveTo(25,25,25,62.5); + ctx.quadraticCurveTo(25,100,50,100); + ctx.quadraticCurveTo(50,120,30,125); + ctx.quadraticCurveTo(60,120,65,100); + ctx.quadraticCurveTo(125,100,125,62.5); + ctx.quadraticCurveTo(125,25,75,25); + ctx.stroke(); + } +} +</pre> + +<p>{{EmbedLiveSample("Quadratic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}</p> + +<h4 id="Curvas_cúbicas_Bezier">Curvas cúbicas Bezier</h4> + +<p>Este ejemplo dibuja un corazon usanco curvas cúbicas de Bézier.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext){ + var ctx = canvas.getContext('2d'); + + // Quadratric curves example + ctx.beginPath(); + ctx.moveTo(75,40); + ctx.bezierCurveTo(75,37,70,25,50,25); + ctx.bezierCurveTo(20,25,20,62.5,20,62.5); + ctx.bezierCurveTo(20,80,40,102,75,120); + ctx.bezierCurveTo(110,102,130,80,130,62.5); + ctx.bezierCurveTo(130,62.5,130,25,100,25); + ctx.bezierCurveTo(85,25,75,37,75,40); + ctx.fill(); + } +} +</pre> + +<p>{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}</p> + +<h3 id="Rectangles">Rectangles</h3> + +<p>In addition to the three methods we saw in {{anch("Drawing rectangles")}}, which draw rectangular shapes directly to the canvas, there's also the <code>rect()</code> method, which adds a rectangular path to a currently open path.</p> + +<dl> + <dt><code>rect(<em>x</em>, <em>y</em>, <em>width</em>, <em>height</em>)</code></dt> + <dd>Draws a rectangle whose top-left corner is specified by (<code>x</code>, <code>y</code>) with the specified <code>width</code> and <code>height</code>.</dd> +</dl> + +<p>When this method is executed, the <code>moveTo()</code> method is automatically called with the parameters (0,0). In other words, the current pen position is automatically reset to the default coordinates.</p> + +<h3 id="Making_combinations">Making combinations</h3> + +<p>So far, each example on this page has used only one type of path function per shape. However, there's no limitation to the number or types of paths you can use to create a shape. So in this final example, let's combine all of the path functions to make a set of very famous game characters.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext){ + var ctx = canvas.getContext('2d'); + + roundedRect(ctx,12,12,150,150,15); + roundedRect(ctx,19,19,150,150,9); + roundedRect(ctx,53,53,49,33,10); + roundedRect(ctx,53,119,49,16,6); + roundedRect(ctx,135,53,49,33,10); + roundedRect(ctx,135,119,25,49,10); + + ctx.beginPath(); + ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false); + ctx.lineTo(31,37); + ctx.fill(); + + for(var i=0;i<8;i++){ + ctx.fillRect(51+i*16,35,4,4); + } + + for(i=0;i<6;i++){ + ctx.fillRect(115,51+i*16,4,4); + } + + for(i=0;i<8;i++){ + ctx.fillRect(51+i*16,99,4,4); + } + + ctx.beginPath(); + ctx.moveTo(83,116); + ctx.lineTo(83,102); + ctx.bezierCurveTo(83,94,89,88,97,88); + ctx.bezierCurveTo(105,88,111,94,111,102); + ctx.lineTo(111,116); + ctx.lineTo(106.333,111.333); + ctx.lineTo(101.666,116); + ctx.lineTo(97,111.333); + ctx.lineTo(92.333,116); + ctx.lineTo(87.666,111.333); + ctx.lineTo(83,116); + ctx.fill(); + + ctx.fillStyle = "white"; + ctx.beginPath(); + ctx.moveTo(91,96); + ctx.bezierCurveTo(88,96,87,99,87,101); + ctx.bezierCurveTo(87,103,88,106,91,106); + ctx.bezierCurveTo(94,106,95,103,95,101); + ctx.bezierCurveTo(95,99,94,96,91,96); + ctx.moveTo(103,96); + ctx.bezierCurveTo(100,96,99,99,99,101); + ctx.bezierCurveTo(99,103,100,106,103,106); + ctx.bezierCurveTo(106,106,107,103,107,101); + ctx.bezierCurveTo(107,99,106,96,103,96); + ctx.fill(); + + ctx.fillStyle = "black"; + ctx.beginPath(); + ctx.arc(101,102,2,0,Math.PI*2,true); + ctx.fill(); + + ctx.beginPath(); + ctx.arc(89,102,2,0,Math.PI*2,true); + ctx.fill(); + } +} + +// A utility function to draw a rectangle with rounded corners. + +function roundedRect(ctx,x,y,width,height,radius){ + ctx.beginPath(); + ctx.moveTo(x,y+radius); + ctx.lineTo(x,y+height-radius); + ctx.quadraticCurveTo(x,y+height,x+radius,y+height); + ctx.lineTo(x+width-radius,y+height); + ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius); + ctx.lineTo(x+width,y+radius); + ctx.quadraticCurveTo(x+width,y,x+width-radius,y); + ctx.lineTo(x+radius,y); + ctx.quadraticCurveTo(x,y,x,y+radius); + ctx.stroke(); +} +</pre> + +<div id="section_18"> +<p>The resulting image looks like this:</p> + +<p>{{EmbedLiveSample("Making_combinations", 160, 160)}}</p> + +<p>We won't go over this in detail, since it's actually surprisingly simple. The most important things to note are the use of the <code>fillStyle</code> property on the drawing context, and the use of a utility function (in this case <code>roundedRect()</code>). Using utility functions for bits of drawing you do often can be very helpful and reduce the amount of code you need, as well as its complexity.</p> + +<p>We'll take another look at <code>fillStyle</code>, in more detail, later in this tutorial. Here, all we're doing is using it to change the fill color for paths from the default color of black to white, and then back again.</p> + +<p>{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Basic_usage", "Web/Guide/HTML/Canvas_tutorial/Using_images")}}</p> +</div> +</div> + +<p> </p> diff --git a/files/es/web/guide/html/canvas_tutorial/hit_regions_and_accessibility/index.html b/files/es/web/guide/html/canvas_tutorial/hit_regions_and_accessibility/index.html new file mode 100644 index 0000000000..967710de49 --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/hit_regions_and_accessibility/index.html @@ -0,0 +1,99 @@ +--- +title: Hit regions and accessibility +slug: Web/Guide/HTML/Canvas_tutorial/Hit_regions_and_accessibility +translation_of: Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility +--- +<div>{{CanvasSidebar}} {{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}</div> + +<div class="summary">The {{HTMLElement("canvas")}} element on its own is just a bitmap and does not provide information about any drawn objects. Canvas content is not exposed to accessibility tools like semantic HTML is. In general, you should avoid using canvas in an accessible website or app. The following guidelines can help to make it more accessible.</div> + +<div class="summary">El elemento {{HTMLElement ("canvas")}} por sí solo es solo un mapa de bits y no proporciona información sobre ningún objeto dibujado. El contenido del lienzo no está expuesto a herramientas de accesibilidad como el HTML semántico. En general, debe evitar usar canvas en un sitio web o aplicación accesible. Las siguientes pautas pueden ayudar a que sea más accesible.</div> + +<h2 id="Fallback_content">Fallback content</h2> + +<p>The content inside the <code><canvas> ... </canvas></code> tags can be used as a fallback for browsers which don't support canvas rendering. It's also very useful for assistive technology users (like screen readers) which can read and interpret the sub DOM in it. A good example at <a href="http://www.html5accessibility.com/tests/canvas.html">html5accessibility.com</a> demonstrates how this can be done:</p> + +<pre class="brush: html"><canvas> + <h2>Shapes</h2> + <p>A rectangle with a black border. + In the background is a pink circle. + Partially overlaying the <a href="http://en.wikipedia.org/wiki/Circle" onfocus="drawCircle();" onblur="drawPicture();">circle</a>. + Partially overlaying the circle is a green + <a href="http://en.wikipedia.org/wiki/Square" onfocus="drawSquare();" onblur="drawPicture();">square</a> + and a purple <a href="http://en.wikipedia.org/wiki/Triangle" onfocus="drawTriangle();" onblur="drawPicture();">triangle</a>, + both of which are semi-opaque, so the full circle can be seen underneath.</p> +</canvas> </pre> + +<p>See the <a href="https://www.youtube.com/watch?v=ABeIFlqYiMQ">video how NVDA reads this example by Steve Faulkner</a>.</p> + +<h2 id="ARIA_rules">ARIA rules</h2> + +<p>Accessible Rich Internet Applications <strong>(<a href="/en-US/docs/Web/Accessibility/ARIA">ARIA</a>)</strong> defines ways to make Web content and Web applications more accessible to people with disabilities. You can use ARIA attributes to describe the behavior and purpose of the canvas element. See <a href="/en-US/docs/Web/Accessibility/ARIA">ARIA</a> and <a href="/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques">ARIA techniques</a> for more information.</p> + +<pre class="brush: html"><canvas id="button" tabindex="0" role="button" aria-pressed="false" aria-label="Start game"></canvas> +</pre> + +<h2 id="Hit_regions">Hit regions</h2> + +<p>Whether the mouse coordinates are within a particular area on the canvas, is a common problem to solve. The hit region API allows you to define an area of your canvas and provides another possibility to expose interactive content on a canvas to accessibility tools. It allows you to make hit detection easier and lets you route events to DOM elements. The API has the following three methods (which are still experimental in current web browsers; check the browser compatibility tables).</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.addHitRegion()")}} {{experimental_inline}}</dt> + <dd>Adds a hit region to the canvas.</dd> + <dt>{{domxref("CanvasRenderingContext2D.removeHitRegion()")}} {{experimental_inline}}</dt> + <dd>Removes the hit region with the specified <code>id</code> from the canvas.</dd> + <dt>{{domxref("CanvasRenderingContext2D.clearHitRegions()")}} {{experimental_inline}}</dt> + <dd>Removes all hit regions from the canvas.</dd> +</dl> + +<p>You can add a hit region to your path and check for the {{domxref("MouseEvent.region")}} property to test if your mouse is hitting your region, for example.</p> + +<pre class="brush: html"><canvas id="canvas"></canvas> +<script> +var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); + +ctx.beginPath(); +ctx.arc(70, 80, 10, 0, 2 * Math.PI, false); +ctx.fill(); +ctx.addHitRegion({id: 'circle'}); + +canvas.addEventListener('mousemove', function(event) { + if (event.region) { + alert('hit region: ' + event.region); + } +}); +</script></pre> + +<p>The <code>addHitRegion()</code> method also takes a <code>control</code> option to route events to an element (that is a descendant of the canvas):</p> + +<pre class="brush: js">ctx.addHitRegion({control: element});</pre> + +<p>This can be useful for routing to {{HTMLElement("input")}} elements, for example. See also this <a href="https://codepen.io/peterj35/pen/PEdLKx">codepen demo</a>.</p> + +<h2 id="Focus_rings">Focus rings</h2> + +<p>When working with the keyboard, focus rings are a handy indicator to help navigating on a page. To draw focus rings on a canvas drawing, the <code>drawFocusIfNeeded</code> property can be used.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.drawFocusIfNeeded()")}} {{experimental_inline}}</dt> + <dd>If a given element is focused, this method draws a focus ring around the current path.</dd> +</dl> + +<p>Additionally, the <code>scrollPathIntoView()</code> method can be used to make an element visible on the screen if focused, for example.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.scrollPathIntoView()")}} {{experimental_inline}}</dt> + <dd>Scrolls the current path or a given path into the view.</dd> +</dl> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://www.w3.org/WAI/PF/HTML/wiki/Canvas_Accessibility_Use_Cases">Canvas accessibility use cases</a></li> + <li><a href="https://www.w3.org/html/wg/wiki/AddedElementCanvas">Canvas element accessibility issues</a></li> + <li><a href="http://www.paciellogroup.com/blog/2012/06/html5-canvas-accessibility-in-firefox-13/">HTML5 Canvas Accessibility in Firefox 13 – by Steve Faulkner</a></li> + <li><a href="https://html.spec.whatwg.org/multipage/scripting.html#best-practices">Best practices for interactive canvas elements</a></li> +</ul> + +<div>{{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}</div> diff --git a/files/es/web/guide/html/canvas_tutorial/index.html b/files/es/web/guide/html/canvas_tutorial/index.html new file mode 100644 index 0000000000..da5b0b3cc9 --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/index.html @@ -0,0 +1,61 @@ +--- +title: Tutorial Canvas +slug: Web/Guide/HTML/Canvas_tutorial +tags: + - Canvas + - HTML5 + - graficos +translation_of: Web/API/Canvas_API/Tutorial +--- +<p><a href="/en-US/docs/HTML/Canvas" title="HTML/Canvas"><img alt="" src="https://mdn.mozillademos.org/files/257/Canvas_tut_examples.jpg" style="float: right; height: 450px; width: 200px;"></a></p> + +<p><a href="/en-US/docs/HTML/Canvas" title="HTML/Canvas"><strong><code><canvas></code></strong></a> es un elemento <a href="/en-US/docs/HTML" title="HTML">HTML</a> el cual puede ser usado para dibujar gráficos usando scripts (normalmente <a href="/en-US/docs/JavaScript" title="JavaScript">JavaScript</a>). Este puede, por ejemplo, ser usado para dibujar gráficos, realizar composición de fotos o simples (y <a href="/en-US/docs/HTML/Canvas/A_Basic_RayCaster" title="A_Basic_RayCaster">no tan simples</a>) animaciones. Las imágenes a la derecha muestran algunos ejemplos de implementaciones <code><canvas></code> las cuales se verán en un futuro en este tutorial.</p> + +<p><code><canvas></code> fue introducido primero por Apple para el Mac OS X Dashboard y después implementado en Safari y Google Chrome. Navegadores basados en <a href="/en-US/docs/Gecko" title="Gecko">Gecko</a> 1.8, tal como Firefox 1.5, que también soportan este elemento. El <code><canvas></code> es un elemento parte de las especificaciones de la <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/">WhatWG Web applications 1.0</a> mejor conocida como HTML5.</p> + +<p><span class="seoSummary">En este tutorial se describe cómo usar el elemento <code><canvas></code> para dibujar gráficos en 2D, empezando con lo básico. Los ejemplos le proveerán mayor claridad a las ideas que pueda tener referentes al canvas, así como los códigos que necesita para crear su propio contenido.</span></p> + +<h2 id="Before_you_start" name="Before_you_start">Antes de Empezar</h2> + +<p>Usar el elemento <code><canvas></code> no es algo muy díficil pero necesita saber y entender los aspectos básicos del <a href="/en-US/docs/HTML" title="HTML">HTML</a> y <a href="/en-US/docs/JavaScript" title="JavaScript">JavaScript</a>. El elemento <code><canvas></code> no está soportado en navegadores viejos, pero están soportado en la mayoría de las versiones más recientes de los navegadores. El tamaño por defecto del canvas es 300px * 150px [ancho (width) * alto (height)]. Pero se puede personalizar el tamaño usando las propiedades height y width de CSS.<span id="result_box" lang="es"><span class="hps"> Con el fin de</span> <span class="hps">dibujar gráficos</span> <span class="hps">en el lienzo</span> <span class="hps"><canvas> se utiliza un</span> <span class="hps">objeto de contexto de</span> <span class="hps">JavaScript</span> <span class="hps">que crea</span> <span class="hps">gráficos</span> <span class="hps">sobre la marcha.</span></span></p> + +<h2 id="In_this_tutorial" name="In_this_tutorial">En este Tutorial</h2> + +<ul> + <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Basic_usage" title="Canvas_tutorial/Basic_usage">Usos Básicos</a></li> + <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Drawing_shapes" title="Canvas_tutorial/Drawing_shapes">Dibujando Formas</a></li> + <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images" title="Canvas_tutorial/Using_images">Usando Imágenes</a></li> + <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors" title="Canvas_tutorial/Applying_styles_and_colors">Aplicando estilos y colores</a></li> + <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Transformations" title="Canvas_tutorial/Transformations">Transformaciones</a></li> + <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Compositing" title="Canvas_tutorial/Compositing">Composiciones</a></li> + <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Basic_animations" title="Canvas_tutorial/Basic_animations">Animaciones Básicas</a></li> + <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas" title="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas">Optimización de Canvas</a></li> +</ul> + +<h2 id="See_also" name="See_also">Vea también</h2> + +<ul> + <li><a href="/en-US/docs/HTML/Canvas" title="HTML/Canvas">Canvas topic page</a></li> + <li><a href="/en-US/docs/HTML/Canvas/Drawing_Graphics_with_Canvas" title="Drawing_Graphics_with_Canvas">Drawing Graphics with Canvas</a></li> + <li><a href="/en-US/docs/tag/Canvas_examples" title="tag/Canvas_examples">Canvas examples</a></li> + <li><a href="http://www.html5andcss3.org">HTML5 Tutorial</a></li> + <li><a href="/en-US/docs/Drawing_text_using_a_canvas" title="Drawing_text_using_a_canvas">Drawing Text Using a Canvas</a></li> + <li><a class="external" href="http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/HTML-canvas-guide/AddingText/AddingText.html#//apple_ref/doc/uid/TP40010542-CH6-SW4" title="Adding Text to Canvas">Adding Text to Canvas</a></li> + <li><a class="external" href="http://www.canvasdemos.com/" title="Canvas Demos">Canvas Demos - Games, applications, tools and tutorials</a></li> + <li><a class="external" href="http://canvimation.github.com/" title="http://canvimation.github.com/">Canvas Drawing and Animation Application</a></li> + <li><a class="external" href="http://billmill.org/static/canvastutorial/" title="http://billmill.org/static/canvastutorial/">Interactive canvas tutorial</a></li> + <li><a class="external" href="http://blog.nihilogic.dk/2009/02/html5-canvas-cheat-sheet.html" title="http://blog.nihilogic.dk/2009/02/html5-canvas-cheat-sheet.html">Canvas Cheat Sheet with all attributes and methods</a></li> + <li><a class="external" href="http://visitmix.com/labs/ai2canvas/" title="http://visitmix.com/labs/ai2canvas/">Adobe Illustrator to Canvas plug-in</a></li> + <li><a class="external" href="http://www.html5canvastutorials.com/" title="http://www.html5canvastutorials.com/">HTML5CanvasTutorials</a></li> + <li><a class="external" href="http://html5tutorial.com/how-to-draw-n-grade-bezier-curve-with-canvas-api" title="http://html5tutorial.com/how-to-draw-n-grade-bezier-curve-with-canvas-api">How to draw N grade Bézier curves with the Canvas API</a></li> + <li><a class="external" href="http://creativejs.com/2011/08/31-days-of-canvas-tutorials/" title="http://creativejs.com/2011/08/31-days-of-canvas-tutorials/">31 days of canvas tutorials</a></li> + <li><a href="http://www.w3.org/TR/2dcontext/" title="http://www.w3.org/TR/2dcontext/">W3C Standard</a></li> + <li><a href="http://www.tutorialspark.com/html5/HTML5_canvas_Intro.php" title="http://www.tutorialspark.com/html5/HTML5_canvas_Intro.php">HTML5 Canvas tutorials and reference</a></li> + <li><a href="http://davidwalsh.name/convert-canvas-image">JavaScript Canvas Image Conversion</a></li> +</ul> + +<h2 id="Nota_a_los_contribuyentes">Nota a los contribuyentes</h2> + +<p>Debido a un desafortunado error técnico que ocurrió el 17 de junio del 2013, perdimos la historia de este tutorial, incluyendo atribuciones a todos los contribuyentes del pasado a su contenido. Pedimos disculpas por esto, y esperamos que perdone este desafortunado percance.</p> + +<div>{{ Next("Web/Guide/HTML/Canvas_tutorial/Basic_usage") }}</div> diff --git a/files/es/web/guide/html/canvas_tutorial/optimizing_canvas/index.html b/files/es/web/guide/html/canvas_tutorial/optimizing_canvas/index.html new file mode 100644 index 0000000000..145e2734f0 --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/optimizing_canvas/index.html @@ -0,0 +1,19 @@ +--- +title: Optimizing canvas +slug: Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas +translation_of: Web/API/Canvas_API/Tutorial/Optimizing_canvas +--- +<p>{{HTMLElement("canvas")}} es uno de los estándares más utilizados para la representación de gráficos 2D en la Web. Se utiliza ampliamente en los juegos y visualizaciones complejas. Sin embargo, as Web sites and apps push canvas to the limits, el rendimiento comienza a sufrir. <span class="seoSummary">This article aims to provide suggestions for optimizing your use of the canvas element, to ensure that your Web site or app performs well.</span></p> +<p>A continuación una lista de tips par mejorar el rendimiento:</p> +<ul> + <li>Repintar primitives similares o objetos repetidos dentro y fuera de la pantalla canvas.</li> + <li>Batch canvas calls together (for example, draw a poly-line instead of multiple separate lines).</li> + <li>Avoid floating-point coordinates and use integers instead.</li> + <li>Avoid unnecessary canvas state changes.</li> + <li>Render screen differences only, not the whole new state.</li> + <li>Utilice varios lienzos en capas para escenas complejas.</li> + <li>Evite la propiedad <code>shadowBlur</code> siempre que sea posible.</li> + <li>Con las animaciones, use {{domxref("window.requestAnimationFrame()")}}.</li> + <li>Probar el rendimiento con <a href="http://jsperf.com" title="http://jsperf.com">JSPerf</a>.</li> +</ul> +<p>{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Basic_animations")}}</p> diff --git a/files/es/web/guide/html/canvas_tutorial/pixel_manipulation_with_canvas/index.html b/files/es/web/guide/html/canvas_tutorial/pixel_manipulation_with_canvas/index.html new file mode 100644 index 0000000000..14ccc9c4a5 --- /dev/null +++ b/files/es/web/guide/html/canvas_tutorial/pixel_manipulation_with_canvas/index.html @@ -0,0 +1,301 @@ +--- +title: Pixel manipulation with canvas +slug: Web/Guide/HTML/Canvas_tutorial/Pixel_manipulation_with_canvas +translation_of: Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}</div> + +<div class="summary"> +<p>Hasta ahora, no habíamos mirado los píxeles reales de nuestro <em>canvas</em>. Con el objeto <code>ImageData</code>, puedes leer y escribir directamente un <em>array</em> de datos para manipular píxeles.</p> + +<p>También veremos cómo se puede controlar el suavizado de la imagen (antialiasing) y cómo guardar imágenes de tu <em>canvas</em>.</p> +</div> + +<h2 id="El_objeto_ImageData">El objeto <code>ImageData</code></h2> + +<p>El objeto {{domxref("ImageData")}} representa los datos pixelados subyacentes de un área de un objeto lienzo. Contiene los siguientes atributos de sólo lectura:</p> + +<dl> + <dt><code>width</code></dt> + <dd>El ancho de la imagen en píxeles.</dd> + <dt><code>height</code></dt> + <dd>La altura de la imagen en píxeles.</dd> + <dt><code>data</code></dt> + <dd>Un objeto {{jsxref("Uint8ClampedArray")}} que representa un array unidimensional, contiene información en formato RGBA, con valores desde <code>0</code> hasta <code>255</code> (incluído).</dd> +</dl> + +<p>La propiedad <code>data</code> devuelve un {{jsxref("Uint8ClampedArray")}}, al que se puede acceder para ver los datos originales del pixel; cada pixel está representado por cuatro valores (rojo, verde, azul, y alfa, en ese orden; esto es, formato "RGBA"). Cada componente de color se representa con un valor entero entre 0 y 255. Dentro del array, cada componente ocupa un índice consecutivo, comenzando con 0 desde el punto superior izquierdo, continuando de izquierda a derecha y de arriba hacia abajo, a través del array.</p> + +<p>El {{jsxref("Uint8ClampedArray")}} contiene <code>alto</code> × <code>ancho</code> × 4 bytes de datos, con valores de índice en el rango entre 0 y (<code>alto</code>×<code>ancho</code>×4)-1.</p> + +<p>Por ejemplo, para leer el valor del componente azul del pixel en la columna 200, fila 50 de una imagen, deberías hacer lo siguiente:</p> + +<p>blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];</p> + +<p>Si se le da un conjunto de coordenadas (X e Y), puede que termine haciendo algo así:</p> + +<pre class="brush: js">var xCoord = 50; +var yCoord = 100; +var canvasWidth = 1024; + +function getColorIndicesForCoord(x, y, width) { + var red = y * (width * 4) + x * 4; + return [red, red + 1, red + 2, red + 3]; +} + +var colorIndices = getColorIndicesForCoord(xCoord, yCoord, canvasWidth); + +var redIndex = colorIndices[0]; +var greenIndex = colorIndices[1]; +var blueIndex = colorIndices[2]; +var alphaIndex = colorIndices[3]; + +var redForCoord = imageData.data[redIndex]; +var greenForCoord = imageData.data[greenIndex]; +var blueForCoord = imageData.data[blueIndex]; +var alphaForCoord = imageData.data[alphaIndex]; +</pre> + +<p>O, en ES6 sería algo así:</p> + +<pre class="brush: js">const xCoord = 50; +const yCoord = 100; +const canvasWidth = 1024; + +const getColorIndicesForCoord = (x, y, width) => { + const red = y * (width * 4) + x * 4; + return [red, red + 1, red + 2, red + 3]; +}; + +const colorIndices = getColorIndicesForCoord(xCoord, yCoord, canvasWidth); + +const [redIndex, greenIndex, blueIndex, alphaIndex] = colorIndices; +</pre> + +<p>You may also access the size of the pixel array in bytes by reading the <code>Uint8ClampedArray.length</code> attribute:</p> + +<pre class="brush: js">var numBytes = imageData.data.length; +</pre> + +<h2 id="Creando_un_objeto_ImageData">Creando un objeto <code>ImageData</code></h2> + +<p>Para crear un objeto nuevo y vacío tipo <code>ImageData</code>, debes usar el método {{domxref("CanvasRenderingContext2D.createImageData", "createImageData()")}}. Hay dos versiones del método <code>createImageData()</code>:</p> + +<pre class="brush: js">var myImageData = ctx.createImageData(width, height);</pre> + +<p>Esto crea un nuevo objeto <code>ImageData</code> con las dimensiones especificadas. Todos los pixels tienen valor correspondiente a negro - transparente (0,0,0,0).</p> + +<p>También puedes crear un nuevo objeto <code>ImageData</code> con las mismas dimensiones que otro objeto, especificado por <code>anotherImageData</code>. Los píxels del nuevo objeto tienen valor negro - transparente. <strong>¡Esto no es una copia de los datos de la imagen!</strong></p> + +<pre class="brush: js">var myImageData = ctx.createImageData(anotherImageData);</pre> + +<h2 id="Getting_the_pixel_data_for_a_context">Getting the pixel data for a context</h2> + +<p>To obtain an <code>ImageData</code> object containing a copy of the pixel data for a canvas context, you can use the <code>getImageData()</code> method:</p> + +<pre class="brush: js">var myImageData = ctx.getImageData(left, top, width, height);</pre> + +<p>This method returns an <code>ImageData</code> object representing the pixel data for the area of the canvas whose corners are represented by the points (<code>left</code>,<code>top</code>), (<code>left+width</code>, <code>top</code>), (<code>left</code>, <code>top+height</code>), and (<code>left+width</code>, <code>top+height</code>). The coordinates are specified in canvas coordinate space units.</p> + +<div class="note"> +<p><strong>Note</strong>: Any pixels outside the canvas are returned as transparent black in the resulting <code>ImageData</code> object.</p> +</div> + +<p>This method is also demonstrated in the article <a href="/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas">Manipulating video using canvas</a>.</p> + +<h3 id="A_color_picker">A color picker</h3> + +<p>In this example we are using the <a href="/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData">getImageData() </a>method to display the color under the mouse cursor. For this, we need the current position of the mouse with <code>layerX</code> and <code>layerY</code>, then we look up the pixel data on that position in the pixel array that <a href="/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData">getImageData()</a> provides us. Finally, we use the array data to set a background color and a text in the <code><div></code> to display the color.</p> + +<div class="hidden"> +<pre class="brush: html;"><canvas id="canvas" width="300" height="227" style="float:left"></canvas> +<div id="color" style="width:200px;height:50px;float:left"></div> +</pre> +</div> + +<pre class="brush: js;">var img = new Image(); +img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg'; +var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +img.onload = function() { + ctx.drawImage(img, 0, 0); + img.style.display = 'none'; +}; +var color = document.getElementById('color'); +function pick(event) { + var x = event.layerX; + var y = event.layerY; + var pixel = ctx.getImageData(x, y, 1, 1); + var data = pixel.data; + var rgba = 'rgba(' + data[0] + ', ' + data[1] + + ', ' + data[2] + ', ' + (data[3] / 255) + ')'; + color.style.background = rgba; + color.textContent = rgba; +} +canvas.addEventListener('mousemove', pick); +</pre> + +<p>{{ EmbedLiveSample('A_color_picker', 610, 240) }}</p> + +<h2 id="Painting_pixel_data_into_a_context">Painting pixel data into a context</h2> + +<p>You can use the<a href="/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData"> putImageData() </a>method to paint pixel data into a context:</p> + +<pre class="brush: js">ctx.putImageData(myImageData, dx, dy); +</pre> + +<p>The <code>dx</code> and <code>dy</code> parameters indicate the device coordinates within the context at which to paint the top left corner of the pixel data you wish to draw.</p> + +<p>For example, to paint the entire image represented by <code>myImageData</code> to the top left corner of the context, you can simply do the following:</p> + +<pre class="brush: js">ctx.putImageData(myImageData, 0, 0); +</pre> + +<h3 id="Grayscaling_and_inverting_colors">Grayscaling and inverting colors</h3> + +<p>In this example we iterate over all pixels to change their values, then we put the modified pixel array back to the canvas using <a href="/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData">putImageData()</a>. The invert function simply subtracts each color from the max value 255. The grayscale function simply uses the average of red, green and blue. You can also use a weighted average, given by the formula <code>x = 0.299r + 0.587g + 0.114b</code>, for example. See <a href="http://en.wikipedia.org/wiki/Grayscale">Grayscale</a> on Wikipedia for more information.</p> + +<div class="hidden"> +<pre class="brush: html;"><canvas id="canvas" width="300" height="227"></canvas> +<div> + <input id="grayscalebtn" value="Grayscale" type="button"> + <input id="invertbtn" value="Invert" type="button"> +</div> +</pre> +</div> + +<pre class="brush: js">var img = new Image(); +img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg'; +img.onload = function() { + draw(this); +}; + +function draw(img) { + var canvas = document.getElementById('canvas'); + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + img.style.display = 'none'; + var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + var data = imageData.data; + + var invert = function() { + for (var i = 0; i < data.length; i += 4) { + data[i] = 255 - data[i]; // red + data[i + 1] = 255 - data[i + 1]; // green + data[i + 2] = 255 - data[i + 2]; // blue + } + ctx.putImageData(imageData, 0, 0); + }; + + var grayscale = function() { + for (var i = 0; i < data.length; i += 4) { + var avg = (data[i] + data[i + 1] + data[i + 2]) / 3; + data[i] = avg; // red + data[i + 1] = avg; // green + data[i + 2] = avg; // blue + } + ctx.putImageData(imageData, 0, 0); + }; + + var invertbtn = document.getElementById('invertbtn'); + invertbtn.addEventListener('click', invert); + var grayscalebtn = document.getElementById('grayscalebtn'); + grayscalebtn.addEventListener('click', grayscale); +} +</pre> + +<p>{{ EmbedLiveSample('Grayscaling_and_inverting_colors', 330, 270) }}</p> + +<h2 id="Zooming_and_anti-aliasing">Zooming and anti-aliasing</h2> + +<p>With the help of the {{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}} method, a second canvas and the {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} property, we are able to zoom into our picture and see the details.</p> + +<p>We get the position of the mouse and crop an image of 5 pixels left and above to 5 pixels right and below. Then we copy that one over to another canvas and resize the image to the size we want it to. In the zoom canvas we resize a 10×10 pixel crop of the original canvas to 200×200.</p> + +<pre class="brush: js">zoomctx.drawImage(canvas, + Math.abs(x - 5), Math.abs(y - 5), + 10, 10, 0, 0, 200, 200);</pre> + +<p>Because anti-aliasing is enabled by default, we might want to disable the smoothing to see clear pixels. You can toggle the checkbox to see the effect of the <code>imageSmoothingEnabled</code> property (which needs prefixes for different browsers).</p> + +<h6 class="hidden" id="Zoom_example">Zoom example</h6> + +<div class="hidden"> +<pre class="brush: html;"><canvas id="canvas" width="300" height="227"></canvas> +<canvas id="zoom" width="300" height="227"></canvas> +<div> +<label for="smoothbtn"> + <input type="checkbox" name="smoothbtn" checked="checked" id="smoothbtn"> + Enable image smoothing +</label> +</div> +</pre> +</div> + +<pre class="brush: js">var img = new Image(); +img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg'; +img.onload = function() { + draw(this); +}; + +function draw(img) { + var canvas = document.getElementById('canvas'); + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + img.style.display = 'none'; + var zoomctx = document.getElementById('zoom').getContext('2d'); + + var smoothbtn = document.getElementById('smoothbtn'); + var toggleSmoothing = function(event) { + zoomctx.imageSmoothingEnabled = this.checked; + zoomctx.mozImageSmoothingEnabled = this.checked; + zoomctx.webkitImageSmoothingEnabled = this.checked; + zoomctx.msImageSmoothingEnabled = this.checked; + }; + smoothbtn.addEventListener('change', toggleSmoothing); + + var zoom = function(event) { + var x = event.layerX; + var y = event.layerY; + zoomctx.drawImage(canvas, + Math.abs(x - 5), + Math.abs(y - 5), + 10, 10, + 0, 0, + 200, 200); + }; + + canvas.addEventListener('mousemove', zoom); +}</pre> + +<p>{{ EmbedLiveSample('Zoom_example', 620, 490) }}</p> + +<h2 id="Guardando_las_imágenes">Guardando las imágenes</h2> + +<p>The {{domxref("HTMLCanvasElement")}} provides a <code>toDataURL()</code> method, which is useful when saving images. It returns a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs">data URI</a> containing a representation of the image in the format specified by the <code>type</code> parameter (defaults to <a class="external external-icon" href="https://en.wikipedia.org/wiki/Portable_Network_Graphics">PNG</a>). The returned image is in a resolution of 96 dpi.</p> + +<dl> + <dt>{{domxref("HTMLCanvasElement.toDataURL", "canvas.toDataURL('image/png')")}}</dt> + <dd>Default setting. Creates a PNG image.</dd> + <dt>{{domxref("HTMLCanvasElement.toDataURL", "canvas.toDataURL('image/jpeg', quality)")}}</dt> + <dd>Creates a JPG image. Optionally, you can provide a quality in the range from 0 to 1, with one being the best quality and with 0 almost not recognizable but small in file size.</dd> +</dl> + +<p>Once you have generated a data URI from you canvas, you are able to use it as the source of any {{HTMLElement("image")}} or put it into a hyper link with a <a href="/en-US/docs/Web/HTML/Element/a#attr-download">download attribute</a> to save it to disc, for example.</p> + +<p>You can also create a {{domxref("Blob")}} from the canvas.</p> + +<dl> + <dt>{{domxref("HTMLCanvasElement.toBlob", "canvas.toBlob(callback, type, encoderOptions)")}}</dt> + <dd>Creates a <code>Blob</code> object representing the image contained in the canvas.</dd> +</dl> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{domxref("ImageData")}}</li> + <li><a href="/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas">Manipulating video using canvas</a></li> + <li><a href="https://codepo8.github.io/canvas-images-and-pixels/">Canvas, images and pixels – by Christian Heilmann</a></li> +</ul> + +<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}</p> diff --git a/files/es/web/guide/html/categorias_de_contenido/index.html b/files/es/web/guide/html/categorias_de_contenido/index.html new file mode 100644 index 0000000000..b9c4fb6061 --- /dev/null +++ b/files/es/web/guide/html/categorias_de_contenido/index.html @@ -0,0 +1,175 @@ +--- +title: Categorías de contenido +slug: Web/Guide/HTML/categorias_de_contenido +tags: + - Avanzado + - Guía + - HTML + - HTML5 + - Web +translation_of: Web/Guide/HTML/Content_categories +--- +<p><span class="seoSummary">Cada elemento {{web.link("/es/docs/Web/HTML", "HTML")}} es miembro de una o más <strong>categorías de contenido</strong> — estas categorías agrupan elementos que comparten características comunes.</span> Esta es una agrupación flexible (en realidad no crea una relación entre los elementos de estas categorías), pero ayuda a definir y describir el comportamiento compartido de las categorías y sus reglas asociadas, especialmente cuando te encuentras con sus intrincados detalles. También es posible que los elementos no sean miembros de <em>ninguna</em> de estas categorías.</p> + +<p>Hay tres tipos de categorías de contenido:</p> + +<ul> + <li>Categoría de contenido principal — que describe reglas comunes compartidas por muchos elementos.</li> + <li>Categorías de contenido relacionado con formularios — que describe reglas comunes a los elementos relacionados con formularios.</li> + <li>Categorías de contenido específico — que describe categorías raras compartidas solo por unos pocos elementos, a veces, solo en un contexto específico.</li> +</ul> + +<div class="note"> +<p><strong>Nota</strong>: Una explicación comparativa más detallada de estas categorías de contenido y su funcionalidad está más allá del alcance de este artículo; para eso, posiblemente desees leer las <a href="https://html.spec.whatwg.org/multipage/dom.html#kinds-of-content">partes relevantes de la especificación HTML</a>.</p> +</div> + +<p><a href="/@api/deki/files/6244/=Content_categories_venn.png"><img alt="Un diagrama de Venn que muestra cómo se interrelacionan las distintas categorías de contenido. Las siguientes secciones explican estas relaciones en texto." class="default internal" src="/@api/deki/files/6244/=Content_categories_venn.png?size=webview" style="height: 200px; width: 350px;"></a></p> + +<h2 id="Categorías_de_contenido_principal">Categorías de contenido principal</h2> + +<h3 id="Contenido_de_metadatos">Contenido de metadatos</h3> + +<p>Los elementos pertenecientes a la categoría <em>contenido de metadatos</em> modifican la presentación o el comportamiento del resto del documento, establecen enlaces a otros documentos o transmiten otra información <em>fuera de banda</em>.</p> + +<p>Los elementos que pertenecen a esta categoría son {{HTMLElement("base")}}, {{ Obsolete_inline() }}{{HTMLElement("command")}}, {{HTMLElement("link")}}, {{HTMLElement("meta")}}, {{HTMLElement("noscript")}}, {{HTMLElement("script")}}, {{HTMLElement("style")}} y {{HTMLElement("title")}}.</p> + +<h3 id="Flujo_de_contenido">Flujo de contenido</h3> + +<p>Los elementos que pertenecen a la categoría de flujo de contenido suelen contener texto o contenido incrustado. Son: {{HTMLElement("a")}}, {{HTMLElement("abbr")}}, {{HTMLElement("address")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("audio")}}, {{HTMLElement("b")}},{{HTMLElement("bdo")}}, {{HTMLElement("bdi")}}, {{HTMLElement("blockquote")}}, {{HTMLElement("br")}}, {{HTMLElement("button")}}, {{HTMLElement("canvas")}}, {{HTMLElement("cite")}}, {{HTMLElement("code")}}, {{ Obsolete_inline() }}{{HTMLElement("command")}}, {{HTMLElement("data")}}, {{HTMLElement("datalist")}}, {{HTMLElement("del")}}, {{HTMLElement("details")}}, {{HTMLElement("dfn")}}, {{HTMLElement("div")}}, {{HTMLElement("dl")}}, {{HTMLElement("em")}}, {{HTMLElement("embed")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}}, {{HTMLElement("footer")}}, {{HTMLElement("form")}}, {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}, {{HTMLElement("header")}}, {{HTMLElement("hgroup")}}, {{HTMLElement("hr")}}, {{HTMLElement("i")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{HTMLElement("input")}}, {{HTMLElement("ins")}}, {{HTMLElement("kbd")}}, {{deprecated_inline()}}{{HTMLElement("keygen")}}, {{HTMLElement("label")}}, {{HTMLElement("main")}}, {{HTMLElement("map")}}, {{HTMLElement("mark")}}, {{MathMLElement("math")}}, {{HTMLElement("menu")}}, {{HTMLElement("meter")}}, {{HTMLElement("nav")}}, {{HTMLElement("noscript")}}, {{HTMLElement("object")}}, {{HTMLElement("ol")}}, {{HTMLElement("output")}}, {{HTMLElement("p")}}, {{HTMLElement("picture")}}, {{HTMLElement("pre")}}, {{HTMLElement("progress")}}, {{HTMLElement("q")}}, {{HTMLElement("ruby")}}, {{HTMLElement("s")}}, {{HTMLElement("samp")}}, {{HTMLElement("script")}}, {{HTMLElement("section")}}, {{HTMLElement("select")}}, {{HTMLElement("small")}}, {{HTMLElement("span")}}, {{HTMLElement("strong")}}, {{HTMLElement("sub")}}, {{HTMLElement("sup")}}, {{SVGElement("svg")}}, {{HTMLElement("table")}}, {{HTMLElement("template")}}, {{HTMLElement("textarea")}}, {{HTMLElement("time")}}, {{HTMLElement("ul")}}, {{HTMLElement("var")}}, {{HTMLElement("video")}}, {{HTMLElement("wbr")}} and Text.</p> + +<p>Algunos otros elementos pertenecen a esta categoría, pero solo si se cumple una condición específica:</p> + +<ul> + <li>{{HTMLElement("area")}}, si es descendiente de un elemento {{HTMLElement("map")}}</li> + <li>{{HTMLElement("link")}}, si está presente el atributo {{web.link("/es/docs/HTML/Global_attributes#attr-itemprop", "itemprop")}}</li> + <li>{{HTMLElement("meta")}}, si está presente el atributo {{web.link("/es/docs/HTML/Global_attributes#attr-itemprop", "itemprop")}}</li> + <li>{{HTMLElement("style")}}, si está presente el atributo {{deprecated_inline()}} {{HTMLAttrxRef("scoped", "style")}}</li> +</ul> + +<h3 id="Contenido_de_sección">Contenido de sección</h3> + +<p>Los elementos que pertenecen al modelo de contenido de secciones crean una {{web.link("/es/docs/Sections_and_Outlines_of_an_HTML5_document", "sección en el esquema actual")}} que define el alcance de los elementos {{HTMLElement("header")}}, {{HTMLElement("footer")}} y {{anch("Contenido del encabezado")}}.</p> + +<p>Los elementos que pertenecen a esta categoría son {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("nav")}} y {{HTMLElement("section")}}.</p> + +<div class="note"> +<p>No confundas este modelo de contenido con la categoría de {{web.link("/es/docs/Web/Guide/HTML/Using_HTML_sections_and_outlines#Sectioning_roots", "seccionado raíz")}}, que aísla su contenido del esquema regular.</p> +</div> + +<h3 id="Contenido_del_encabezado">Contenido del encabezado</h3> + +<p>El contenido del encabezado define el título de una sección, ya sea que esté marcado por un elemento {{anch("Contenido de sección")}} explícito o definido implícitamente por el contenido del encabezado en sí mismo.</p> + +<p>Los elementos que pertenecen a esta categoría son {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}} y {{HTMLElement("hgroup")}}.</p> + +<div class="note"> +<p>Aunque es probable que tenga contenido de encabezado, {{HTMLElement("header")}} no es contenido de encabezado en sí mismo.</p> +</div> + +<div class="note"> +<p><strong>Nota</strong>: El elemento {{HTMLElement("hgroup")}} se eliminó de la especificación HTML del W3C antes de que se finalizara HTML 5, pero sigue siendo parte de la especificación WHATWG y la mayoría de los navegadores lo admiten por lo menos parcialmente.</p> +</div> + +<h3 id="Contenido_de_redacción">Contenido de redacción</h3> + +<p>El contenido de redacción define el texto y el marcado que contiene. Las series de contenido de redacción forman párrafos.</p> + +<p>Los elementos que pertenecen a esta categoría son: {{HTMLElement("abbr")}}, {{HTMLElement("audio")}}, {{HTMLElement("b")}}, {{HTMLElement("bdo")}}, {{HTMLElement("br")}}, {{HTMLElement("button")}}, {{HTMLElement("canvas")}}, {{HTMLElement("cite")}}, {{HTMLElement("code")}}, {{ Obsolete_inline() }}{{HTMLElement("command")}}, {{HTMLElement("data")}}, {{HTMLElement("datalist")}}, {{HTMLElement("dfn")}}, {{HTMLElement("em")}}, {{HTMLElement("embed")}}, {{HTMLElement("i")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{HTMLElement("input")}}, {{HTMLElement("kbd")}}, {{deprecated_inline()}}{{HTMLElement("keygen")}}, {{HTMLElement("label")}}, {{HTMLElement("mark")}}, {{MathMLElement("math")}}, {{HTMLElement("meter")}}, {{HTMLElement("noscript")}}, {{HTMLElement("object")}}, {{HTMLElement("output")}}, {{HTMLElement("picture")}}, {{HTMLElement("progress")}}, {{HTMLElement("q")}}, {{HTMLElement("ruby")}}, {{HTMLElement("samp")}}, {{HTMLElement("script")}}, {{HTMLElement("select")}}, {{HTMLElement("small")}}, {{HTMLElement("span")}}, {{HTMLElement("strong")}}, {{HTMLElement("sub")}}, {{HTMLElement("sup")}}, {{SVGElement("svg")}}, {{HTMLElement("textarea")}}, {{HTMLElement("time")}}, {{HTMLElement("var")}}, {{HTMLElement("video")}}, {{HTMLElement("wbr")}} y texto sin formato (no solo consiste de espacios en blanco).</p> + +<p>Algunos otros elementos pertenecen a esta categoría, pero solo si se cumple una condición específica:</p> + +<ul> + <li>{{HTMLElement("a")}}, si solo incluye contenido de redacción</li> + <li>{{HTMLElement("area")}}, si es descendiente de un elemento {{HTMLElement("map")}}</li> + <li>{{HTMLElement("del")}}, si solo incluye contenido de redacción</li> + <li>{{HTMLElement("ins")}}, si solo incluye contenido de redacción</li> + <li>{{HTMLElement("link")}}, si está presente el atributo {{web.link("/es/docs/HTML/Global_attributes#itemprop", "itemprop")}}</li> + <li>{{HTMLElement("map")}}, si solo incluye contenido de redacción</li> + <li>{{HTMLElement("meta")}}, si está presente el atributo {{web.link("/es/docs/HTML/Global_attributes#itemprop", "itemprop")}}</li> +</ul> + +<h3 id="Contenido_incrustado">Contenido incrustado</h3> + +<p>El contenido incrustado importa otro recurso o inserta contenido de otro lenguaje de marcado o espacio de nombres en el documento. Los elementos que pertenecen a esta categoría incluyen: {{HTMLElement("audio")}}, {{HTMLElement("canvas")}}, {{HTMLElement("embed")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{MathMLElement("math")}}, {{HTMLElement("object")}}, {{HTMLElement("picture")}}, {{SVGElement("svg")}} y {{HTMLElement("video")}}.</p> + +<h3 id="Contenido_interactivo">Contenido interactivo</h3> + +<p>El contenido interactivo incluye elementos diseñados específicamente para la interacción del usuario. Los elementos que pertenecen a esta categoría incluyen: {{HTMLElement("a")}}, {{HTMLElement("button")}}, {{HTMLElement("details")}}, {{HTMLElement("embed")}}, {{HTMLElement("iframe")}}, {{deprecated_inline()}}{{HTMLElement("keygen")}}, {{HTMLElement("label")}}, {{HTMLElement("select")}} y {{HTMLElement("textarea")}}.<br> + Algunos elementos pertenecen a esta categoría solo bajo condiciones específicas:</p> + +<ul> + <li>{{HTMLElement("audio")}}, si está presente el atributo {{HTMLAttrxRef("controls", "audio")}}</li> + <li>{{HTMLElement("img")}}, si está presente el atributo {{HTMLAttrxRef("usemap", "img")}}</li> + <li>{{HTMLElement("input")}}, si el atributo {{HTMLAttrxRef("type", "input")}} no está en estado oculto</li> + <li>{{HTMLElement("menu")}}, si el atributo {{HTMLAttrxRef("type", "menu")}} está en la barra de estado de herramientas</li> + <li>{{HTMLElement("object")}}, si está presente el atributo {{HTMLAttrxRef("usemap", "object")}}</li> + <li>{{HTMLElement("video")}}, si está presente el atributo {{HTMLAttrxRef("controls", "video")}}</li> +</ul> + +<h3 id="Contenido_palpable">Contenido palpable</h3> + +<p>El contenido es palpable cuando no está vacío ni oculto; es contenido que se presenta y es sustantivo. Los elementos cuyo modelo es flujo de contenido o contenido de redacción deben tener, por lo menos, un nodo que sea palpable.</p> + +<h3 id="Contenido_asociado_a_formulario">Contenido asociado a formulario</h3> + +<p>El contenido asociado a un formulario comprende elementos que tienen un formulario de propietario, expuesto mediante un atributo <strong>form</strong>. El propietario de un formulario es el elemento {{HTMLElement("form")}} que lo contiene o el elemento cuya identificación se especifica en el atributo <strong>form</strong>.</p> + +<ul> + <li>{{HTMLElement("button")}}</li> + <li>{{HTMLElement("fieldset")}}</li> + <li>{{HTMLElement("input")}}</li> + <li>{{deprecated_inline()}} {{HTMLElement("keygen")}}</li> + <li>{{HTMLElement("label")}}</li> + <li>{{HTMLElement("meter")}}</li> + <li>{{HTMLElement("object")}}</li> + <li>{{HTMLElement("output")}}</li> + <li>{{HTMLElement("progress")}}</li> + <li>{{HTMLElement("select")}}</li> + <li>{{HTMLElement("textarea")}}</li> +</ul> + +<p>Esta categoría contiene varias subcategorías:</p> + +<dl> + <dt id="Enumerado_en_formulario">enumerado</dt> + <dd>Elementos que se enumeran en las colecciones IDL {{DOMxRef("HTMLFormElement.elements", "form.elements")}} y <code>fieldset.elements</code>. Contiene: {{HTMLElement("button")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("input")}}, {{deprecated_inline()}} {{HTMLElement("keygen")}}, {{HTMLElement("object")}}, {{HTMLElement("output")}}, {{HTMLElement("select")}} y {{HTMLElement("textarea")}}.</dd> + <dt id="Etiquetable_en_formulario">etiquetable</dt> + <dd>Elementos que se pueden asociar con elementos {{HTMLElement("label")}}. Contiene {{HTMLElement("button")}}, {{HTMLElement("input")}}, {{deprecated_inline()}}{{HTMLElement("keygen")}}, {{HTMLElement("meter")}}, {{HTMLElement("output")}}, {{HTMLElement("progress")}}, {{HTMLElement("select")}} y {{HTMLElement("textarea")}}.</dd> + <dt id="transmisible_de_formulario">transmisible</dt> + <dd>Elementos que se pueden utilizar para construir el conjunto de datos del formulario cuando se envía el formulario. Contiene {{HTMLElement("button")}}, {{HTMLElement("input")}}, {{deprecated_inline()}}{{HTMLElement("keygen")}}, {{HTMLElement("object")}}, {{HTMLElement("select")}} y {{HTMLElement("textarea")}}.</dd> + <dt id="Reiniciable_de_forumalior">reiniciable</dt> + <dd>Elementos que se pueden ver afectados cuando se restablece o reinicia un formulario. Contiene {{HTMLElement("input")}}, {{deprecated_inline()}}{{HTMLElement("keygen")}}, {{HTMLElement("output")}},{{HTMLElement("select")}} y {{HTMLElement("textarea")}}.</dd> +</dl> + +<h2 id="Categorías_secundarias">Categorías secundarias</h2> + +<p>Hay algunas clasificaciones secundarias de elementos que también puede ser útil tener en cuenta.</p> + +<h3 id="Elementos_de_soporte_de_scripts">Elementos de soporte de scripts</h3> + +<p>Los <strong>elementos de soporte de scripts</strong> son elementos que no contribuyen directamente a la salida renderizada de un documento. En cambio, sirven para admitir scripts, ya sea conteniendo o especificando directamente el código del script, o especificando datos que serán utilizados por los scripts.</p> + +<p>Los elementos que admiten scripts son:</p> + +<ul> + <li>{{HTMLElement("script")}}</li> + <li>{{HTMLElement("template")}}</li> +</ul> + +<h2 id="Modelo_de_contenido_transparente">Modelo de contenido transparente</h2> + +<p>Si un elemento tiene un modelo de contenido transparente, entonces su contenido debe estar estructurado de manera que sea HTML 5 válido, incluso si el elemento transparente fuera eliminado y reemplazado por elementos secundarios.</p> + +<p>Por ejemplo, los elementos {{HTMLElement("del")}} y {{HTMLElement("ins")}} son transparentes:</p> + +<pre class="notranslate"><p>Sostenemos que estas verdades son <del><em>sagradas e innegablemente</em></del> <ins>evidentes por sí mismas</ins>.</p> +</pre> + +<p>Si esos elementos fueran eliminados, este fragmento seguiría siendo HTML válido (si no es Español correcto).</p> + +<pre class="notranslate"><p>Sostenemos que estas verdades son <del><em>sagradas e innegablemente</em></del> <ins>evidentes por sí mismas</ins>.</p> +</pre> + +<h2 id="Otros_modelos_de_contenido">Otros modelos de contenido</h2> + +<p>Seccionado raíz.</p> diff --git a/files/es/web/guide/html/editable_content/index.html b/files/es/web/guide/html/editable_content/index.html new file mode 100644 index 0000000000..c8818aa7ae --- /dev/null +++ b/files/es/web/guide/html/editable_content/index.html @@ -0,0 +1,226 @@ +--- +title: Making content editable +slug: Web/Guide/HTML/Editable_content +tags: + - Avanzado + - Ejemplo + - Entrada de texto + - Guía + - HTML + - HTML5 + - Texto + - Web + - contentediatable +translation_of: Web/Guide/HTML/Editable_content +--- +<p><span class="seoSummary">En HTML, cualquier elemento puede ser editable. Con el uso de algunos manejadores de eventos de JavaScript, puedes transformar tu página web en un completo y rápido editor de texto. Este artículo brinda información sobre esta funcionalidad.</span></p> + +<h2 id="¿Cómo_funciona">¿Cómo funciona?</h2> + +<p>Todo lo que debes hacer es definir el atributo {{htmlattrxref("contenteditable")}} en cualquier elemento HTML que quieras hacer editable.</p> + +<p>Este es un ejemplo simple con el cual puedes crear elementos {{HTMLElement("div")}} cuyo contenido pueda ser editado por el usuario.</p> + +<pre class="brush: html"><div contenteditable="true"> + This text can be edited by the user. +</div></pre> + +<p>Aquí esta el HTML anterion en acción:</p> + +<p>{{ EmbedLiveSample('How_does_it_work') }}</p> + +<h2 id="Ejecutando_Comandos">Ejecutando Comandos</h2> + +<p>Cuando un elemento HTML tiene el parametro <code>contenteditable</code> en <code>true</code>, se hace disponible el método {{ domxref("document.execCommand") }}. Esto te permite ejecutar <a href="/en-US/docs/Web/API/document.execCommand#Commands">comandos</a> para manipular el contenido de una region editable. La mayoria de estos comandos afectan a la selección del documento (bold, italics, etc), mientras que otros insertan nuevos elementos (como añadiendo un link) o afectan a una linea entera (indenting). Cuando usas <code>contentEditable</code>, estás llamando a <code>execCommand</code> que afectará al elemento editable activo.</p> + +<h2 id="Differences_in_markup_generation">Differences in markup generation</h2> + +<p>El uso de <code>contenteditable</code> en diferentes navegadores ha sido laborioso durante mucho tiempo debido a las diferencias en las marcas generadas por los diferentes navegadores. Por ejemplo, incluso algo tan simple como qué pasa cuando pulsas Enter/Return para crear una nueva línea de texto dentro de un elemento editable era manejado de forma diferente por los navegadores más utilizados (Firefox insertaba {{htmlelement("br")}} elements, IE/Opera usaba {{htmlelement("p")}}, Chrome/Safari usaba {{htmlelement("div")}}).</p> + +<p>Afortunadamente, en los navegadores modernos las cosas son un poco más consistentes. A partir de <a href="/en-US/docs/Mozilla/Firefox/Releases/55">Firefox 55</a>, Firefox ha sido actualizado para envolver las líneas separadas en elementos {{htmlelement("div")}}, igualando el comportamiento de Chrome, el moderno Opera, Edge, y Safari.</p> + +<p>Pruebalo en el ejemplo de abajo.</p> + +<div class="note"> +<p><strong>Note</strong>: Internet Explorer ya no se está desarrollando y usa {{htmlelement("p")}}.</p> +</div> + +<p>Si quieres utilizar un separador de párrafo diferente, todos los navegadores arriba mencionados soportan {{domxref("document.execCommand")}}, el cual provee un DefaultParagraphSeparator comando que te premite cambiarlo. Por ejemplo, para usar {{htmlelement("p")}} elements:</p> + +<pre class="language-js"><code class="language-js">document<span class="punctuation token">.</span><span class="function token">execCommand</span><span class="punctuation token">(</span><span class="string token">"DefaultParagraphSeparator"</span><span class="punctuation token">,</span> <span class="keyword token">false</span><span class="punctuation token">,</span> <span class="string token">"p"</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<h2 id="Seguridad">Seguridad</h2> + +<p>Por razones de seguridad, Firefox no permite al código JavaScript utilizar las características relacionadas con el portapapeles (copiar, pegar, etc.) por defecto. Puedes permitirlo estableciendo las preferencias mostradas abajo usando using <code>about:config</code>:</p> + +<pre class="code">user_pref("capability.policy.policynames", "allowclipboard"); +user_pref("capability.policy.allowclipboard.sites", "https://www.mozilla.org"); +user_pref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess"); +user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess");</pre> + +<h2 id="Ejemplo_un_simple_pero_completo_editor_de_texto_enriquecido">Ejemplo: un simple pero completo editor de texto enriquecido</h2> + +<div style="height: 500px; width: auto; overflow: auto;"> +<pre class="brush: html"><!doctype html> +<html> +<head> +<title>Rich Text Editor</title> +<script type="text/javascript"> +var oDoc, sDefTxt; + +function initDoc() { + oDoc = document.getElementById("textBox"); + sDefTxt = oDoc.innerHTML; + if (document.compForm.switchMode.checked) { setDocMode(true); } +} + +function formatDoc(sCmd, sValue) { + if (validateMode()) { document.execCommand(sCmd, false, sValue); oDoc.focus(); } +} + +function validateMode() { + if (!document.compForm.switchMode.checked) { return true ; } + alert("Uncheck \"Show HTML\"."); + oDoc.focus(); + return false; +} + +function setDocMode(bToSource) { + var oContent; + if (bToSource) { + oContent = document.createTextNode(oDoc.innerHTML); + oDoc.innerHTML = ""; + var oPre = document.createElement("pre"); + oDoc.contentEditable = false; + oPre.id = "sourceText"; + oPre.contentEditable = true; + oPre.appendChild(oContent); + oDoc.appendChild(oPre); + } else { + if (document.all) { + oDoc.innerHTML = oDoc.innerText; + } else { + oContent = document.createRange(); + oContent.selectNodeContents(oDoc.firstChild); + oDoc.innerHTML = oContent.toString(); + } + oDoc.contentEditable = true; + } + oDoc.focus(); +} + +function printDoc() { + if (!validateMode()) { return; } + var oPrntWin = window.open("","_blank","width=450,height=470,left=400,top=100,menubar=yes,toolbar=no,location=no,scrollbars=yes"); + oPrntWin.document.open(); + oPrntWin.document.write("<!doctype html><html><head><title>Print<\/title><\/head><body onload=\"print();\">" + oDoc.innerHTML + "<\/body><\/html>"); + oPrntWin.document.close(); +} +</script> +<style type="text/css"> +.intLink { cursor: pointer; } +img.intLink { border: 0; } +#toolBar1 select { font-size:10px; } +#textBox { + width: 540px; + height: 200px; + border: 1px #000000 solid; + padding: 12px; + overflow: scroll; +} +#textBox #sourceText { + padding: 0; + margin: 0; + min-width: 498px; + min-height: 200px; +} +#editMode label { cursor: pointer; } +</style> +</head> +<body onload="initDoc();"> +<form name="compForm" method="post" action="sample.php" onsubmit="if(validateMode()){this.myDoc.value=oDoc.innerHTML;return true;}return false;"> +<input type="hidden" name="myDoc"> +<div id="toolBar1"> +<select onchange="formatDoc('formatblock',this[this.selectedIndex].value);this.selectedIndex=0;"> +<option selected>- formatting -</option> +<option value="h1">Title 1 &lt;h1&gt;</option> +<option value="h2">Title 2 &lt;h2&gt;</option> +<option value="h3">Title 3 &lt;h3&gt;</option> +<option value="h4">Title 4 &lt;h4&gt;</option> +<option value="h5">Title 5 &lt;h5&gt;</option> +<option value="h6">Subtitle &lt;h6&gt;</option> +<option value="p">Paragraph &lt;p&gt;</option> +<option value="pre">Preformatted &lt;pre&gt;</option> +</select> +<select onchange="formatDoc('fontname',this[this.selectedIndex].value);this.selectedIndex=0;"> +<option class="heading" selected>- font -</option> +<option>Arial</option> +<option>Arial Black</option> +<option>Courier New</option> +<option>Times New Roman</option> +</select> +<select onchange="formatDoc('fontsize',this[this.selectedIndex].value);this.selectedIndex=0;"> +<option class="heading" selected>- size -</option> +<option value="1">Very small</option> +<option value="2">A bit small</option> +<option value="3">Normal</option> +<option value="4">Medium-large</option> +<option value="5">Big</option> +<option value="6">Very big</option> +<option value="7">Maximum</option> +</select> +<select onchange="formatDoc('forecolor',this[this.selectedIndex].value);this.selectedIndex=0;"> +<option class="heading" selected>- color -</option> +<option value="red">Red</option> +<option value="blue">Blue</option> +<option value="green">Green</option> +<option value="black">Black</option> +</select> +<select onchange="formatDoc('backcolor',this[this.selectedIndex].value);this.selectedIndex=0;"> +<option class="heading" selected>- background -</option> +<option value="red">Red</option> +<option value="green">Green</option> +<option value="black">Black</option> +</select> +</div> +<div id="toolBar2"> +<img class="intLink" title="Clean" onclick="if(validateMode()&&confirm('Are you sure?')){oDoc.innerHTML=sDefTxt};" src="data:image/gif;base64,R0lGODlhFgAWAIQbAD04KTRLYzFRjlldZl9vj1dusY14WYODhpWIbbSVFY6O7IOXw5qbms+wUbCztca0ccS4kdDQjdTLtMrL1O3YitHa7OPcsd/f4PfvrvDv8Pv5xv///////////////////yH5BAEKAB8ALAAAAAAWABYAAAV84CeOZGmeaKqubMteyzK547QoBcFWTm/jgsHq4rhMLoxFIehQQSAWR+Z4IAyaJ0kEgtFoLIzLwRE4oCQWrxoTOTAIhMCZ0tVgMBQKZHAYyFEWEV14eQ8IflhnEHmFDQkAiSkQCI2PDC4QBg+OAJc0ewadNCOgo6anqKkoIQA7" /> +<img class="intLink" title="Print" onclick="printDoc();" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oEBxcZFmGboiwAAAAIdEVYdENvbW1lbnQA9syWvwAAAuFJREFUOMvtlUtsjFEUx//n3nn0YdpBh1abRpt4LFqtqkc3jRKkNEIsiIRIBBEhJJpKlIVo4m1RRMKKjQiRMJRUqUdKPT71qpIpiRKPaqdF55tv5vvusZjQTjOlseUkd3Xu/3dPzusC/22wtu2wRn+jG5So/OCDh8ycMJDflehMlkJkVK7KUYN+ufzA/RttH76zaVocDptRxzQtNi3mRWuPc+6cKtlXZ/sddP2uu9uXlmYXZ6Qm8v4Tz8lhF1H+zDQXt7S8oLMXtbF4e8QaFHjj3kbP2MzkktHpiTjp9VH6iHiA+whtAsX5brpwueMGdONdf/2A4M7ukDs1JW662+XkqTkeUoqjKtOjm2h53YFL15pSJ04Zc94wdtibr26fXlC2mzRvBccEbz2kiRFD414tKMlEZbVGT33+qCoHgha81SWYsew0r1uzfNylmtpx80pngQQ91LwVk2JGvGnfvZG6YcYRAT16GFtW5kKKfo1EQLtfh5Q2etT0BIWF+aitq4fDbk+ImYo1OxvGF03waFJQvBCkvDffRyEtxQiFFYgAZTHS0zwAGD7fG5TNnYNTp8/FzvGwJOfmgG7GOx0SAKKgQgDMgKBI0NJGMEImpGDk5+WACEwEd0ywblhGUZ4Hw5OdUekRBLT7DTgdEgxACsIznx8zpmWh7k4rkpJcuHDxCul6MDsmmBXDlWCH2+XozSgBnzsNCEE4euYV4pwCpsWYPW0UHDYBKSWu1NYjENDReqtKjwn2+zvtTc1vMSTB/mvev/WEYSlASsLimcOhOBJxw+N3aP/SjefNL5GePZmpu4kG7OPr1+tOfPyUu3BecWYKcwQcDFmwFKAUo90fhKDInBCAmvqnyMgqUEagQwCoHBDc1rjv9pIlD8IbVkz6qYViIBQGTJPx4k0XpIgEZoRN1Da0cij4VfR0ta3WvBXH/rjdCufv6R2zPgPH/e4pxSBCpeatqPrjNiso203/5s/zA171Mv8+w1LOAAAAAElFTkSuQmCC"> +<img class="intLink" title="Undo" onclick="formatDoc('undo');" src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7/I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq7046807TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfEwhdRIH4fh/DZMICe3/C4nBQBADs=" /> +<img class="intLink" title="Redo" onclick="formatDoc('redo');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1////yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9NaEDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==" /> +<img class="intLink" title="Remove formatting" onclick="formatDoc('removeFormat')" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB501ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqGXz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMzdeiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3//sf37/1/c02cCG1lB8f//f95DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af///2ckaHBp7+7wmavP5n76+P2ClrLIYl8H9W36auJCbCxM4szMTJac7Kza////R3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tAwMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1lsXc4Db7z8C3r8p7Qjf///2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwffj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv//vPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrjb/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCcXmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc666s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg=="> +<img class="intLink" title="Bold" onclick="formatDoc('bold');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" /> +<img class="intLink" title="Italic" onclick="formatDoc('italic');" src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALAAAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" /> +<img class="intLink" title="Underline" onclick="formatDoc('underline');" src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALAAAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA7" /> +<img class="intLink" title="Left align" onclick="formatDoc('justifyleft');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" /> +<img class="intLink" title="Center align" onclick="formatDoc('justifycenter');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" /> +<img class="intLink" title="Right align" onclick="formatDoc('justifyright');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" /> +<img class="intLink" title="Numbered list" onclick="formatDoc('insertorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P///////yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEOzyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" /> +<img class="intLink" title="Dotted list" onclick="formatDoc('insertunorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv///////yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud64UwiuKnigGQliQuWOyKQykgAAOw==" /> +<img class="intLink" title="Quote" onclick="formatDoc('formatblock','blockquote');" src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////////////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2CekkErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrTq/b7/i8fp8PAQA7" /> +<img class="intLink" title="Add indentation" onclick="formatDoc('outdent');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMczsYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" /> +<img class="intLink" title="Delete indentation" onclick="formatDoc('indent');" src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3NHa7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==" /> +<img class="intLink" title="Hyperlink" onclick="var sLnk=prompt('Write the URL here','http:\/\/');if(sLnk&&sLnk!=''&&sLnk!='http://'){formatDoc('createlink',sLnk)}" src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb/I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq7046827/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghGi9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" /> +<img class="intLink" title="Cut" onclick="formatDoc('cut');" src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P///////////////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnEbGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" /> +<img class="intLink" title="Copy" onclick="formatDoc('copy');" src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OPs++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAAGrpy+wsbKzIiEAOw==" /> +<img class="intLink" title="Paste" onclick="formatDoc('paste');" src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrpqbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f///////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvBSyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQo9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAAMOaK+bLAOrtLUyt7i5uiUhADs=" /> +</div> +<div id="textBox" contenteditable="true"><p>Lorem ipsum</p></div> +<p id="editMode"><input type="checkbox" name="switchMode" id="switchBox" onchange="setDocMode(this.checked);" /> <label for="switchBox">Show HTML</label></p> +<p><input type="submit" value="Send" /></p> +</form> +</body> +</html> +</pre> +</div> + +<div class="note"><strong>Nota:</strong> si quieres ver cómo estandarizar la creación y la inserción de tu editor en tu página, puedes ver nuestro <a class="internal" href="/@api/deki/files/6243/=rich-text-editor.zip" title="rich-text-editor.zip">más completo ejemplo de editor de texto enriquecido</a>.</div> + +<h2 id="Véase_también">Véase también</h2> + +<ul> + <li>{{domxref("HTMLElement.contentEditable")}}</li> + <li>El atributo global {{htmlattrxref("contenteditable")}} </li> + <li><a href="/en-US/docs/Mozilla/Projects/Midas">Midas</a> (el componente de editor de texto programable)</li> + <li>Browser Support <a href="http://caniuse.com/#feat=contenteditable"> http://caniuse.com/#feat=contenteditable</a></li> +</ul> diff --git a/files/es/web/guide/html/introduction_alhtml_clone/index.html b/files/es/web/guide/html/introduction_alhtml_clone/index.html new file mode 100644 index 0000000000..991cf90181 --- /dev/null +++ b/files/es/web/guide/html/introduction_alhtml_clone/index.html @@ -0,0 +1,172 @@ +--- +title: Introducción al HTML +slug: Web/Guide/HTML/Introduction_alhtml_clone +tags: + - HTML +--- +<p>Cuando miras una página web en el navegador, lo que ves a simple vista son palabras. Estas palabras normalmente tienen algunas características, como diferentes tamaños y colores. En algunos casos la página web puede mostrar imágenes o incluso vídeos. Otras veces, formularios donde puedes introducir o buscar información, o personalizar la apariencia de la página que estás viendo. La página también puede contener animaciones y contenidos que cambian mientras el resto de la página se mantiene sin cambios.</p> + +<p>Varias tecnologías (como <a href="/en-US/docs/CSS" title="CSS">CSS</a>, <a href="/en-US/docs/JavaScript/About_JavaScript" title="JavaScript/About_JavaScript">JavaScript</a>, <a href="/en-US/docs/Scripting_Plugins/Adobe_Flash" title="Scripting_Plugins/Adobe_Flash">Flash</a>, <a href="/en-US/docs/AJAX" title="AJAX">AJAX</a>, <a href="/en-US/docs/JSON" title="JSON">JSON</a>) pueden usarse para definir los elementos que componen una página web. Sin embargo, en el nivel más bajo, una página web se define usando <a href="/en-US/docs/HTML" title="HTML"><strong>HTML</strong></a> (<strong>HyperText Markup Language)</strong>. Sin HTML, no habría páginas web.</p> + +<p>Este artículo proporciona una introducción al HTML. Si alguna vez te has preguntado qué ocurre detrás de tu navegador web, este artículo es el mejor lugar para empezar a aprender.</p> + +<h2 id="Una_breve_historia_del_HTML">Una breve historia del HTML</h2> + +<p>A finales de la década de los 80s, <a href="http://www.w3.org/People/Berners-Lee/" title="http://www.w3.org/People/Berners-Lee/">Tim Berners-Lee</a> estuvo trabajando como físico en <a href="http://public.web.cern.ch/public/" title="http://public.web.cern.ch/public/">CERN</a> (las siglas inglesas de la Organización Europea para la Investigación Nuclear). Ideó un sistema para que los científicos pudieran compartir documentos a través de internet. Antes de su invención, las comunicaciones por Internet sólo permitían transmitir texto plano, empleando tecnologías como el email, <a href="http://en.wikipedia.org/wiki/Ftp" title="http://en.wikipedia.org/wiki/Ftp">FTP</a> (File Transfer Protocol), y <a href="http://en.wikipedia.org/wiki/Usenet" title="http://en.wikipedia.org/wiki/Usenet">Usenet</a>- tecnología en la que se basan los foros de internet. La invención del HTML permitió el uso de un modelo de contenido almacenado en un servidor central, que podía ser mostrado en un terminal local mediante un navegador. Esto simplificó el acceso al contenido y habilitó la posibilidad de mostrar contenido "enriquecido" (como un sofisticado texto formateado y visualización de imagenes).</p> + +<h2 id="¿Qué_es_el_HTML">¿Qué es el HTML?</h2> + +<p>HTML es un <strong>lenguaje de etiquetas</strong>. Indica al navegador como tiene que mostrar el contenido. El HTML separa el "contenido" (palabras, imágenes, audio, video, etc.) de la "presentación" (la definición del tipo de contenido y las instrucciones de cómo esos contenidos tienen que mostrarse). El HTML emplea un conjunto de elementos predefinidos que permiten identificar los distintos tipos de elementos. Estos elementos contienen una o más etiquetas que contienen o expresan el contenido. Estas etiquetas suelen ir encapsuladas entre los símbolos <>, y las etiquetas de cierre (que indican el final de un determinado contenido) están precedidas por una barra /.</p> + +<p>Por ejemplo, el elemento párrafo consiste en una etiqueta de inicio como esta "<p>" y una de cierre "</p>". El siguiente ejemplo muestra un párrafo que está contenido dentro del elemento párrafo en HTML:</p> + +<div id="Spl1"> +<pre class="brush:html;"><p>Mi perro odia el pescado.</p></pre> +</div> + +<p>Cuando este contenido se muestra en una página web, mediante un navegador, aparece así:</p> + +<p>{{ EmbedLiveSample("Spl1", 400, 50) }}</p> + +<p>El navegador emplea las etiquetas como guías para saber cómo debe ser mostrado el contenido que hay dentro de dichas etiquetas.</p> + +<p>Los elementos que contienen contenidos, normalmente suelen contener también otros elementos. Por ejemplo, el elemento énfasis (etiqueta <em>) puede estar dentro del elemento párrafo:</p> + +<div id="Spl2"> +<pre class="brush:html;"><p>Mi perro <em>odia</em> el pescado.</p></pre> +</div> + +<p>Cuando se muestre se verá del siguiente modo:</p> + +<p>{{ EmbedLiveSample("Spl2", 400, 50) }}</p> + +<p>Algunos elementos no contienen otros elementos. Como es el caso de la etiqueta imagen ("<img>") que simplemente especifica el nombre del archivo que contiene la imagen como atributo:</p> + +<pre class="brush:html;"><img src="smileyface.jpg"></pre> + +<p>En ocasiones, suele ponerse una barra "/" al final de la etiqueta, justo antes del cierre de la misma ">" para indicar el final de la misma "/>". Aunque se trata de algo opcional en HTML, en <a href="/en-US/docs/XHTML" title="XHTML">XHTML</a> es obligatoria (que es un lenguaje que permite una forma de poder implementar XML en los elementos del HTML).</p> + +<p>El resto de este artículo describe con un mayor detalle los conceptos descritos en esta sección. Además, si quieres ver HTML en acción, pásate por <a href="http://thimble.webmaker.org/en-US/projects/wrangler/edit" title="http://thimble.webmaker.org/en-US/projects/wrangler/edit">Mozilla Thimble</a>, que es un editor online interactivo que enseña cómo escribir HTML. Además, en el <a href="/en-US/docs/HTML/HTML_Elements" title="HTML/HTML_Elements">HTML Elements</a> podrás ver una lista de los elementos HTML disponibles, así como una descripción de los mismos y el uso de cada uno de ellos.</p> + +<h2 id="Elementos_—_los_bloques_básicos_de_construcción">Elementos — los bloques básicos de construcción</h2> + +<p>El HTML consiste en una serie de elementos. Los Elementos definen el significado <strong>semántico</strong> del contenido. Todos los Elementos están incluídos entre dos grandes etiquetas, que a su vez contienen otras etiquetas. Por ejemplo, el elemento "<p>" indica un párrafo; el elemento "<img>" indica una imagen. Mira la página <a href="/en-US/docs/HTML/Element" title="HTML/Element">HTML Elements</a> para ver una lista completa de todos los elementos.</p> + +<p>Algunos elementos tienen un significado muy preciso, como "esto es una imagen", "esto es un encabezado" o "esto es una lista ordenada". Otros elementos resultan menos específicos, como "esto es una sección de una página" o "esto es parte de un texto". Finalmente otros elementos son usados por razones técnicas, como "esto es la información identificativa de la página que no debe ser mostrada". De un modo y otro, todos los elementos del HTML tienen un determinado valor semántico.</p> + +<p>Muchos elementos contienen otros elementos, formando una estructura jerárquica. Un ejemplo simple, pero completo de una página web sería este:</p> + +<pre class="brush:html;"><html> + <body> + + <p>Mi perro <em>odia</em> el pescado.</p> + + </body> +</html></pre> + +<p>Como puedes ver, los elementos <html> encierran el resto del documento, y el elemento <body> encierra el contenido de la página. Esta estructura crece con las ramas de un árbol, donde los elementos <body> y <p> son las ramas que crecen del tronco que es <html>. Esta estructura jerárquica es lo que se denomina <strong>DOM</strong>: siglas inglesas del Documento Objeto Modelo (<strong>Document Object Model)</strong>.</p> + +<h2 id="Etiquetas">Etiquetas</h2> + +<p>Los documentos HTML están escritos en texto plano. Pueden ser escritos mediante editores de texto capaces de guardar contenido de texto plano (aunque la mayor parte de los creadores de código HTML prefieren editores especializados que resaltan las partes de código propias de la sintaxis del HTML y muestran el DOM). Los nombres de las Etiquetas, pueden escribirse en mayúsculas o en minúsculas. Aunque, el <a href="http://www.w3.org/" title="http://www.w3.org/">W3C</a> (Asociación Global que vela por mantener los estándares HTML) recomiendan usar minúsculas (y además el <a href="/en-US/docs/XHTML" title="XHTML">XHTML</a> requiere de las minúsculas).</p> + +<p>El código HTML contenido entre los signos de menor que ("<") al comienzo y mayor que (">") al final, tienen un significado especial. Es lo que denominamos etiquetas. He aquí un ejemplo sencillo:</p> + +<pre class="brush: xml"><p>Esto es texto dentro de un párrafo.</p> +</pre> + +<p>En este ejemplo hay una etiqueta de comienzo y otra de cierre. Las etiquetas de cierre son las mismas que las etiquetas de comienzo sólo que contienen una barra justo después del signo menor que. Muchos elementos de HTML se escriben empleando las dos etiquetas de comienzo y final. Las etiquetas de comiezo y final de un elemento deben estar adecuadamente anidadas, esto significa que las etiquetas de cierre deben escribirse en el orden inverso al de las etiquetas de inicio. La regla del anidamiento de etiquetas tiene que cumplirse de forma escrupulosa para poder escribir <strong>código válido</strong>.</p> + +<p>Esto es un ejemplo de <em>código válido</em>:</p> + +<pre class="brush: xml"><em>Me <strong>refiero</strong> a eso</em>. +</pre> + +<p>Esto es un ejemplo de <em>código inválido</em>:</p> + +<pre class="brush: xml">Invalido: <em>Me <strong>refiero</em> a eso</strong>.</pre> + +<p>Observa que en el ejemplo válido, la etiqueta de cierre para el elemento anidado está situada antes de la etiqueta de cierre del elemento que la contenedor.</p> + +<div class="note"> +<p>Hasta la adopción de las reglas revisadas del HTML5, los navegadores no interpretaban los códigos no válidos del mismo modo y provocaban distintos resultados cuando se encontraban con estas partes de código. Los navegadores eran tolerantes con los autores de código Web, pero por desgracia no todos de la misma forma, llevando a situaciones impredecibles a la hora de interpretar códigos no válidos de HTML. Pero esos días han acabado tras la última evolución de los navegadores como Internet Explorer 10, Firefox 4, Opera 11.60, Chrome 18 o Safari 5, a medida que han implementado las nuevas normas de interpretación de código HTML no válido. Aquí puede ver el resultado de un código invalido para el mismo arbol DOM <a class="external" href="http://arstechnica.com/open-source/news/2011/11/a-look-at-the-state-of-html5-parsing-and-the-opera-1160-beta.ars" title="http://arstechnica.com/open-source/news/2011/11/a-look-at-the-state-of-html5-parsing-and-the-opera-1160-beta.ars">en todos los navegadores modernos</a>.</p> +</div> + +<p>Algunos elementos no contienen texto o ningún otro elemento. Es lo que se denominan elementos vacíos y no necesitan etiquetas de cierre. Este es un ejemplo:</p> + +<pre class="brush: xml"><img src="smileyface.jpg"></pre> + +<p>Mucha gente marca los elementos vacíos usando una barra al final de la etiqueta, justo antes del simbolo mayor que (necesario en los códigos de XHTML).</p> + +<pre class="brush: xml"><img src="smileyface.jpg" /></pre> + +<p>En HTML esta barra no aporta ninguna funcionalidad técnica y su uso es solamente una elección de estilo.</p> + +<h2 id="Atributos">Atributos</h2> + +<p>La etiqueta de comienzo puede contener información adicional, tal y como puede verse en el siguiente ejemplo. Dicha información es lo que se conoce como <strong>atributos</strong>. Los atributos suelen consistir en dor partes:</p> + +<ul> + <li>Un atributo <strong>nombre </strong>(name).</li> + <li>Un atributo <strong>valor</strong> (value).</li> +</ul> + +<p>Algunos atributos sólo pueden tener un único valor. Son atributos <strong>Booleanos</strong> y pueden ser incluidos para especificar el nombre del atributo, o dejar su valor vacío. Así los siguientes tres ejemplos tienen el mismo significado:</p> + +<pre class="brush: xml"><input required="required"> + +<input required=""> + +<input required> +</pre> + +<p>Los valores de los atributos que constan de una sola palabra o un número se pueden escribir tal cual, pero en cuanto hay dos o más cadenas de caracteres en el valor, éstos deben escribirse entre comillas. Están permitidas tanto las comillas simples ('), como las comillas dobles (") aunque muchos desarrolladores prefieren utilizar siempre comillas simples para que el código sea menos ambiguo para la vista y para evitar errores. El siguiente es semejante error..:Attribute values that consist of a single word or number may be written as they are, but as soon as there are two or more strings of characters in the value, it must be written within quotation marks. Both single quotes (') and double quotes (") are allowed. Many developers prefer to always use quotes to make the code less ambiguous to the eye and to avoid mistakes. El siguiente código sería un error:</p> + +<pre class="brush: xml"><p class=foo bar> (Ten cuidado, esto probablemente no quiere decir lo que piensas que significa.)</pre> + +<p>En este ejemplo suponemos que el valor del atributo es "foo bar" pero al no haber comillas en el código se interpreta como si se hubiera escrito así:</p> + +<pre class="brush: xml"><p class="foo" bar=""></pre> + +<h2 id="Nombre_de_caracteres_referenciados">Nombre de caracteres referenciados</h2> + +<p>Los<strong> Caraceteres Referenciados </strong> (a veces llamados<em> entidades) </em>son combinaciones de caracteres que sirven para mostrar en el navegador símbolos que tienen un significado especial en el código HTML. Por ejemplo, HTML interpreta que el símbolo menor que y mayor que son delimitadores de una etiqueta. Si quieres que estos simbolos sean mostrados en el contenido del texto, debemos usar los nombres de referencia de estos caracteres. Aquí están los cuatro caracteres referenciados más comunes, que no estaría de más que memorizases:</p> + +<ul> + <li><code>&gt;</code> representa el carater mayor que (<code>></code>)</li> + <li><code>&lt;</code> representa el caracter menor que (<code><</code>)</li> + <li><code>&amp;</code> representa el caracter ampersand (<code>&</code>)</li> + <li><code>&quot;</code> representa el caracter de comillas dobles (")</li> +</ul> + +<p>Hay <a class="external" href="http://www.w3.org/TR/2011/WD-html5-20110113/named-character-references.html" title="http://www.w3.org/TR/html5/named-character-references.html#named-character-references">muchas más entidades</a>, pero estas cuatro son las más importantes por que representan caracteres que tienen un significado especial en HTML.</p> + +<h2 id="Tipo_de_documento_y_comentarios">Tipo de documento y comentarios</h2> + +<p>Además de las etiquetas, el contenido y las entidades, un documento de HTML debe contener una declaración <strong>doctype</strong> en la primera línea. En el HTML actual esto se escribe del siguiente modo:</p> + +<pre class="brush: xml"><!DOCTYPE html></pre> + +<p>El doctype tiene una historia larga y complicada, pero todo lo que necesitas saber ahora es que el doctype le dice al navegador que interprete el código HTML y CSS de acuerdo a los estándares web del <a href="http://www.w3.org/" title="http://www.w3.org/">W3C</a> y que no trate de emular que se trata de un Internet Explorer de los 90's. (Consultar <a href="/en-US/docs/Quirks_Mode_and_Standards_Mode" title="Mozilla's Quirks Mode">peculiaridades</a>.)</p> + +<p>HTML tiene un mecanismo para poder introducir <strong>comentarios</strong> al código que no serán mostrados en la página cuando esta sea interpretada o leída por un navegador web. Esto suele emplearse para añadir explicaciones al código, o dejar notas para explicar a otras personas cómo trabaja el código de la página, o simplemente para dejar recordatorios para uno mismo. Los comentarios en HTML están contenidos entre los siguientes símbolos:</p> + +<pre class="brush: xml"><!-- Esto es un comentario de texto --></pre> + +<h2 id="Un_pequeño_documento_pero_completo">Un pequeño documento pero completo</h2> + +<p>Colocando todas estas explicaciones juntas, aquí os dejamos un pequeño ejemplo de un documento HTML completo. Puedes copiar este código en un editor de textos, guardarlo como <em>myfirstdoc.html</em> y cargarlo en un navegador. Asegurate de estar usando los códigos de caracteres UTF-8. Dado que este documento no utiliza estilos (CSS) su apariencia será muy plana, pero sólo se trata de un pequeño comienzo.</p> + +<pre class="brush: xml"><!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8" /> + <title>A tiny document</title> +</head> +<body> + <h1>Main heading in my document</h1> + <!-- Note that it is "h" + "1", not "h" + the letter "one" --> + <p>Loook Ma, I am coding <abbr title="Hyper Text Markup Language">HTML</abbr>.</p> +</body> +</html> +</pre> diff --git a/files/es/web/guide/index.html b/files/es/web/guide/index.html new file mode 100644 index 0000000000..7de6c6ee26 --- /dev/null +++ b/files/es/web/guide/index.html @@ -0,0 +1,72 @@ +--- +title: Guía de Desarrollo Web +slug: Web/Guide +tags: + - Guia(2) + - Guía + - Landing + - NeedsTranslation + - TopicStub + - Web +translation_of: Web/Guide +--- +<dl> + <dt>Este artículo proporciona información para ayudarte a hacer uso de tecnologías y APIs.</dt> +</dl> + +<div> +<div> +<div class="row topicpage-table"> +<div class="section"> +<dl> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Learn/HTML">Área de aprendizaje HTML</a></dt> + <dd class="landingPageList"><strong>HyperText Markup Language</strong> (lenguaje de marcas de hipertexto) es el lenguaje principal de prácticamente todo el contenido web. La mayoría de las cosas que ves en en la pantalla de tu navegador están escritas, fundamentalmente, utilizando HTML.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/es/docs/Web/Guide/CSS">Guía del Desarrollador: CSS</a></dt> + <dd class="landingPageList">CSS (hojas de estilo en cascada) es un lenguaje usado para describir la presentación gráfica de un documento escrito en HTML.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/Events">Guía de Eventos </a></dt> + <dd class="landingPageList">El término "Eventos" se refiere tanto al patrón de diseño usado para el manejo asíncrono de sucesos que ocurren durante el tiempo de vida de una página web como al nombramiento, caracterización y uso de grandes cantidades de sucesos de diferentes tipos.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX">AJAX</a></dt> + <dd class="landingPageList">AJAX es el término utilizado para definir un conjunto de tecnologías que permiten a las aplicaciones web hacer rápidamente actualizaciones incrementales a la interfaz de usuario sin la necesidad de recargar toda la página web. Esto permite que las aplicaciones web sean más rápidas y más responsivas a las acciones de los usuarios.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/es/docs/Web/Guide/Graphics">Elementos Gráficos en la Web</a></dt> + <dd class="landingPageList">Las páginas web y aplicaciones modernas a menudo necesitan presentar elementos gráficos (2D, 3D o video).</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/API">Guía de Web APIs</a></dt> + <dd class="landingPageList">Listado de todas las APIs web y qué hacen.</dd> + <dt><a href="/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a></dt> + <dd>JavaScript es un poderoso lenguaje de scripting utilizado para crear aplicaciones para la Web.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Localizations_and_character_encodings">Localización y codificación de Caracteres</a></dt> + <dd class="landingPageList">Los navegadores procesan el texto internamente como Unicode. No obstante, una forma de representar los caracteres a nivel de bytes (codificación) se usa para transferir texto a través de la red a un navegador web. En <a class="external external-icon" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#charset" title="http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#charset">recomendaciones de la especificación HTML</a> se aconseja el uso de la codificación UTF-8 (que puede representar todo Unicode) e independientemente de la codificación usada se requiere que el contenido web declare que codificación utiliza.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/Mobile">Desarrollo Web Móvil</a></dt> + <dd class="landingPageList">Esta página proporciona una visión general de algunas de las principales técnicas necesarias para el diseño de sitios web que funcionen en dispositivos móviles. Si estás buscando información sobre el proyecto Firefox OS de Mozilla, mira la web <a href="https://developer.mozilla.org/en/Mozilla/Firefox_OS" title="Boot to Gecko">Firefox OS</a>. O puede que te interesen los detalles de <a href="https://developer.mozilla.org/en/Mozilla/Firefox_for_Android" title="Firefox for Android">Firefox para Android.</a></dd> +</dl> + +<dl> +</dl> +</div> + +<div class="section"> +<dl> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/Apps/Progressive#Core_PWA_guides">Progressive Web Apps (PWA)</a></dt> + <dd class="landingPageList">Las aplicaciones web progresivas usan APIs Web modernas junto con mejoras progresivas estratégicas para crear aplicaciones multi-plataforma. Estas aplicaciones funcionan donde sea y proporcionan muchas características que brindan la misma experiencia de usuario que una aplicación nativa. Este conjunto de documentos y guías te indican sobre todo lo que debes saber de las PWAs.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/es/docs/Web/Guide/Performance">Optimización y Rendimiento</a></dt> + <dd class="landingPageList">Cuando creamos modernas Web apps y páginas web, es importante hacer que tu contenido rinda bien. Eso es, hacer que funcione de forma rápida y eficiente. Esto permite trabajar de forma más efectiva tanto a los usuarios de potentes equipos de sobremesa como a los que utilizan dispositivos portátiles con menos potencia.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/Parsing_and_serializing_XML">Mapeo y Serialización XML</a></dt> + <dd class="landingPageList">La Plataforma Web provee los diferentes métodos de parseo y serialización, cada uno con sus pros y contras.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/SVG-in-OpenType">SVG-in-OpenType</a></dt> + <dd class="landingPageList">El SVG-in-OpenType está actualmente en manos del <a class="external external-icon" href="http://mpeg.chiariglione.org/">MPEG group</a>. Una vez listos para una más amplia adopción de información desde <a class="external external-icon" href="https://wiki.mozilla.org/SVGOpenTypeFonts">wiki.mozilla.org</a> nos trasladaremos aquí, actualizados y expandidos.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/WOFF">El Web Open Font Format (WOFF)</a></dt> + <dd class="landingPageList"><strong>WOFF</strong> ( <strong>Web Open Font Format</strong>) es un formato de tipografías para páginas web desarrollado por Mozilla en conjunto con Type Supply, LettError y otras organizaciones.</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects">Utilizar FormData Objects</a></dt> + <dd class="landingPageList"><a href="https://developer.mozilla.org/en/DOM/XMLHttpRequest/FormData" title="en/DOM/XMLHttpRequest/FormData"><code>FormData</code></a> te permite compilar un conjunto de pares clave/valor para enviarlos utilizando XMLHttpRequest. En un principio se pensó como manera de enviar información de formularios, pero puede utilizarse independientemente de los formularios para transmitir datos. La información trasmitida está en el mismo formato que se utiliza mediante el método <code>submit()</code> de los formularios para enviarla si el tipo de codificación del formulario fuese "multipart/form-data".</dd> + <dt class="landingPageList"><a href="https://developer.mozilla.org/es/docs/Glossary">Glosario</a></dt> + <dd class="landingPageList">Define gran cantidad de términos técnicos relativos a las páginas Web e Internet.</dd> +</dl> +</div> +</div> +</div> +</div> + +<h2 id="Ver_también">Ver también</h2> + +<ul> + <li><a href="/en-US/docs/Web/Reference" title="/en-US/docs/Web/Reference">Referencia para el desarrollador Web</a></li> +</ul> diff --git a/files/es/web/guide/movil/index.html b/files/es/web/guide/movil/index.html new file mode 100644 index 0000000000..684d3df672 --- /dev/null +++ b/files/es/web/guide/movil/index.html @@ -0,0 +1,75 @@ +--- +title: Desarrollo Web Móvil +slug: Web/Guide/Movil +tags: + - Intermedio + - NecesitaEjemplo +translation_of: Web/Guide/Mobile +--- +<p>Esta página proporciona una visión general de algunas de las principales técnicas necesarias para diseñar sitios web que funcionen bien en dispositivos móviles. Si está buscando información sobre el proyecto Firefox OS de Mozilla, consulte la página de <a href="/en/Mozilla/Firefox_OS" title="Boot to Gecko">Firefox OS</a>. O podría estar interesado en detalles sobre <a href="/en/Mozilla/Firefox_for_Android" title="Firefox for Android">Firefox para Android</a>.</p> + +<p>Hemos organizado esta documentación en dos secciones, <a href="#DisenandoParaDispositivosMoviles">diseñando para dispositivos móviles</a> y <a href="#DesarrolloParaDiferentesNavegadores">desarrollo para diferentes navegadores</a>. Vea también la guía a la <a href="/en-US/docs/Web_Development/Mobile/Mobile-friendliness" title="/en-US/docs/Web_Development/Mobile/Mobile-friendliness">amigabilidad móvil</a> para desarrolladores web de Jason Grlicky.</p> + +<h2 id="Diseñando_para_dispositivos_móviles"><a id="DisenandoParaDispositivosMoviles" name="DisenandoParaDispositivosMoviles"></a>Diseñando para dispositivos móviles</h2> + +<p>Los dispositivos móviles tienen características de hardware bastante diferentes comparados con los ordenadores de escritorio/sobremesa o portátiles. Obviamente sus pantallas son usualmente más pequeñas, pero además habitualmente también cambian automáticamente su orientación, entre retrato o paisaje, según el usuario rota el dispositivo. Por lo general tienen pantallas táctiles para la entrada de datos por parte del usuario. APIs como la geolocalización o la orientación, o bien no son soportadas en ordenadores de escritorio o son mucho menos útiles, y estas APIs ofrecen a los usuarios móviles nuevas formas de interactuar con su sitio web.</p> + +<h3 id="Trabajando_con_pantallas_pequeñas">Trabajando con pantallas pequeñas</h3> + +<p><a href="https://developer.mozilla.org/es/docs/Desarrollo_Web/Web_adaptable" title="en/Web_Development/Responsive_Web_design">Diseño web adaptable</a> es un término para un conjunto de técnicas que permiten a su sitio web adaptar su diseño según el entorno de visualización — lo más evidente, el tamaño y orientación de la pantalla — cambie. Incluye técnicas como:</p> + +<ul> + <li>diseño CSS fluido, para hacer que la página se adapte sin problemas según cambie el tamaño de la ventana del navegador y</li> + <li>el uso de <a href="https://developer.mozilla.org/es/docs/CSS/Media_queries" title="en/CSS/Media_queries">media queries</a> para incluir condicionalmente reglas CSS adecuadas para el <a href="https://developer.mozilla.org/es/docs/CSS/Media_queries#width" title="en/CSS/Media_queries#width">ancho</a> y <a href="https://developer.mozilla.org/es/docs/CSS/Media_queries#height" title="en/CSS/Media_queries#height">alto</a> de la pantalla.</li> +</ul> + +<p>La <a href="https://developer.mozilla.org/es/docs/M%C3%B3vil/Viewport_meta_tag" title="en/Mobile/Viewport_meta_tag">etiqueta meta viewport</a> ordena al navegador que muestre su sitio web a la escala adecuada para el dispositivo del usuario.</p> + +<h3 id="Trabajando_con_pantallas_táctiles">Trabajando con pantallas táctiles</h3> + +<p>Para usar una pantalla táctil necesitará trabajar con eventos <a href="https://developer.mozilla.org/es/docs/DOM/Touch_events" title="en/DOM/Touch_events">DOM Touch</a>. No tendrá la posibilidad de usar la pseudo-clase <a href="https://developer.mozilla.org/es/docs/Web/CSS/%3Ahover" title="En/CSS/:hover">CSS :hover</a> y tendrá que diseñar elementos interactivos como botones para respetar el hecho de que los dedos son más gordos que el puntero del ratón. Vea este artículo sobre <a class="external" href="http://www.whatcreative.co.uk/blog/tips/designing-for-touch-screen/">diseñar para pantallas táctiles</a>.</p> + +<p>Puede usar el <em>media query</em> <a href="https://developer.mozilla.org/es/docs/CSS/Media_queries#-moz-touch-enabled" title="en/CSS/Media_queries#-moz-touch-enabled">-moz-touch-enabled</a> para cargar una CSS diferente en un dispositivo con pantalla táctil.</p> + +<h3 id="Optimizando_imágenes">Optimizando imágenes</h3> + +<p>Para ayudar a los usuarios cuyos dispositivos tienen un bajo o caro ancho de banda, puede optimizar las imágenes cargando sólo aquellas apropiadas para el tamaño y resolución del dispositivo. Es algo que se hace en la CSS consultando la <a href="https://developer.mozilla.org/es/docs/CSS/Media_queries#height" title="en/CSS/Media_queries#height">altura</a> de pantalla, <a href="https://developer.mozilla.org/es/docs/CSS/Media_queries#width" title="en/CSS/Media_queries#width">anchura</a> y <a href="https://developer.mozilla.org/es/docs/CSS/Media_queries#-moz-device-pixel-ratio" title="en/CSS/Media_queries#-moz-device-pixel-ratio">proporción de píxeles</a>.</p> + +<p>También puede hacer uso de propiedades CSS para implementar efectos visuales como <a href="https://developer.mozilla.org/es/docs/CSS/Using_CSS_gradients" title="en/CSS/Using_CSS_gradients">gradientes</a> y <a href="https://developer.mozilla.org/es/docs/Web/CSS/box-shadow" title="En/CSS/Box-shadow">sombras</a> sin utilizar imágenes para ello.</p> + +<h3 id="APIs_móviles">APIs móviles</h3> + +<p>Finalmente, puede aprovechar las nuevas posibilidades ofrecidas por los dispositivos móviles, como la <a href="https://developer.mozilla.org/es/docs/Web/API/Detecting_device_orientation" title="en/Detecting_device_orientation">orientación</a> y la <a href="https://developer.mozilla.org/es/docs/WebAPI/Using_geolocation" title="En/Using_geolocation">geolocalización</a>.</p> + +<h2 id="Desarrollo_para_diferentes_navegadores"><a id="DesarrolloParaDiferentesNavegadores" name="DesarrolloParaDiferentesNavegadores"></a>Desarrollo para diferentes navegadores</h2> + +<h3 id="Escribir_código_para_diferentes_navegadores_(cross-browser)">Escribir código para diferentes navegadores (<em>cross-browser</em>)</h3> + +<p>Para crear sitios web que funcionen aceptablemente en diferentes navegadores móviles:</p> + +<ul> + <li>Intente evitar características específicas de un navegador, como las propiedades CSS prefijadas por el proveedor (<em>vendor-prefixed</em>).</li> + <li>Si necesita utilizar estas características, compruebe si otros navegadores implementan sus propias versiones e inclúyalas igualmente.</li> + <li>Para navegadores que no soportan estas características, ofrezca una alternativa aceptable.</li> +</ul> + +<p>Por ejemplo, si establece un gradiente como fondo para cierto texto usando una propiedad prefijada por el proveedor (<em>vendor-prefixed</em>) como <code>-webkit-linear-gradient</code>, es mejor incluir las otras versiones prefijadas de la propiedad <a href="https://developer.mozilla.org/es/docs/Web/CSS/linear-gradient" title="en/CSS/linear-gradient">linear-gradient</a> (gradiente linear). Si no lo hace, asegúrese al menos de que el fondo por defecto contrasta con el texto. Así, la página será al menos usable en un navegador al que no esté dirigida su regla <code>linear-gradient</code>.</p> + +<p>Vea esta <a href="https://developer.mozilla.org/es/docs/Web/CSS/Referencia_CSS/Extensiones_CSS_Mozilla" title="en/CSS/CSS_Reference/Mozilla_Extensions">lista de propiedades específicas para Gecko</a>, esta lista de <a href="/en/CSS/CSS_Reference/Webkit_Extensions" title="en/CSS/CSS_Reference/Webkit_Extensions">propiedades específicas para WebKit</a> y la <a class="external" href="http://peter.sh/experiments/vendor-prefixed-css-property-overview/">tabla de propiedades específicas de proveedores (<em>vendor-specific</em>)</a> de Peter Beverloo.</p> + +<p>Usar herramientas como <a class="external" href="http://csslint.net/">CSS Lint</a> puede ayudar a encontrar problemas como este en el código y preprocesadores como <a class="external" href="http://sass-lang.com/">SASS</a> y <a class="external" href="http://lesscss.org/">LESS</a> pueden ser de ayuda para crear código compatible con diferentes navegadores.</p> + +<h3 id="Precaución_al_husmear_el_agente_de_usuario_(user_agent)">Precaución al husmear el agente de usuario (<em>user agent</em>)</h3> + +<p>Es preferible para los sitios web usar las técnicas enumeradas anteriormente con el objetivo de detectar características específicas del dispositivo, como el tamaño de pantalla y las pantallas táctiles, y adaptarse a ellas adecuadamente. Pero a veces esto no es práctico y los sitios web recurren a analizar la cadena de agente de usuario del navegador (<em>user agent</em>) para intentar distinguir entre ordenadores de escritorio, tabletas y teléfonos, y servir diferente contenido a cada tipo de dispositivo.</p> + +<p>Si hace esto, asegúrese de que su algoritmo es correcto y no está sirviendo el tipo equivocado de contenido a un dispositivo porque no entiende la cadena de un agente de usuario particular. Vea esta <a href="/en/Browser_detection_using_the_user_agent#Mobile.2C_Tablet_or_Desktop" title="browser detection using the user agent">guía para usar la cadena de agente de usuario para determinar el tipo de dispositivo</a>.</p> + +<h3 id="Probar_en_múltiples_navegadores">Probar en múltiples navegadores</h3> + +<p>Compruebe su sitio web en múltiples navegadores. Esto significa probarlo en múltiples plataformas — al menos iOS y Android.</p> + +<ul> + <li>Pruebe Safari móvil en iPhone usando el <a class="link-https" href="https://developer.apple.com/devcenter/ios/index.action">simulador iOS</a>.</li> + <li>Pruebe Opera y Firefox utilizando el <a class="link-https" href="https://developer.android.com/sdk/index.html">Android SDK</a>. Vea estas instrucciones adicionales para <a class="link-https" href="https://wiki.mozilla.org/Mobile/Fennec/Android/Emulator">ejecutar Firefox para Android usando el emulador de Android</a>.</li> +</ul> diff --git a/files/es/web/guide/parsing_and_serializing_xml/index.html b/files/es/web/guide/parsing_and_serializing_xml/index.html new file mode 100644 index 0000000000..faff8bfbe4 --- /dev/null +++ b/files/es/web/guide/parsing_and_serializing_xml/index.html @@ -0,0 +1,133 @@ +--- +title: >- + Convertir código a cadena de texto (serializing) y visceversa (parsing) a un + XML +slug: Web/Guide/Parsing_and_serializing_XML +translation_of: Web/Guide/Parsing_and_serializing_XML +--- +<p>La plataforma web proveé Los siguientes objetos para hacer parsing (convertir una cadena de texto a código) y serializing (visceversa) a un XML:</p> + +<ul> + <li><a href="/en/XMLSerializer" title="en/XMLSerializer">XMLSerializer</a> para convertir a tipo string el arbol del DOM</li> + <li><a class="internal" href="/en/XPath" title="en/XPath">XPath</a> para apuntar a diferentes partes de un documento<strong> <a href="/en/XML" rel="internal" title="en/XML">XML</a> ( sin seguir la sintaxis XML) y convertirlas a string.</strong></li> + <li><a href="/en/DOM/DOMParser" title="en/DOMParser">DOMParser</a> para convertir a XML desde un tipo string (texto)<strong> dentro del árbol del DOM </strong></li> + <li><a href="/en/nsIXMLHttpRequest" title="en/XMLHttpRequest">XMLHttpRequest</a> para convertit recursos URL direccionables <strong>en arboles del DOM </strong></li> +</ul> + +<h2 id="Parte_1_Como_crear_un_documento_XML">Parte 1: Como crear un documento XML </h2> + +<p>Usar una de la siguientes opciones para crear un documento XML (el cual es una instancia de <code>Document</code>).</p> + +<h3 id="Codificando_textos_al_árbol_del_DOM">Codificando textos al árbol del DOM</h3> + +<div style="overflow: hidden;"> +<pre class="brush: js">var miTexto = '<a id="a"><b id="b">Hey!</b></a>'; +var codigo = new DOMParser(); +var oDOM = codigo.parseFromString(miTexto, "text/xml"); +// Imprimir el nombre del elemento raiz o un mensaje de error +dump(oDOM.documentElement.nodeName == "parsererror" ? "error mientras se codificaba" : oDOM.documentElement.nodeName); +</pre> +</div> + +<h3 id="Creando_un_documento_XML_empezando_desde_un_árbol_de_Objetos_JavaScript_(JXON)">Creando un documento XML empezando desde un árbol de Objetos JavaScript (JXON)</h3> + +<p>Por favor vea JXON<a class="internal" href="/en/JXON#Reverse_Algorithms" title="en/JXON – Reverse Algorithms"> algoritmos </a>de reversa.</p> + +<h3 id="Codificando_rexursos_de_URL_direccionables_en_árboles_del_DOM">Codificando rexursos de URL direccionables en árboles del DOM</h3> + +<h4 id="Usando_XMLHttpRequest">Usando XMLHttpRequest</h4> + +<p>Aquí hay un código de ejemplo que lee y codifica un archivo XML con URL direccionable en un árbol del DOM:</p> + +<pre class="brush: js">var xhr = new XMLHttpRequest(); +xhr.onload = function() { + dump(xhr.responseXML.documentElement.nodeName); +} +xhr.onerror = function() { + dump("Error mientras se tomaba el XML."); +} +xhr.open("GET", "example.xml"); +xhr.responseType = "document"; +xhr.send(); +</pre> + +<p><code>xhr.responseXML</code> es una instancia de {{domxref("Document")}}.</p> + +<h2 id="Parte_2_Como_serializar_el_contenido_de_un_documento_XML">Parte 2: Como serializar el contenido de un documento XML</h2> + +<p>Use the following approaches to serialize the contents of the XML document you created in Part 1.</p> + +<h3 id="Serializing_DOM_trees_to_strings">Serializing DOM trees to strings</h3> + +<p>First, create a DOM tree as described in <a href="/en/How_to_create_a_DOM_tree" title="en/How_to_create_a_DOM_tree">How to Create a DOM tree</a>. Alternatively, use a DOM tree obtained from {{ domxref("XMLHttpRequest") }}.</p> + +<p>Now, let's serialize <code>doc</code> — the DOM tree — to a string:</p> + +<pre class="brush: js">var oSerializer = new XMLSerializer(); +var sXML = oSerializer.serializeToString(doc);</pre> + +<p>The <code>new XMLSerializer()</code> constructor is not available from within a JS XPCOM component (or a <a class="internal" href="/en/JavaScript_code_modules" title="En/JavaScript modules">JS module</a>). Instead, write:</p> + +<pre class="brush: js">var oSerializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"] + .createInstance(Components.interfaces.nsIDOMSerializer); +var sXML = oSerializer.serializeToString(doc); +</pre> + +<h4 id="Pretty_serialization_of_DOM_trees_to_strings">"Pretty" serialization of DOM trees to strings</h4> + +<p>You can <a class="external" href="http://en.wikipedia.org/wiki/Pretty-print">pretty print</a> a DOM tree using <a href="/en/XMLSerializer" title="XMLSerializer"><code>XMLSerializer</code></a> and <a href="/en/E4X" title="en/E4X">E4X</a>. First, create a DOM tree as described in the <a href="/en/How_to_create_a_DOM_tree" title="en/How_to_create_a_DOM_tree">How to Create a DOM tree</a> article. Alternatively, use a DOM tree obtained from {{ domxref("XMLHttpRequest") }}. The <code>doc</code> variable contains the DOM tree.</p> + +<pre class="brush: js">var oSerializer = new XMLSerializer(); +var sPrettyXML = XML(oSerializer.serializeToString(doc)).toXMLString();</pre> + +<p>Indents consist of two spaces. To write a more efficient version or customize the indent string, use {{ domxref("treeWalker") }}.</p> + +<div class="note"><strong>Note:</strong> When using the E4X <code>toXMLString</code> method, your <strong>CDATA elements will be lost</strong>, and only the containing text will remain. So if you have CDATA elements in your XML, <span style="background-color: #f5f6f5;">using the preceding method might not be useful</span>.</div> + +<pre class="brush: xml"><content><![CDATA[This is the content]]></content> +</pre> + +<p>Becomes</p> + +<pre class="brush: xml"><content>This is the content</content></pre> + +<h3 id="Serializing_DOM_trees_to_Javascript_Object_trees_(JXON)">Serializing DOM trees to Javascript Object trees (JXON)</h3> + +<p><a href="/en/JXON" title="en/JXON">JXON</a> (lossless <strong>J</strong>avaScript <strong>X</strong>ML <strong>O</strong>bject <strong>N</strong>otation) is a way to represent JavaScript Objects using XML. To address only parts of an XML document, use <a class="internal" href="/en/XPath" title="en/XPath">XPath</a> instead of converting the whole document into JSON! Otherwise, read the <a class="internal" href="/en/JXON" title="en/JXON">article about JXON</a>.</p> + +<h3 id="Serializing_DOM_trees_to_files">Serializing DOM trees to files</h3> + +<p>First, create a DOM tree as described in the <a href="/en/How_to_create_a_DOM_tree" title="en/How_to_create_a_DOM_tree">How to Create a DOM tree</a> article. If you already have a DOM tree from using {{ domxref("XMLHttpRequest") }}, skip to the end of this section.</p> + +<p>Now, let's serialize <code>doc</code>, the DOM tree, to a file. For more information about files, see <a href="/en/Code_snippets/File_I//O" title="en/Code_snippets/File_I//O">about using files in Mozilla</a>):</p> + +<pre class="brush: js">var oFOStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); +var oFile = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsILocalFile); // get profile folder +oFile.append("extensions"); // extensions sub-directory +oFile.append("{5872365E-67D1-4AFD-9480-FD293BEBD20D}"); // GUID of your extension +oFile.append("myXMLFile.xml"); // filename +oFOStream.init(oFile, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate +(new XMLSerializer()).serializeToStream(doc, oFOStream, ""); // rememeber, doc is the DOM tree +oFOStream.close(); +</pre> + +<h3 id="Serializing_XMLHttpRequest_objects_to_files">Serializing XMLHttpRequest objects to files</h3> + +<p>If you already have a DOM tree from using {{ domxref("XMLHttpRequest") }}, use the same code as above but replace <code>serializer.serializeToStream(doc, oFOStream, "")</code> with <code>serializer.serializeToStream(xmlHttpRequest.responseXML.documentElement, oFOStream, "")</code> where <code>xmlHttpRequest</code> is an instance of <code>XMLHttpRequest</code>.</p> + +<p>Note that this first parses the XML retrieved from the server, and then re-serializes it into a stream. Depending on your needs, you could just save the <code>xmlHttpRequest.responseText</code> directly.</p> + +<h3 id="Serializing_HTML_documents">Serializing HTML documents</h3> + +<p>If the DOM you have is an HTML document, you can serialize it simply using</p> + +<pre class="brush: js">var serialized = document.documentElement.innerHTML; +</pre> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a class="internal" href="/en/XPath" title="en/XPath">XPath</a></li> + <li><a href="/en/nsIXMLHttpRequest" title="en/XMLHttpRequest">XMLHttpRequest</a></li> + <li><a href="/en/JXON" title="en/JXON">JXO</a></li> +</ul> diff --git a/files/es/web/guide/performance/index.html b/files/es/web/guide/performance/index.html new file mode 100644 index 0000000000..dca2ce95b5 --- /dev/null +++ b/files/es/web/guide/performance/index.html @@ -0,0 +1,12 @@ +--- +title: Optimización y rendimiento +slug: Web/Guide/Performance +tags: + - Optimizacion + - Rendimiento + - Web +translation_of: Web/Guide/Performance +--- +<p>Cuando se construyen aplicaciones o sitios Web modernos, es importante hacer que su contenido funcione bien. Es decir, hacer que trabaje de forma rápida y eficiente. Esto permite que funcione eficazmente tanto para usuarios de potentes sistemas de escritorio así como para dispositivos móviles con menos potencia.</p> + +<p>{{LandingPageListSubpages}}</p> diff --git a/files/es/web/guide/performance/usando_web_workers/index.html b/files/es/web/guide/performance/usando_web_workers/index.html new file mode 100644 index 0000000000..db4dbc07e3 --- /dev/null +++ b/files/es/web/guide/performance/usando_web_workers/index.html @@ -0,0 +1,633 @@ +--- +title: Usando Web Workers +slug: Web/Guide/Performance/Usando_web_workers +translation_of: Web/API/Web_Workers_API/Using_web_workers +--- +<p><span class="seoSummary">Los Web Workers dedicados proveen un medio sencillo para que el contenido web ejecute scripts en hilos en segundo plano. Una vez creado, un worker puede enviar mensajes a la tarea creada mediante envio de mensajes al manejador de eventos especificado por el creador.</span> Sin embargo, <strong>los workers trabajan dentro de un <a href="https://developer.mozilla.org/en-US/docs/JavaScript/DedicatedWorkerGlobalScope">contexto global</a> diferente de la ventana actual</strong> (usar el atajo <span style="line-height: 1.5;"> {{ domxref("window") }} en lugar de </span><span style="line-height: 1.5;">{{ domxref("window.self","self") }} con el fin de obtener el scope actual dentro de un </span><span style="line-height: 1.5;">{{ domxref("Worker") }} retornaría, de hecho, un error).</span></p> + +<p>El hilo worker puede realizar tareas sin interferir con la interfaz de usuario. Ademas, pueden realizar I/O usando <code style="font-size: 14px;"><a class="internal" href="/en/nsIXMLHttpRequest" title="En/XMLHttpRequest">XMLHttpRequest</a></code><span style="line-height: 1.5;"> (aunque el responseXML y los atributos channel son siempre null).</span></p> + +<p><span style="line-height: 1.5;">Para documentacion de referencia acerca de workers busca </span><span style="line-height: 1.5;">{{ domxref("Worker") }} ; este articulo complementa ese ofreciendo ejemplos y detalles adicionales. Para una lista de las funciones disponibles sobre workers, visita </span><span style="line-height: 1.5;"> </span><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/Needs_categorization/Functions_available_to_workers?redirect=no" style="line-height: 1.5;" title="En/DOM/Worker/Functions available to workers">Functions and interfaces available to workers</a><span style="line-height: 1.5;">.</span></p> + +<h2 id="Acerca_de_seguridad_de_hilos" style="line-height: 22.79199981689453px;">Acerca de seguridad de hilos</h2> + +<p>La interfaz <span style="line-height: 1.5;"> {{ domxref("Worker") }} crea hilos a nivel de SO reales, y la concurrencia puede causar effectos interesantes en tu código si no eres cuidadoso. Sin embargo, en el caso de los web workers, el control cuidadoso de los puntos de comunicacion con otros hilos indica que es realmente muy dificil causar problemas de concurrencia. No existe acceso a componentes no-hilo seguros o al DOM y debes pasar la informacion entrante o saliente del hilo a traves de objetos serializados. Así que debes poner esfuerzo para causar problemas en tu código.</span></p> + +<p><strong style="">Creando un web worker</strong></p> + +<p>Crear un nuevo worker es simple. Sólo tienes que llamar el constructor {{ domxref("Worker.Worker", "Worker()") }}, especificando la URI de un script a ejecutar en el hilo del worker (<em>worker thread</em>), y, si deseas poder recibir notificaciones del worker, establece la propiedad {{domxref("Worker.onmessage")}} del worker a una función de manejo de eventos apropiada.</p> + +<div style="overflow: hidden;"> +<pre class="brush: js notranslate">var myWorker = new Worker("my_task.js"); + +myWorker.onmessage = function (oEvent) { + console.log("Called back by the worker!\n"); +};</pre> +</div> + +<p>Alternativamente, puedes usar <code>addEventListener()</code> :</p> + +<div style="overflow: hidden;"> +<pre class="brush: js notranslate">var myWorker = new Worker("my_task.js"); + +myWorker.addEventListener("message", function (oEvent) { + console.log("Called back by the worker!\n"); +}, false); + +myWorker.postMessage(""); // start the worker.</pre> +</div> + +<p>La Línea 1 en este ejemplo crea un nuevo worker (<em>worker thread)</em>. La Línea 3 configura un manejador de eventos (<em>listener</em>) para encargarse de los eventos <code>message</code> del worker. Este manejador de eventos se llamará cuando el worker llame a su propia función {{domxref("Worker.postMessage()")}}. Finalmente, la Linea 7 inicia el worker <em>(worker thread)</em>.</p> + +<div class="note"><strong>Nota</strong> : La URI pasada como parámetro del constructor de <code>Worker</code> debe obedecer la política <a href="/en/Same_origin_policy_for_JavaScript" title="Same origin policy for JavaScript">same-origin policy</a> . Actualmente hay desacuerdo entre los desarolladores de navegadores sobre qué URIs son del mismo origen; Gecko 10.0 {{ geckoRelease("10.0") }} y posteriores sí permiten data URIs e Internet Explorer 10 no permite Blob URIs como un script válido para los workers.</div> + +<h2 id="Pasando_datos">Pasando datos</h2> + +<p>Los datos pasan entre la página principal y los workers son <strong>copiados</strong>, no compartidos. Los objetos se serializan a medida que se entregan al worker, y posteriormente, se deserializan en el otro extremo. La página y el worker <strong>no comparten la misma instancia</strong>, por lo que el resultado final es que un duplicado es creado en cada extremo. La mayoría de los navegadores implementan esta característica como <a href="/en/DOM/The_structured_clone_algorithm" title="The structured clone algorithm">structured cloning</a>.</p> + +<p>Antes de continuar, vamos a crear con fines didácticos una función llamada <code>emulateMessage()</code> que simulará el comportamiento de un valor el cual es clonado y no compartido durante el paso desde un <em>worker </em>a la página principal o viceversa:</p> + +<pre class="brush: js notranslate">function emulateMessage (vVal) { + return eval("(" + JSON.stringify(vVal) + ")"); +} + +// Tests + +// test #1 +var example1 = new Number(3); +alert(typeof example1); // object +alert(typeof emulateMessage(example1)); // number + +// test #2 +var example2 = true; +alert(typeof example2); // boolean +alert(typeof emulateMessage(example2)); // boolean + +// test #3 +var example3 = new String("Hello World"); +alert(typeof example3); // object +alert(typeof emulateMessage(example3)); // string + +// test #4 +var example4 = { + "name": "John Smith", + "age": 43 +}; +alert(typeof example4); // object +alert(typeof emulateMessage(example4)); // object + +// test #5 +function Animal (sType, nAge) { + this.type = sType; + this.age = nAge; +} +var example5 = new Animal("Cat", 3); +alert(example5.constructor); // Animal +alert(emulateMessage(example5).constructor); // Object</pre> + +<p>A Un valor que es clonado y no compartido se denomina <em>mensaje</em>. De vuelta con los workers, los <em>mensajes</em> pueden ser enviados hacia y desde el hilo principal empleando <code>postMessage()</code>. Los eventos de <code>mensaje</code> {{domxref("MessageEvent.data", "data")}} atributo contienen datos devueltos desde el worker.</p> + +<p><strong>example.html</strong>: (la página principal):</p> + +<pre class="brush: js notranslate">var myWorker = new Worker("my_task.js"); + +myWorker.onmessage = function (oEvent) { + console.log("Worker said : " + oEvent.data); +}; + +myWorker.postMessage("ali");</pre> + +<p><strong>my_task.js</strong> (el worker):</p> + +<pre class="brush: js notranslate">postMessage("I\'m working before postMessage(\'ali\')."); + +onmessage = function (oEvent) { + postMessage("Hi " + oEvent.data); +};</pre> + +<div class="note"><strong>Note:</strong> Como siempre, los hilos en segundo plano -incluyendo workers- <strong>no pueden manipular el DOM</strong>. Si acciones tomadas por el hilo en segundo planos resultarían en cambios en el DOM, deberian enviar mensajes a sus creadores para llevarlos a cabo.</div> + +<p>The <a href="/en-US/docs/Web/Guide/DOM/The_structured_clone_algorithm" style="line-height: 1.572;" title="The structured clone algorithm">structured cloning</a> algorithm can accept JSON and a few things that JSON can't like circular references.</p> + +<h3 id="Ejemplos_pasando_datos">Ejemplos pasando datos</h3> + +<h4 id="Example_1_Crear_un_eval_asíncrono_genérico">Example #1: Crear un "<code>eval() asíncrono</code>" genérico</h4> + +<p>El siguiente ejemplo muestra como usar un worker para ejecutar <strong>asíncronamente</strong> cualquier tipo de código en Javascript a traves de <a href="/en-US/docs/JavaScript/Reference/Global_Objects/eval" title="/en-US/docs/JavaScript/Reference/Global_Objects/eval"><code>eval</code></a> dentro del worker:</p> + +<pre class="brush: js notranslate">// Syntax: asyncEval(code[, listener]) + +var asyncEval = (function () { + + var aListeners = [], oParser = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D"); + + oParser.onmessage = function (oEvent) { + if (aListeners[oEvent.data.id]) { aListeners[oEvent.data.id](oEvent.data.evaluated); } + delete aListeners[oEvent.data.id]; + }; + + + return function (sCode, fListener) { + aListeners.push(fListener || null); + oParser.postMessage({ + "id": aListeners.length - 1, + "code": sCode + }); + }; + +})();</pre> + +<p>Ejemplo de uso:</p> + +<pre class="brush: js notranslate">// asynchronous alert message... +asyncEval("3 + 2", function (sMessage) { + alert("3 + 2 = " + sMessage); +}); + +// asynchronous print message... +asyncEval("\"Hello World!!!\"", function (sHTML) { + document.body.appendChild(document.createTextNode(sHTML)); +}); + +// asynchronous void... +asyncEval("(function () {\n\tvar oReq = new XMLHttpRequest();\n\toReq.open(\"get\", \"http://www.mozilla.org/\", false);\n\toReq.send(null);\n\treturn oReq.responseText;\n})()");</pre> + +<h4 id="Ejemplo_2_Paso_avanzado_de_JSON_Data_y_creación_de_un_sistema_de_conmutación">Ejemplo #2: Paso avanzado de JSON Data y creación de un sistema de conmutación</h4> + +<p>Si tiene que pasar datos complejos y tienes que llamar a muchas funciones diferentes tanto en la página principal como en el Worker, puede crear un sistema como el siguiente.</p> + +<p><strong>example.html</strong> (the main page):</p> + +<pre class="brush: html notranslate"><!doctype html> +<html> +<head> +<meta charset="UTF-8" /> +<title>MDN Example - Queryable worker</title> +<script type="text/javascript"> + /* + QueryableWorker instances methods: + * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function + * postMessage(string or JSON Data): see Worker.prototype.postMessage() + * terminate(): terminates the Worker + * addListener(name, function): adds a listener + * removeListener(name): removes a listener + QueryableWorker instances properties: + * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly + */ + function QueryableWorker (sURL, fDefListener, fOnError) { + var oInstance = this, oWorker = new Worker(sURL), oListeners = {}; + this.defaultListener = fDefListener || function () {}; + oWorker.onmessage = function (oEvent) { + if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty("vo42t30") && oEvent.data.hasOwnProperty("rnb93qh")) { + oListeners[oEvent.data.vo42t30].apply(oInstance, oEvent.data.rnb93qh); + } else { + this.defaultListener.call(oInstance, oEvent.data); + } + }; + if (fOnError) { oWorker.onerror = fOnError; } + this.sendQuery = function (/* queryable function name, argument to pass 1, argument to pass 2, etc. etc */) { + if (arguments.length < 1) { throw new TypeError("QueryableWorker.sendQuery - not enough arguments"); return; } + oWorker.postMessage({ "bk4e1h0": arguments[0], "ktp3fm1": Array.prototype.slice.call(arguments, 1) }); + }; + this.postMessage = function (vMsg) { + //I just think there is no need to use call() method + //how about just oWorker.postMessage(vMsg); + //the same situation with terminate + //well,just a little faster,no search up the prototye chain + Worker.prototype.postMessage.call(oWorker, vMsg); + }; + this.terminate = function () { + Worker.prototype.terminate.call(oWorker); + }; + this.addListener = function (sName, fListener) { + oListeners[sName] = fListener; + }; + this.removeListener = function (sName) { + delete oListeners[sName]; + }; + }; + + // your custom "queryable" worker + var oMyTask = new QueryableWorker("my_task.js" /* , yourDefaultMessageListenerHere [optional], yourErrorListenerHere [optional] */); + + // your custom "listeners" + + oMyTask.addListener("printSomething", function (nResult) { + document.getElementById("firstLink").parentNode.appendChild(document.createTextNode(" The difference is " + nResult + "!")); + }); + + oMyTask.addListener("alertSomething", function (nDeltaT, sUnit) { + alert("Worker waited for " + nDeltaT + " " + sUnit + " :-)"); + }); +</script> +</head> +<body> + <ul> + <li><a id="firstLink" href="javascript:oMyTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li> + <li><a href="javascript:oMyTask.sendQuery('waitSomething');">Wait 3 seconds</a></li> + <li><a href="javascript:oMyTask.terminate();">terminate() the Worker</a></li> + </ul> +</body> +</html></pre> + +<p><strong>my_task.js</strong> (el worker):</p> + +<pre class="brush: js notranslate">// your custom PRIVATE functions + +function myPrivateFunc1 () { + // do something +} + +function myPrivateFunc2 () { + // do something +} + +// etc. etc. + +// your custom PUBLIC functions (i.e. queryable from the main page) + +var queryableFunctions = { + // example #1: get the difference between two numbers: + getDifference: function (nMinuend, nSubtrahend) { + reply("printSomething", nMinuend - nSubtrahend); + }, + // example #2: wait three seconds + waitSomething: function () { + setTimeout(function() { reply("alertSomething", 3, "seconds"); }, 3000); + } +}; + +// system functions + +function defaultQuery (vMsg) { + // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly + // do something +} + +function reply (/* listener name, argument to pass 1, argument to pass 2, etc. etc */) { + if (arguments.length < 1) { throw new TypeError("reply - not enough arguments"); return; } + postMessage({ "vo42t30": arguments[0], "rnb93qh": Array.prototype.slice.call(arguments, 1) }); +} + +onmessage = function (oEvent) { + if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty("bk4e1h0") && oEvent.data.hasOwnProperty("ktp3fm1")) { + queryableFunctions[oEvent.data.bk4e1h0].apply(self, oEvent.data.ktp3fm1); + } else { + defaultQuery(oEvent.data); + } +};</pre> + +<p>Es un método posible para conmutar el contenido de cada mensaje de cada mainpage-worker y viceversa.</p> + +<h3 id="Pasando_datos_mediante_transferencia_de_propiedades_objetos_transferibles">Pasando datos mediante transferencia de propiedades (objetos transferibles)</h3> + +<p>Google Chrome 17 y Firefox 18 implementan un método adicional para enviar ciertos tipos de objetos desde o hacia el worker con un mejor rendimiento. Estos objetos se denominan objetos transferibles (transferable objects), es decir, o<span class="external">bjetos que implementan la interfaz {{domxref("Transferable")}}</span>. Los objetos transferibles se transfieren de un contexto a otro con una operación "zero-copy". Esto supone una gran mejora de rendimiento al enviar grandes cantidades de datos. Piensa en ello como un paso por referencia si vienes del mundo de C/C++. Sin embargo, a diferecia del paso por referencia, la "versión" original no queda disponible una vez transferida. Su contenido es transferido al nuevo contexto. Por ejemplo, cuando se transfiere un {{domxref("ArrayBuffer")}} de tu aplicacion al Worker, el contenido del {{domxref("ArrayBuffer")}} original se vacía y no se puede utilizar posteriormente. Su contenido es (literalmente) transferido al contexto del Worker.</p> + +<pre class="brush: js notranslate">// Create a 32MB "file" and fill it. +var uInt8Array = new Uint8Array(1024*1024*32); // 32MB +for (var i = 0; i < uInt8Array.length; ++i) { + uInt8Array[i] = i; +} + +worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]); +</pre> + +<p>Para más información sobre los objetos transferibles, <a class="external" href="http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast" title="http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast">visita HTML5Rocks</a> .</p> + +<h2 id="Spawning_subworkers">Spawning subworkers</h2> + +<p>Workers may spawn more workers if they wish. So-called subworkers must be hosted within the same origin as the parent page. Also, the URIs for subworkers are resolved relative to the parent worker's location rather than that of the owning page. This makes it easier for workers to keep track of where their dependencies are.</p> + +<p>Subworkers are currently not supported in Chrome. See <a class="external" href="http://code.google.com/p/chromium/issues/detail?id=31666" title="http://code.google.com/p/chromium/issues/detail?id=31666">crbug.com/31666</a> .</p> + +<h2 id="Embedded_workers">Embedded workers</h2> + +<p>There is not an "official" way to embed the code of a worker within a web page as for the {{ HTMLElement("script") }} elements. But a {{ HTMLElement("script") }} element which does not have a <code>src</code> attribute and has a <code>type</code> attribute that does not identify an executable mime-type will be considered a data block element, that JavaScript could use. "Data blocks" is a more general feature of HTML5 that can carry almost any textual data. So, a worker could be embedded in this way:</p> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8" /> +<title>MDN Example - Embedded worker</title> +<script type="text/js-worker"> + // This script WON'T be parsed by JS engines because its mime-type is text/js-worker. + var myVar = "Hello World!"; + // Rest of your worker code goes here. +</script> +<script type="text/javascript"> + // This script WILL be parsed by JS engines because its mime-type is text/javascript. + function pageLog (sMsg) { + // Use a fragment: browser will only render/reflow once. + var oFragm = document.createDocumentFragment(); + oFragm.appendChild(document.createTextNode(sMsg)); + oFragm.appendChild(document.createElement("br")); + document.querySelector("#logDisplay").appendChild(oFragm); + } +</script> +<script type="text/js-worker"> + // This script WON'T be parsed by JS engines because its mime-type is text/js-worker. + onmessage = function (oEvent) { + postMessage(myVar); + }; + // Rest of your worker code goes here. +</script> +<script type="text/javascript"> + // This script WILL be parsed by JS engines because its mime-type is text/javascript. + + // In the past...: + // blob builder existed + // ...but now we use Blob...: + var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"}); + + // Creating a new document.worker property containing all our "text/js-worker" scripts. + document.worker = new Worker(window.URL.createObjectURL(blob)); + + document.worker.onmessage = function (oEvent) { + pageLog("Received: " + oEvent.data); + }; + + // Start the worker. + window.onload = function() { document.worker.postMessage(""); }; +</script> +</head> +<body><div id="logDisplay"></div></body> +</html></pre> + +<p>The embedded worker is now nested into a new custom <code>document.worker</code> property.</p> + +<h2 id="Tiempos_fuera_e_intervalos">Tiempos fuera e intervalos</h2> + +<p>Los trabajadores pueden usar tiempos fuera e intervalos de la misma forma que el "hilo principal". Esto puede ser útil, por ejemplo, si quieres tener a tu hilo trabajador corriendo codigo periodicamente en lugar de sin parar.</p> + +<p>Ver <a class="internal" href="/en/DOM/window.setTimeout" title="En/DOM/Window.setTimeout"><code>setTimeout()</code> </a> , <a class="internal" href="/en/DOM/window.clearTimeout" title="En/DOM/Window.clearTimeout"> <code>clearTimeout()</code> </a> , <a class="internal" href="/en/DOM/window.setInterval" title="En/DOM/Window.setInterval"> <code>setInterval()</code> </a> , y <a class="internal" href="/en/DOM/window.clearInterval" title="En/DOM/Window.clearInterval"><code>clearInterval()</code> </a> para más detalles. Ver también: <a href="/en-US/docs/JavaScript/Timers" title="/en-US/docs/JavaScript/Timers">JavaScript Timers</a>.</p> + +<h2 id="Terminating_a_worker">Terminating a worker</h2> + +<p>If you need to immediately terminate a running worker, you can do so by calling the worker's <code>terminate()</code> method:</p> + +<pre class="syntaxbox notranslate">myWorker.terminate();</pre> + +<p>The worker thread is killed immediately without an opportunity to complete its operations or clean up after itself.</p> + +<p>Workers may close themselves by calling their own {{ ifmethod("nsIWorkerScope", "close") }} method:</p> + +<pre class="syntaxbox notranslate">self.close();</pre> + +<h2 id="Manejo_de_errores">Manejo de errores</h2> + +<p>When a runtime error occurs in worker, its <code>onerror</code> event handler is called. It receives an event named <code>error</code> which implements the <code>ErrorEvent</code> interface. The event doesn't bubble and is cancelable; to prevent the default action from taking place, the worker can call the error event's <a class="internal" href="/en/DOM/event.preventDefault" title="En/DOM/Event.preventDefault"> <code>preventDefault()</code> </a> method.</p> + +<p>The error event has the following three fields that are of interest:</p> + +<dl> + <dt><code>message</code></dt> + <dd>A human-readable error message.</dd> + <dt><code>filename</code></dt> + <dd>The name of the script file in which the error occurred.</dd> + <dt><code>lineno</code></dt> + <dd>The line number of the script file on which the error occurred.</dd> +</dl> + +<h2 id="Accediendo_al_objeto_navigator">Accediendo al objeto navigator</h2> + +<p>Los workers pueden acceder al objeto <code>navigator</code>, el cuál está disponible dentro de su scope actual. Este contiene los siguientes strings que pueden ser usados para identificar el navegador, al igual que puede realizarse usando scripts normales:</p> + +<ul> + <li><code>appName</code></li> + <li><code>appVersion</code></li> + <li><code>platform</code></li> + <li><code>userAgent</code></li> +</ul> + +<h2 id="Importing_scripts_and_libraries">Importing scripts and libraries</h2> + +<p>Worker threads have access to a global function, <code>importScripts()</code> , which lets them import scripts or libraries into their scope. It accepts as parameters zero or more URIs to resources to import; all of the following examples are valid:</p> + +<pre class="brush: js notranslate">importScripts(); /* imports nothing */ +importScripts('foo.js'); /* imports just "foo.js" */ +importScripts('foo.js', 'bar.js'); /* imports two scripts */ +</pre> + +<p>The browser loads each listed script and executes it. Any global objects from each script may then be used by the worker. If the script can't be loaded, <code>NETWORK_ERROR</code> is thrown, and subsequent code will not be executed. Previously executed code (including code deferred using {{ domxref("window.setTimeout()") }}) will still be functional though. Function declarations <strong>after</strong> the <code>importScripts()</code> method are also kept, since these are always evaluated before the rest of the code.</p> + +<div class="note"><strong>Note:</strong> Scripts may be downloaded in any order, but will be executed in the order in which you pass the filenames into <code>importScripts()</code> . This is done synchronously; <code>importScripts()</code> does not return until all the scripts have been loaded and executed.</div> + +<h2 id="Examples">Examples</h2> + +<p>This section provides several examples of how to use DOM workers.</p> + +<h3 id="Performing_computations_in_the_background">Performing computations in the background</h3> + +<p>One way workers are useful is to allow your code to perform processor-intensive calculations without blocking the user interface thread. In this example, a worker is used to calculate Fibonacci numbers.</p> + +<h4 id="The_JavaScript_code">The JavaScript code</h4> + +<p>The following JavaScript code is stored in the "fibonacci.js" file referenced by the HTML in the next section.</p> + +<pre class="brush: js notranslate">var results = []; + +function resultReceiver(event) { + results.push(parseInt(event.data)); + if (results.length == 2) { + postMessage(results[0] + results[1]); + } +} + +function errorReceiver(event) { + throw event.data; +} + +onmessage = function(event) { + var n = parseInt(event.data); + + if (n == 0 || n == 1) { + postMessage(n); + return; + } + + for (var i = 1; i <= 2; i++) { + var worker = new Worker("fibonacci.js"); + worker.onmessage = resultReceiver; + worker.onerror = errorReceiver; + worker.postMessage(n - i); + } + };</pre> + +<p>The worker sets the property <code>onmessage</code> to a function which will receive messages sent when the worker object's <code>postMessage()</code> is called. (Note that this differs from defining a global <em>variable</em> of that name, or defining a <em>function</em> with that name. <code>var onmessage</code> and <code>function onmessage</code> will define global properties with those names, but they will not register the function to receive messages sent by the web page that created the worker.) This starts the recursion, spawning new copies of itself to handle each iteration of the calculation.</p> + +<h4 id="The_HTML_code">The HTML code</h4> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8" /> + <title>Test threads fibonacci</title> + </head> + <body> + + <div id="result"></div> + + <script language="javascript"> + + var worker = new Worker("fibonacci.js"); + + worker.onmessage = function(event) { + document.getElementById("result").textContent = event.data; + dump("Got: " + event.data + "\n"); + }; + + worker.onerror = function(error) { + dump("Worker error: " + error.message + "\n"); + throw error; + }; + + worker.postMessage("5"); + + </script> + </body> +</html> +</pre> + +<p>The web page creates a <code>div</code> element with the ID <code>result</code> , which gets used to display the result, then spawns the worker. After spawning the worker, the <code>onmessage</code> handler is configured to display the results by setting the contents of the <code>div</code> element, and the <code>onerror</code> handler is set to <a class="external" href="/en/Debugging_JavaScript#dump()" title="https://developer.mozilla.org/editor/fckeditor/core/editor/en/Debugging_JavaScript#dump()">dump</a> the error message.</p> + +<p>Finally, a message is sent to the worker to start it.</p> + +<p><a class="external" href="/samples/workers/fibonacci" title="https://developer.mozilla.org/samples/workers/fibonacci/">Try this example</a> .</p> + +<h3 id="Performing_web_IO_in_the_background">Performing web I/O in the background</h3> + +<p>You can find an example of this in the article <a class="internal" href="/En/Using_workers_in_extensions" title="En/Using workers in extensions">Using workers in extensions</a> .</p> + +<h3 id="Dividing_tasks_among_multiple_workers">Dividing tasks among multiple workers</h3> + +<p>As multi-core computers become increasingly common, it's often useful to divide computationally complex tasks among multiple workers, which may then perform those tasks on multiple-processor cores.</p> + +<p>example coming soon</p> + +<h3 id="Creating_workers_from_within_workers">Creating workers from within workers</h3> + +<p>The Fibonacci example shown previously demonstrates that workers can in fact <a href="#Spawning_subworkers">spawn additional workers</a>. This makes it easy to create recursive routines.</p> + +<h2 id="Browser_Compatibility" name="Browser_Compatibility">Browser compatibility</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Dedicated workers</td> + <td>{{CompatChrome(3)}}</td> + <td>{{CompatGeckoDesktop(1.9.1)}}</td> + <td>{{CompatIE(10)}}</td> + <td>{{CompatOpera(10.60)}}</td> + <td>{{CompatSafari(4)}}</td> + </tr> + <tr> + <td>Shared workers</td> + <td>{{CompatChrome(3)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatOpera(10.60)}}</td> + <td>{{CompatSafari(5)}}</td> + </tr> + <tr> + <td>Passing data using <a href="/en/DOM/The_structured_clone_algorithm" title="The structured clone algorithm">structured cloning</a> . </td> + <td>{{CompatChrome(13)}}</td> + <td>{{CompatGeckoDesktop(8)}}</td> + <td>{{CompatIE(10)}}</td> + <td>{{CompatOpera(11.50)}}</td> + <td>{{CompatSafari(5.1)}}</td> + </tr> + <tr> + <td>Passing data using <a class="external" href="http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#transferable-objects" title="http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects">transferable objects</a></td> + <td>17 {{ property_prefix("webkit") }}<br> + {{CompatChrome(21)}}</td> + <td>{{CompatGeckoDesktop(18)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatOpera(15)}}</td> + <td>{{CompatSafari(6)}}</td> + </tr> + <tr> + <td>Global {{ domxref("window.URL", "URL") }}</td> + <td>10 as <code>webkitURL</code><br> + {{CompatChrome(23)}}</td> + <td>{{CompatGeckoDesktop(21)}}</td> + <td>{{CompatIE(11)}}</td> + <td>{{CompatOpera(15)}}</td> + <td>6 as <code>webkitURL</code></td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Dedicated workers</td> + <td>---</td> + <td>0.16</td> + <td>3.5 (1.9.1)</td> + <td>---</td> + <td>11</td> + <td>5</td> + </tr> + <tr> + <td>Shared workers</td> + <td>---</td> + <td>{{ CompatNo() }}</td> + <td>---</td> + <td>---</td> + <td>---</td> + <td>---</td> + </tr> + <tr> + <td>Passing data using <a href="/en/DOM/The_structured_clone_algorithm" title="The structured clone algorithm">structured cloning</a> . </td> + <td>---</td> + <td>0.16</td> + <td>8</td> + <td>---</td> + <td>---</td> + <td>---</td> + </tr> + <tr> + <td>Passing data using <a class="external" href="http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#transferable-objectshtml#transferable-objects" title="http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects">transferable objects</a></td> + <td>---</td> + <td></td> + <td>18</td> + <td>---</td> + <td>---</td> + <td>---</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{ spec("http://dev.w3.org/html5/workers/", "File API Specification: Web Workers", "ED") }}</li> + <li><code><a class="internal" href="/en/DOM/Worker" title="En/DOM/Worker">Worker</a></code> interface</li> + <li><code><a class="internal" href="/en/DOM/SharedWorker" title="En/DOM/SharedWorker">SharedWorker</a></code> interface</li> + <li><a href="/en/DOM/Worker/Functions_available_to_workers" title="En/DOM/Worker/Functions available to workers">Functions available to workers</a></li> + <li><a class="external" href="http://www.html5rocks.com/en/tutorials/workers/basics/#toc-enviornment-subworkers" title="http://www.html5rocks.com/en/tutorials/workers/basics/#toc-enviornment-subworkers">HTML5Rocks - The Basics of Web Workers</a></li> + <li><a class="external" href="http://code.google.com/p/chromium/issues/detail?id=127990" title="Chrome has Problems with many workers">Chrome has problems when using too many worker</a></li> +</ul> diff --git a/files/es/web/guide/usando_objetos_formdata/index.html b/files/es/web/guide/usando_objetos_formdata/index.html new file mode 100644 index 0000000000..4537577011 --- /dev/null +++ b/files/es/web/guide/usando_objetos_formdata/index.html @@ -0,0 +1,136 @@ +--- +title: Usando Objetos FormData +slug: Web/Guide/Usando_Objetos_FormData +translation_of: Web/API/FormData/Using_FormData_Objects +--- +<p>Los objetos <code><a href="/es/docs/XMLHttpRequest/FormData" title="en/DOM/XMLHttpRequest/FormData">FormData</a> </code>le permiten compilar un conjunto de pares clave/valor para enviar mediante <code>XMLHttpRequest</code>. Están destinados principalmente para el envío de los datos del formulario, pero se pueden utilizar de forma independiente con el fin de transmitir los datos tecleados. Los datos transmitidos estarán en el mismo formato que usa el método <code>submit() </code>del formulario para enviar los datos si el tipo de codificación del formulario se establece en "multipart/form-data".</p> + +<h2 id="Creación_de_un_objeto_FormData_desde_cero">Creación de un objeto FormData desde cero</h2> + +<p>Usted mismo puede construir un objeto <code>FormData</code> instanciándolo y después añadiendo campos a la instancia usando su método <a href="/en/DOM/XMLHttpRequest/FormData#append()" title="en/XMLHttpRequest/FormData#append()"><code>append()</code></a> , tal y como se muestra:</p> + +<pre class="brush: js">var formData = new FormData(); + +<span style="line-height: normal;">formData</span>.append("username", "Groucho"); +<span style="line-height: normal;">formData</span>.append("accountnum", 123456); // number 123456 is immediately converted to string "123456" + +// HTML file input user's choice... +<span style="line-height: normal;">formData</span>.append("userfile", fileInputElement.files[0]); + +// JavaScript file-like object... +var content = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file... +var blob = new Blob([<span style="line-height: normal;">content</span><span style="line-height: normal;">], { type: "text/xml"});</span> + +formData.append("webmasterfile", <span style="line-height: normal;">blob</span><span style="line-height: normal;">);</span> + +var request = new XMLHttpRequest(); +<span style="line-height: normal;">request</span>.open("POST", "http://foo.com/submitform.php"); +<span style="line-height: normal;">request</span>.send(formData); +</pre> + +<div class="note"><strong>Nota:</strong> Los campos "userfile" y "webmasterfile" contienen ambos un archivo. El número asignado al campo "accountnum" es inmediatamente convertido a string por el método <a href="/en/DOM/XMLHttpRequest/FormData#append()" title="en/XMLHttpRequest/FormData#append()"><code>FormData.append()</code></a> (el valor del campo puede ser un {{ domxref("Blob") }}, {{ domxref("File") }}, o una cadena de texto; <strong>si el valor no es ni un Blob, ni un File, será convertido a un string</strong>).</div> + +<p>Este ejemplo construye una instancia de <code>FormData</code> que almacenará los valores de los campos "username", "accountnum", "userfile" y "webmasterfile", entonces usará el método <a href="/en/DOM/XMLHttpRequest#send()" title="en/XMLHttpRequest#send()"><code>send()</code></a> de <code>XMLHttpRequest</code> para enviar los datos del formulario. El campo "webmasterfile" es un <a href="/en/DOM/Blob" title="en/DOM/Blob"><code>Blob</code></a>. Un objeto <a href="/en/DOM/Blob" title="en/DOM/Blob"><code>Blob</code></a> representa un objeto de tipo similar a un fichero que es inalterable y que almacenará datos en formato raw. Los Blobs representan datos que no necesariamente tendrán un formato Javascript nativo. La interfaz {{ domxref("File") }} está basada en <a href="/en/DOM/Blob" title="en/DOM/Blob"><code>Blob</code></a>, y hereda su funcionalidad y la amplía para dar soporte a archivos que estén en el sistema del usuario. Para construir un <code><a href="/en/DOM/Blob" title="en/DOM/Blob">Blob</a></code>, puede invocar <a href="/en/DOM/Blob#Constructor" title="en/DOM/Blob#Constructor"><code>al constructor del objeto Blob</code></a>.</p> + +<h2 id="Recuperando_un_objeto_FormData_de_un_formulario_HTML">Recuperando un objeto FormData de un formulario HTML </h2> + +<p>Para construir un objeto <code>FormData</code> que contenga los datos de un {{ HTMLElement("form") }} existente, especifique ese elemento form cuando cree el objeto <code>FormData</code>:</p> + +<pre class="brush: js">var <span style="line-height: normal;">formData</span><span style="line-height: normal;"> = new FormData(someFormElement);</span> +</pre> + +<p>Por ejemplo:</p> + +<pre class="brush: js">var formElement = document.getElementById("myFormElement"); +var request = new XMLHttpRequest(); +<span style="line-height: normal;">request</span>.open("POST", "submitform.php"); +<span style="line-height: normal;">request</span>.send(new FormData(formElement)); +</pre> + +<p>También puede añadir datos adicionales al objeto <code>FormData</code> antes de enviarlo. Así:</p> + +<pre class="brush: js">var formElement = document.getElementById("myFormElement"); +formData = new FormData(formElement); +formData.append("serialnumber", serialNumber++); +<span style="line-height: normal;">request</span>.send(formData);</pre> + +<p>Esto le permite aumentar los datos del formulario antes de enviarlos para incluir información adicional que no necesariamente debiera ser editable por el usuario en el formulario.</p> + +<h2 id="Enviando_archivos_usando_objetos_FormData">Enviando archivos usando objetos FormData</h2> + +<p>También puede enviar archivos usando <code>FormData</code>. Simplemente incluye un elemento {{ HTMLElement("input") }} de tipo {{ domxref("File") }}:</p> + +<pre class="brush: html"><form enctype="multipart/form-data" method="post" name="fileinfo"> + <label>Your email address:</label> + <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br /> + <label>Custom file label:</label> + <input type="text" name="filelabel" size="12" maxlength="32" /><br /> + <label>File to stash:</label> + <input type="file" name="file" required /> + <input type="submit" value="Stash the file!" /> +</form> +<div id="output"></div> +</pre> + +<p>Luego puede enviarlo usando código como el siguiente:</p> + +<pre class="brush: js">var form = document.forms.namedItem("fileinfo"); +form.addEventListener('submit', function(ev) { + + var + oOutput = document.getElementById("output"), + oData = new FormData(document.forms.namedItem("fileinfo")); + + oData.append("CustomField", "This is some extra data"); + + var oReq = new XMLHttpRequest(); + oReq.open("POST", "stash.php", true); + oReq.onload = function(oEvent) { + if (oReq.status == 200) { + oOutput.innerHTML = "Uploaded!"; + } else { + oOutput.innerHTML = "Error " + oReq.status + " occurred uploading your file.<br \/>"; + } + }; + + oReq.send(oData); + ev.preventDefault(); +}, false); +</pre> + +<div class="note"> +<p><strong>Nota</strong>: el método especificado en el formulario será usado por encima del método utilizado en en la llamada a open().</p> +</div> + +<p>También puede añadir un {{ domxref("File") }} o un {{ domxref("Blob") }} directamente al objeto {{ domxref("XMLHttpRequest/FormData", "FormData") }} de la siguiente manera:</p> + +<pre class="brush: js">data.append("myfile", myBlob, "filename.txt"); +</pre> + +<p>Cuando se usa el método <code>append</code> es posible usar, de manera opcional, un tercer parámetro para pasarle un nombre de fichero dentro de la cabecera <code>Content-Disposition </code>que será enviada al servidor. Cuando no se especifica (o el parámetro no es soportado), el nombre "blob" es el que será utilizado.</p> + +<p>Además, puede usar FormData con jQuery si asigna las opciones correctas:</p> + +<pre class="brush: js">var fd = new FormData(document.getElementById("fileinfo")); +fd.append("CustomField", "This is some extra data"); +$.ajax({ + url: "stash.php", + type: "POST", + data: fd, + processData: false, // tell jQuery not to process the data + contentType: false // tell jQuery not to set contentType +}); +</pre> + +<h2 id="Envío_de_formularios_y_carga_de_archivos_vía_AJAX_sin_objetos_FormData">Envío de formularios y carga de archivos vía AJAX <em>sin</em> objetos <code style="font-size: 30px; font-weight: 700;">FormData</code></h2> + +<p>Si quiere saber cómo serializar y enviar vía <a href="/en-US/docs/AJAX" title="/en-US/docs/AJAX">AJAX</a> un formulario <em>sin </em>utilizar objetos FormData, por favor leer <a href="/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Submitting_forms_and_uploading_files" title="/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Submitting_forms_and_uploading_files">este párrafo</a> .</p> + +<h2 id="Vea_también">Vea también</h2> + +<ul> + <li><a href="/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest" title="/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest">Usando XMLHttpRequest</a></li> + <li><a href="/en-US/docs/DOM/HTMLFormElement" title="/en-US/docs/DOM/HTMLFormElement"><code>HTMLFormElement</code></a></li> + <li><a href="/en-US/docs/DOM/Blob" title="/en-US/docs/DOM/Blob"><code>Blob</code></a></li> + <li><a href="/en-US/docs/JavaScript/Typed_arrays" title="/en-US/docs/JavaScript/Typed_arrays">Typed Arrays</a></li> +</ul> |