From 1109132f09d75da9a28b649c7677bb6ce07c40c0 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:41:45 -0500 Subject: initial commit --- files/es/web/guide/ajax/comunidad/index.html | 44 ++ files/es/web/guide/ajax/index.html | 90 +++ files/es/web/guide/ajax/primeros_pasos/index.html | 231 +++++++ files/es/web/guide/api/camera/index.html | 244 +++++++ .../index.html | 48 ++ files/es/web/guide/api/index.html | 24 + files/es/web/guide/api/vibration/index.html | 155 +++++ .../guide/css/block_formatting_context/index.html | 45 ++ .../guide/css/probando_media_queries/index.html | 93 +++ .../index.html" | 144 ++++ .../dom/events/eventos_controlador/index.html | 132 ++++ files/es/web/guide/dom/events/index.html | 16 + files/es/web/guide/dom/index.html | 21 + files/es/web/guide/graphics/index.html | 53 ++ .../canvas_tutorial/advanced_animations/index.html | 380 +++++++++++ .../applying_styles_and_colors/index.html | 726 +++++++++++++++++++++ .../canvas_tutorial/basic_animations/index.html | 333 ++++++++++ .../html/canvas_tutorial/basic_usage/index.html | 146 +++++ .../canvas_tutorial/dibujando_formas/index.html | 513 +++++++++++++++ .../hit_regions_and_accessibility/index.html | 99 +++ files/es/web/guide/html/canvas_tutorial/index.html | 61 ++ .../canvas_tutorial/optimizing_canvas/index.html | 19 + .../pixel_manipulation_with_canvas/index.html | 301 +++++++++ .../guide/html/categorias_de_contenido/index.html | 175 +++++ .../es/web/guide/html/editable_content/index.html | 226 +++++++ .../html/introduction_alhtml_clone/index.html | 172 +++++ files/es/web/guide/index.html | 72 ++ files/es/web/guide/movil/index.html | 75 +++ .../guide/parsing_and_serializing_xml/index.html | 133 ++++ files/es/web/guide/performance/index.html | 12 + .../performance/usando_web_workers/index.html | 633 ++++++++++++++++++ .../web/guide/usando_objetos_formdata/index.html | 136 ++++ 32 files changed, 5552 insertions(+) create mode 100644 files/es/web/guide/ajax/comunidad/index.html create mode 100644 files/es/web/guide/ajax/index.html create mode 100644 files/es/web/guide/ajax/primeros_pasos/index.html create mode 100644 files/es/web/guide/api/camera/index.html create mode 100644 files/es/web/guide/api/dom/events/orientation_and_motion_data_explained/orientation_and_motion_data_explained/index.html create mode 100644 files/es/web/guide/api/index.html create mode 100644 files/es/web/guide/api/vibration/index.html create mode 100644 files/es/web/guide/css/block_formatting_context/index.html create mode 100644 files/es/web/guide/css/probando_media_queries/index.html create mode 100644 "files/es/web/guide/dom/events/creacion_y_activaci\303\263n_eventos/index.html" create mode 100644 files/es/web/guide/dom/events/eventos_controlador/index.html create mode 100644 files/es/web/guide/dom/events/index.html create mode 100644 files/es/web/guide/dom/index.html create mode 100644 files/es/web/guide/graphics/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/advanced_animations/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/applying_styles_and_colors/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/basic_animations/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/basic_usage/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/dibujando_formas/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/hit_regions_and_accessibility/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/optimizing_canvas/index.html create mode 100644 files/es/web/guide/html/canvas_tutorial/pixel_manipulation_with_canvas/index.html create mode 100644 files/es/web/guide/html/categorias_de_contenido/index.html create mode 100644 files/es/web/guide/html/editable_content/index.html create mode 100644 files/es/web/guide/html/introduction_alhtml_clone/index.html create mode 100644 files/es/web/guide/index.html create mode 100644 files/es/web/guide/movil/index.html create mode 100644 files/es/web/guide/parsing_and_serializing_xml/index.html create mode 100644 files/es/web/guide/performance/index.html create mode 100644 files/es/web/guide/performance/usando_web_workers/index.html create mode 100644 files/es/web/guide/usando_objetos_formdata/index.html (limited to 'files/es/web/guide') 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 +--- +

 

+


+ 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.

+

Mozilla

+ +

{{ DiscussionList("dev-ajax", "mozilla.dev.ajax") }}

+

Listas de correo

+ +

 

+

Foros

+ +

Bitácoras

+ +

 

+

Wikis

+ +

 

+

Otros Sitios

+ +

 

+

categorías

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 +--- +

 

+ +
Primeros Pasos
+Una introducción a AJAX.
+ +

JavaScript Asíncrono + XML (AJAX) 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: HTML o XHTML, CSS, JavaScript, DOM, XML, XSLT, y lo más importante, el objeto XMLHttpRequest. 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.

+ + + + + + + + +
+

Documentación

+ +
+
Primeros pasos con AJAX
+
Este artículo te guiará por los conceptos básicos de AJAX y te proporcionará dos ejemplos prácticos para que empieces.
+
+ +
+
Técnicas Ajax Alternativas
+
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.
+
+ +
+
Ajax con PHP, JSON y CSS
+
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.
+
+ +
+
Ajax Upload File
+
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.
+
+ +
+
Creando formulario editables in situ
+
Breve tutorial que nos muestra como crear nuestros formularios editables in situ con AJAX, PHP y MySQL, al estilo Flickr.
+
+ +
+
Arquitectura Cliente Servidor con AJAX
+
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.
+
+ +

Ver todos

+
+

Comunidad

+ + + +
    +
  • Foros sobre AJAX en la comunidad Mozilla en inglés:
  • +
+ +

{{ DiscussionList("dev-ajax", "mozilla.dev.ajax") }}

+ +

Ver todos

+ +

Herramientas

+ + + +

Ver todos

+ +

Temas relacionados

+ +
+
HTML · XHTML · CSS · DOM · JavaScript · XML · XMLHttpRequest · XSLT · DHTML
+
+
+ +
 
+ +

{{ 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" } ) }}

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 +--- +

 

+ +

Este artículo es una guía básica sobre AJAX e incluye dos ejemplos.

+ +

¿Qué es AJAX?

+ +

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.

+ +

Las dos capacidades en cuestión son:

+ + + +

Primer Paso – Cómo realizar una petición HTTP al servidor

+ +

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 XMLHTTP. Después Mozilla, Safari y otros navegadores lo siguieron, implementando una clase XMLHttpRequest que soportaba los métodos y las propiedades del objeto ActiveX original.

+ +

Como resultado, para crear una instancia de la clase requerida que funcione en todos los navegadores, es necesario poner:

+ +
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
+    http_request = new XMLHttpRequest();
+} else if (window.ActiveXObject) { // IE
+    http_request = new ActiveXObject("Microsoft.XMLHTTP");
+}
+
+ +

(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.)

+ +

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 text/xml.

+ +
http_request = new XMLHttpRequest();
+http_request.overrideMimeType('text/xml');
+
+ +

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 onreadystatechange del objeto al nombre de la función de JavaScript que se va a utilizar:

+ +

http_request.onreadystatechange = nameOfTheFunction;

+ +

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:

+ +
http_request.onreadystatechange = function(){
+    // procesar la respuesta
+};
+
+ +

Después de especificar qué pasará al recibir la respuesta es necesario hacer la petición. Para esto se utilizan los métodos open() y send() de la clase HTTP request, como se muestra a continuación:

+ +
http_request.open('GET', 'http://www.example.org/algun.archivo', true);
+http_request.send();
+
+ + + +

El parámetro en el método send()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:

+ +

name=value&anothername=othervalue&so=on

+ +

Si se quiere enviar información de esta forma, es necesario cambiar el tipo MIME de la petición usando la siguiente línea:

+ +
http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+ +

De otro modo el servidor descartará la información.

+ +

Segundo Paso – Procesando la respuesta del servidor

+ +

Al enviar la petición HTTP es necesario indicar el nombre de la función JavaScript que procesará la respuesta.

+ +

http_request.onreadystatechange = nameOfTheFunction;

+ +

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.

+ +
if (http_request.readyState == 4) {
+    // todo va bien, respuesta recibida
+} else {
+    // aun no esta listo
+}
+
+ +

La lista completa de valores para la propiedad readyState es:

+ + + +

(Source)

+ +

Ahora es necesario revisar el código de status de la respuesta HTTP. La lista completa de códigos aparece en el sitio de la W3C. Para el próposito de este artículo sólo es importante el código 200 OK.

+ +
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)
+}
+
+ +

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:

+ + + +

Tercer Paso – "¡Ahora todo junto!" - Un sencillo ejemplo

+ +

En este ejemplo se utilizará todo lo que se ha visto para hacer una petición HTTP. Se pedirá un documento HTML llamado test.html, que contiene el texto "Esto es una prueba." y después usaremos la función alert() con el contenido del archivo test.html .

+ +
<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>
+
+ +

En este ejemplo:

+ + + +

Puedes probar el ejemplo aquí y puedes ver el archivo de prueba aquí.

+ +

Nota: La línea http_request.overrideMimeType('text/xml'); arriba causaría problemas en la consola de Javascript de Firefox 1.5b, como esta descrito en https://bugzilla.mozilla.org/show_bug.cgi?id=311724, si la página llamada por XMLHttpRequest no es XML válido (por ejemplo, si es texto).

+ +

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.

+ +

Cuarto Paso – Trabajando con la respuesta XML

+ +

En el ejemplo anterior se utilizo la propiedad reponseText del objeto pedido para mostrar el contenido de test.html una vez que la respuesta HTTP había sido recibida. En éste se utilizará la propiedad responseXML.

+ +

Primero hay que crear un documento de XML válido. El documento (test.xml) contiene lo siguiente:

+ +
<?xml version="1.0" ?>
+<root>
+    Esto es una prueba.
+</root>
+
+ +

Para que funcione el script solo es necesario cambiar la línea de petición por:

+ +
...
+onclick="makeRequest('test.xml')">
+...
+
+ +

Y en alertContents() es necerario remplazar la línea donde aparece alert(http_request.responseText); por:

+ +
var xmldoc = http_request.responseXML;
+var root_node = xmldoc.getElementsByTagName('root').item(0);
+alert(root_node.firstChild.data);
+
+ +

De esta manera se utiliza el objeto XMLDocument dado por responseXML y se usan métodos del DOM para acceder a la información contenida en el documento XML. El archivo test.xml se encuentra aquí y el script actualizado está aquí.

+ +

Para más información sobre los metodos del DOM, visita los documentos de la implementación del DOM de Mozilla.

+ +
 
+ +

{{ 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" } ) }}

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 +--- +

Mediante la API de Cámara, es posible tomar fotografías con la cámara de su dispositivo y subirlas a una página web. Esto se logra a través de un elemento input con los atributos type="file" y accept para declarar que el elemento acepta imágenes. El HTML se parece a esto:

+ +
<input type="file" id="take-picture" accept="image/*">
+
+ +

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 <input type="file"> y se lanza su evento onchange.

+ +

Obtener una referencia a la fotografía tomada

+ +

Con la ayuda de la API de Fichero usted puede acceder a la fotografía tomada o el fichero elegido:

+ +
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];
+    }
+};
+
+ +

Presentando la fotografía en la página web

+ +

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 src de una imagen:

+ +
// 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);
+
+ +

Si createObjectURL() no es soportado, una alternativa es retroceder a {{ domxref("FileReader") }}:

+ +
// Retroceder a FileReader si createObjectURL no está soportado
+var fileReader = new FileReader();
+fileReader.onload = function (event) {
+    showPicture.src = event.target.result;
+};
+fileReader.readAsDataURL(file);
+
+ +

Ejemplo completo

+ +

Si desea verlo en acción, eche un vistazo al ejemplo completo de la API de Cámara funcionando.

+ +

Aquí está el código usado para esa demostración:

+ +

Página 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>
+
+ +

Fichero JavaScript

+ +
(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";
+                        }
+                    }
+                }
+            }
+        };
+    }
+})();
+
+ +

Compatibilidad con navegadores

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Camera API{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
createObjectURL()16{{CompatGeckoDesktop("8.0")}}10+{{CompatNo()}}{{CompatNo()}}
{{domxref("FileReader")}}16{{CompatGeckoDesktop("1.9.2")}}10+11.6+{{CompatNo()}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Camera API3.0{{ CompatVersionUnknown() }}{{ CompatGeckoMobile("10.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
createObjectURL()4{{CompatVersionUnknown()}}{{CompatGeckoMobile("10.0")}}{{CompatNo()}}{{CompatNo()}}{{CompatNo()}}
{{domxref("FileReader")}}3{{CompatVersionUnknown()}}{{CompatGeckoMobile("10.0")}}{{CompatNo()}}11.1{{CompatNo()}}
+
+ +

 

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 +--- +

{{ Draft() }}

+

Sumario

+

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.

+
+

Atención: 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.

+
+

Acerca de los marcos de coordenadas

+

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:

+

Marco de coordenadas terrestres

+

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.

+ +

 

+

+

 

+

Marco de coordenadas del dispositivo

+

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

+

axes.png

+ +
+ Nota: 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.
+

Sobre la rotación

+

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.

+

Alpha

+

Rotación alrededor del eje z - es decir, girando el dispositivo - hace que el ángulo de rotación alfa cambie:

+

alpha.png

+

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.

+

Beta

+

Rotación alrededor del eje X - es decir, inclinando el dispositivo desde o hacia el usuario - hace que el ángulo de giro beta cambie:

+

beta.png

+

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.

+

Gamma

+

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:

+

gamma.png

+

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.

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 +--- +

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.

+ + +

{{ListGroups}}

+ +

See also

+ + 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 +--- +

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 Vibration API  ofrece a las aplicaciones web la capacidad de acceder a este hardware en caso este lo soporte, caso contrario el dispositivo no hace nada.

+ +

Describiendo vibraciones

+ +

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:

+ +

{{domxref("window.navigator.vibrate()")}}.

+ +

Vibración simple

+ +

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:

+ +
window.navigator.vibrate(200);
+window.navigator.vibrate([200]);
+
+ +

Ambos ejemplos hacen vibrar el dispositivo por 200 ms.

+ +

Patrones de vibración

+ +

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:

+ +
window.navigator.vibrate([200, 100, 200]);
+
+ +

Según este ejemplo el dispositivo vibrará por 200ms, luego se detiene por 100ms y luego vibra 200ms.

+ +

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.

+ +

Cancelar vibraciones existentes

+ +

Llamar {{domxref("window.navigator.vibrate()")}} con un valor de 0, arreglo vació, o arreglo que contenga 0's detendrá cualquier vibración en curso.

+ +

Vibraciones continuas

+ +

Algunas básicas acciones son setInterval y clearInterval que nos permitirán crear vibraciones persistentes:

+ +
var intervaloDeVibrado;
+
+// Iniciar la vibración
+function iniciarVibrado(duracion) {
+	navigator.vibrate(duracion);
+}
+
+// Detiene la vibración
+function detenerVibrado() {
+	// Limpiar el intervalo y detener las vibraciones existentes
+	if(intervaloDeVibrado) clearInterval(intervaloDeVibrado);
+	navigator.vibrate(0);
+}
+
+// Iniciar las vibraciones con una determinado tiempo e intervalo
+// Asumir que el valor recibido es un entero
+function iniciarVibradoPersistente(duracion, intervalo) {
+	intervaloDeVibrado = setInterval(function() {
+		iniciarVibrado(duracion);
+	}, intervalo);
+}
+ +

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)

+ +

¿Por qué utilizar Vibration API?

+ +

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.

+ +

Especificaciones

+ + + + + + + + + + + + + + + + +
EspecificaciónEstadoComentario
{{SpecName('Vibration API')}}{{Spec2('Vibration API')}}Especificación inicial.
+ +

Compatibilidad entre navegadores

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
CaracteŕisticaChromeFirefox (Gecko)Internet ExplorerOperaSafari
Soporte básico{{CompatVersionUnknown}} {{property_prefix("webkit")}}11.0 {{property_prefix("moz")}}
+ 16 (no prefix)
{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
CaracterísticaAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Soporte básico{{CompatVersionUnknown}} {{property_prefix("webkit")}}11.0 {{property_prefix("moz")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

Ver También

+ + 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 +--- +

{{ CSSRef() }}

+ +

Resumen

+ +

Un contexto de formato de bloque 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.

+ +

Un contexto de formato de bloque es creado por uno de los siguientes casos:

+ + + +

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.

+ +

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.

+ +

Especificaciones

+ + + +

También puedes ver

+ + 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 +--- +

{{SeeCompatTable}}

+

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.

+

Creando una media query list

+

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.

+

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:

+
var mql = window.matchMedia("(orientation: portrait)");
+
+

Revisando el resultado de un query

+

Once your media query list has been created, you can check the result of the query by looking at the value of its matches property, which reflects the result of the query:

+
if (mql.matches) {
+  /* The device is currently in portrait orientation */
+} else {
+  /* The device is currently in landscape orientation */
+}
+
+

Recibiendo notificaciones query

+

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 addListener() method on the {{domxref("MediaQueryList") }} object, specifying an observer that implements the {{domxref("MediaQueryListListener") }} interface:

+
var mql = window.matchMedia("(orientation: portrait)");
+mql.addListener(handleOrientationChange);
+handleOrientationChange(mql);
+
+

This code creates the orientation testing media query list, mql, 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).

+

The handleOrientationChange() method we implement then would look at the result of the query and handle whatever we need to do on an orientation change:

+
function handleOrientationChange(mql) {
+  if (mql.matches) {
+    /* The device is currently in portrait orientation */
+  } else {
+    /* The device is currently in landscape orientation */
+  }
+}
+
+

Terminando con las notificaciones query 

+

Cuando ya no vayas a necesitar recibir las notificaciones sobre los cambios de valro de tu media query, simplemente llama al removeListener() en el {{domxref("MediaQueryList") }}:

+
mql.removeListener(handleOrientationChange);
+
+

Compatibilidad con los navegadores

+

{{CompatibilityTable}}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Soporte básico9{{CompatGeckoDesktop("6.0") }}1012.15.1
+
+
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Soporte básico3.0{{CompatUnknown}}1012.15
+
+

Ver también

+ diff --git "a/files/es/web/guide/dom/events/creacion_y_activaci\303\263n_eventos/index.html" "b/files/es/web/guide/dom/events/creacion_y_activaci\303\263n_eventos/index.html" new file mode 100644 index 0000000000..0038e12c74 --- /dev/null +++ "b/files/es/web/guide/dom/events/creacion_y_activaci\303\263n_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 +--- +

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.

+ +

Crear eventos personalizados

+ +

    Los eventos pueden ser creados con el constructor de eventos de la siguiente manera:

+ +
var event = new Event('build');
+
+// Escucha para el evento.
+elem.addEventListener('build', function (e) { ... }, false);
+
+// Disparar event.
+elem.dispatchEvent(event);
+ +

El codigo de ejemplo de arriba usa el metodo EventTarget.dispatchEvent().   

+ +

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.

+ +

Adición de datos personalizados con CustomEvent ()

+ +

    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.
+ Por Ejemplo, el evento se puede crear de la siguiente manera:

+ +
var event = new CustomEvent('build', { 'detail': elem.dataset.time });
+ +

    Esto permitirá tener acceso a los datos adicionales en el escuchador de eventos (event listener):

+ +
function eventHandler(e) {
+  log('The time is: ' + e.detail);
+}
+
+ +

La Forma Antigua

+ +

    El enfoque más para la creación de eventos utiliza APIs inspirados en Java. A continuación se muestra un ejemplo:

+ +
// 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);
+
+
+ +

El disparo incorporado eventos

+ +

    Comunmente es deseable disparar un evento desde un elemento hijo, y lograr que el padre lo capture: opcionalmente con datos: 

+ +
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");
+  }
+}
+ +

Compatibilidad con los Navegadores

+ +

 

+ +

{{CompatibilityTable()}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Event() constructor1511{{ CompatNo() }}11.606
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}6
+
+ +

See also

+ + 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 +--- +

La plataforma Web provee varias formas de recibir notificaciones de los eventos del DOM.  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. Esta página se enfoca en los detalles de cómo funcionan estos.

+ +

Registering on-event handlers

+ +

Los controladores on-event 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 onclick, onkeypress, onfocus, etc.

+ +

Pueden especificar un controlador de evento on<...> para un evento en particular (como {{event("click")}}) como un opbjeto determinado de diferentes formas:

+ + + +

Un controlador onevent

+ +

Notese que cada objeto puede tener sólo un controlador on-event 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.

+ +

Also note that on-event handlers are called automatically, not at the programmer's will (although you can, like  mybutton.onclick(myevent); ) since they serve more as placeholders to which a real handler function can be assigned.

+ +

Non-element objects

+ +

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:

+ +
xhr.onprogress = function() { ... }
+ +

Details

+ +

The value of HTML on<...> attributes and corresponding  JavaScript properties

+ +

A handler registered via an on<...> attribute will be available via the corresponding on<...> property, but not the other way around:

+ +
<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>
+ +

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: onblur, onerror, onfocus, onload, onscroll.)

+ +

Event handler's parameters, this binding, and the return value

+ +

When the event handler is specified as an HTML attribute, the specified code is wrapped into a function with the following parameters:

+ + + +

When the event handler is invoked, the this keyword inside the handler is set to the DOM element on which the handler is registered. For more details see the this keyword documentation.

+ +

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 "The event handler processing algorithm" in the HTML specification.

+ +

When the event handler is invoked

+ +

TBD (non-capturing listener)

+ +

Terminology

+ +

The term event handler may be used to refer to:

+ + + +

When discussing the various methods of listening to events,

+ + + +

Specifications

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#event-handler-attributes', 'event handlers')}}{{Spec2('HTML WHATWG')}}
{{SpecName('HTML5 W3C', 'webappapis.html#event-handler-attributes', 'event handlers')}}{{Spec2('HTML5 W3C')}}
+ +

Browser compatibility

+ +

Event handler changes in Firefox 9

+ +

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") }}.

+ +

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.

+ +

Detecting the presence of event handler properties

+ +

You can now detect the presence of an event handler property (that is, for example, onload), using the JavaScript in operator. For example:

+ +
if ("onsomenewfeature" in window) {
+  /* do something amazing */
+}
+
+ +

Event handlers and prototypes

+ +

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 Window.prototype.onload anymore. In the past, event handlers (onload, 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.

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 +--- +

{{draft()}}

+

Everything you need to know about events will go under here. We're working on cleanup here now.

+

Docs

+

{{LandingPageListSubpages}}

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 +--- +

{{draft}}

+

The Document Object Model is an API for HTML and XML 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.

+

All of the properties, methods, and events available to the web developer for manipulating and creating web pages are organized into objects (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.

+

The DOM is most often used in conjunction with JavaScript. 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 any language.

+

The World Wide Web Consortium establishes a standard for the DOM, called the W3C DOM. It should, now that the most important browsers correctly implement it, enable powerful cross-browser applications.

+

Why is the DOM important?

+

"Dynamic HTML" (DHTML) 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 W3C FAQ). 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.

+

Even more important is the fact that the user interface of Mozilla (also Firefox and Thunderbird) is built using XUL, using the DOM to manipulate its own UI.

+

More about the DOM

+

{{LandingPageListSubpages}}

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 +--- +

 

+ + + +

Los sitios web modernos a menudo necesitan aplicaciones para presentar y/o visualizar gráficos . Se

+ +
+
+
+
Dibujando gráficas con canvas
+
Una guía inicial para usar el elemento {{HTMLElement("canvas")}} para dibujar gráficos en 2D.
+
SVG
+
+

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.

+
+
+ +

View All...

+
+ +
+

Gráficas en 3D

+ +
+
WebGL
+
+

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 .

+
+
+ +
+
+
+
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 +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}
+ +
+

En el último capítulo hicimos unas animaciones básicas 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.

+
+ +

Dibujar una bola

+ +

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á.

+ +
<canvas id="canvas" width="600" height="300"></canvas>
+
+ +

Como siempre, necesitamos un entorno para dibujar. Para dibujar la bola, creamos un contenido ball lo cual contiene propiedades y un método draw().

+ +
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();
+ +

Nada especial aquí; la bola es en realidad un circulo sencillo y se dibuja con el método {{domxref("CanvasRenderingContext2D.arc()", "arc()")}}.

+ +

Agregar velocidad

+ +

Ya que tenemos una bola, estamos listos agregar una animación básica así como aprendimos en el último capítulo 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.

+ +
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();
+
+ +

Límites

+ +

Si no probamos los límites, de repente nuestra bola se agota el canvas. Necesitamos verificar si las posiciones x e y 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 draw:

+ +
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;
+}
+ +

Primera demo

+ +

Veamos como se ve en acción hasta este punto. Dirige el ratón dentro del canvas para empezar la animación.

+ + + +

{{EmbedLiveSample("First_demo", "610", "310")}}

+ +

Aceleración

+ +

Para convertir la moción en más auténtica, puedes jugar con la velocidad, así por ejemplo:

+ +
ball.vy *= .99;
+ball.vy += .25;
+ +

Esto reduce el vector vertical de velocidad para cada fotograma para que la bola termina rebotando en el suelo.

+ + + +

{{EmbedLiveSample("Second_demo", "610", "310")}}

+ +

Efecto de rezagar

+ +

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.

+ +
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
+ctx.fillRect(0, 0, canvas.width, canvas.height);
+ + + +

{{EmbedLiveSample("Third_demo", "610", "310")}}

+ +

Agregar control de ratón

+ +

Para controlar la bola, podemos hacerla seguir nuestro ratón usando el evento mousemove, por ejemplo. El evento click solta la bola y la deja rebotar de nuevo.

+ + + +
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();
+
+ +

Mueve la bola usando el ratón y suéltala haciendo click.

+ +

{{EmbedLiveSample("Adding_mouse_control", "610", "310")}}

+ +

Breakout

+ +

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 Breakout? Visita nuestra área de Game development para mayor información.

+ +

Vea también

+ + + +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}

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 +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}
+ +
+

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.

+
+ +

Colors

+ +

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: fillStyle y strokeStyle.

+ +
+
{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}
+
Configura el estilo cuando se rellenan las formas.
+
{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}
+
Configura el estilo al contorno perimetral de las formas.
+
+ +

color 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 #000000).

+ +
+

Nota:  Cuando configuras la propiedad  strokeStyle y/o fillStyle, 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.

+
+ +

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.

+ +
// 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)';
+
+ +

A fillStyle example

+ +

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.

+ +
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);
+    }
+  }
+}
+ + + +

The result looks like this:

+ +

{{EmbedLiveSample("A_fillStyle_example", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}

+ +

A strokeStyle example

+ +

Este ejemplo es similar al de arriba, pero usa la propiedad  strokeStyle para cambiar el color del contorno de las formas. Usamos el método  arc() para dibujar circulos en lugar de celdas cuadradas.

+ +
  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();
+      }
+    }
+  }
+
+ + + +

The result looks like this:

+ +

{{EmbedLiveSample("A_strokeStyle_example", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}

+ +

Transparency

+ +

Ademas de dibujar formas opacas en el canvas, podemos dibujar formas semi-transparentes(o translucidas). Esto se logra bien configurando la propiedad  globalAlpha o asignando un color semi-transparente al estilo del trazo u  u/y al de relleno.

+ +
+
{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}
+
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.
+
+ +

The globalAlpha 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.

+ +

Debido qaque las propiedades  strokeStyle y fillStyle aceptan valores de color rgba de CSS, podemos usar la siguiente notacion para asignar una color transparente a ellos.

+ +
// Assigning transparent colors to stroke and fill style
+
+ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
+ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
+
+ +

The rgba() function is similar to the rgb() 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).

+ +

A globalAlpha example

+ +

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 globalAlpha property is set at 0.2 which will be used for all shapes from that point on. Every step in the for 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.

+ +
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();
+  }
+}
+ + + +

{{EmbedLiveSample("A_globalAlpha_example", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}

+ +

An example using rgba()

+ +

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 rgba() gives you a little more control and flexibility because we can set the fill and stroke style individually.

+ +
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);
+    }
+  }
+}
+ + + +

{{EmbedLiveSample("An_example_using_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}

+ +

Line styles

+ +

There are several properties which allow us to style lines.

+ +
+
{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}
+
Sets the width of lines drawn in the future.
+
{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}
+
Sets the appearance of the ends of lines.
+
{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}
+
Sets the appearance of the "corners" where lines meet.
+
{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}
+
Establishes a limit on the miter when two lines join at a sharp angle, to let you control how thick the junction becomes.
+
{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}
+
Returns the current line dash pattern array containing an even number of non-negative numbers.
+
{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}
+
Sets the current line dash pattern.
+
{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}
+
Specifies where to start a dash array on a line.
+
+ +

You'll get a better understanding of what these do by looking at the examples below.

+ +

A lineWidth example

+ +

This property sets the current line thickness. Values must be positive numbers. By default this value is set to 1.0 units.

+ +

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.

+ +

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.

+ +
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();
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_lineWidth_example", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}

+ +

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.

+ +

+ +

If you consider a path from (3,1) to (3,5) with a line thickness of 1.0, 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 1.0 width line in the previous example code.

+ +

To fix this, you have to be very precise in your path creation. Knowing that a 1.0 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 1.0 line width ends up completely and precisely filling a single pixel vertical line.

+ +
+

Note: 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 lineCap style whose default value is butt; you may want to compute consistent strokes with half-pixel coordinates for odd-width lines, by setting the lineCap style to square, so that the outer border of the stroke around the endpoint will be automatically extended to cover the whole pixel exactly).

+ +

Note also that only start and final endpoints of a path are affected: if a path is closed with closePath(), 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 lineJoin style, whose default value is miter, 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.

+
+ +

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.

+ +

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.

+ +

A lineCap example

+ +

The lineCap property determines how the end points of every line are drawn. There are three possible values for this property and those are: butt, round and square. By default this property is set to butt.

+ +

+ +
+
butt
+
The ends of lines are squared off at the endpoints.
+
round
+
The ends of lines are rounded.
+
square
+
The ends of lines are squared off by adding a box with an equal width and half the height of the line's thickness.
+
+ +

In this example, we'll draw three lines, each with a different value for the lineCap 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.

+ +

The line on the left uses the default butt option. You'll notice that it's drawn completely flush with the guides. The second is set to use the round 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 square option. This adds a box with an equal width and half the height of the line thickness.

+ +
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();
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_lineCap_example", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}

+ +

A lineJoin example

+ +

The lineJoin 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).

+ +

There are three possible values for this property: round, bevel and miter. By default this property is set to miter. Note that the lineJoin setting has no effect if the two connected segments have the same direction, because no joining area will be added in this case.

+ +

+ +
+
round
+
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.
+
bevel
+
Fills an additional triangular area between the common endpoint of connected segments, and the separate outside rectangular corners of each segment.
+
miter
+
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 miterLimit property which is explained below.
+
+ +

The example below draws three different paths, demonstrating each of these three lineJoin property settings; the output is shown above.

+ +
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();
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_lineJoin_example", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}

+ +

A demo of the miterLimit property

+ +

As you've seen in the previous example, when joining two lines with the miter 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.

+ +

The miterLimit 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 miterLimit property (whose default value is 10.0 in the HTML {{HTMLElement("canvas")}}), so the miterLimit 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.

+ +

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:

+ + + +

Here's a little demo in which you can set miterLimit 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.

+ +

If you specify a miterLimit 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 miterLimit 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).

+ +
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;
+}
+
+ + + +

{{EmbedLiveSample("A_demo_of_the_miterLimit_property", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}

+ +

Using line dashes

+ +

The setLineDash method and the lineDashOffset property specify the dash pattern for lines. The setLineDash method accepts a list of numbers that specifies distances to alternately draw a line and a gap and the lineDashOffset property sets an offset where to start the pattern.

+ +

In this example we are creating a marching ants effect. It is an animation technique often found in selection 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 basic animations.

+ + + +
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();
+ +

{{EmbedLiveSample("Using_line_dashes", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}

+ +

Gradients

+ +

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 fillStyle or strokeStyle properties.

+ +
+
{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}
+
Creates a linear gradient object with a starting point of (x1, y1) and an end point of (x2, y2).
+
{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}
+
Creates a radial gradient. The parameters represent two circles, one with its center at (x1, y1) and a radius of r1, and the other with its center at (x2, y2) with a radius of r2.
+
+ +

For example:

+ +
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
+var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
+
+ +

Once we've created a CanvasGradient object we can assign colors to it by using the addColorStop() method.

+ +
+
{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}
+
Creates a new color stop on the gradient object. The position is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the color argument must be a string representing a CSS {{cssxref("<color>")}}, indicating the color the gradient should reach at that offset into the transition.
+
+ +

You can add as many color stops to a gradient as you need. Below is a very simple linear gradient from white to black.

+ +
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
+lineargradient.addColorStop(0, 'white');
+lineargradient.addColorStop(1, 'black');
+
+ +

A createLinearGradient example

+ +

In this example, we'll create two different gradients. As you can see here, both the strokeStyle and fillStyle properties can accept a canvasGradient object as valid input.

+ +
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);
+
+}
+
+ + + +

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.

+ +

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.

+ +

{{EmbedLiveSample("A_createLinearGradient_example", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}

+ +

A createRadialGradient example

+ +

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).

+ +
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);
+}
+
+ + + +

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.

+ +

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 #019F62 = rgba(1,159,98,1).

+ +

{{EmbedLiveSample("A_createRadialGradient_example", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}

+ +

Patterns

+ +

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 createPattern() method.

+ +
+
{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}
+
Creates and returns a new canvas pattern object. image is a {{domxref("CanvasImageSource")}} (that is, an {{domxref("HTMLImageElement")}}, another canvas, a {{HTMLElement("video")}} element, or the like. type is a string indicating how to use the image.
+
+ +

The type specifies how to use the image in order to create the pattern, and must be one of the following string values:

+ +
+
repeat
+
Tiles the image in both vertical and horizontal directions.
+
repeat-x
+
Tiles the image horizontally but not vertically.
+
repeat-y
+
Tiles the image vertically but not horizontally.
+
no-repeat
+
Doesn't tile the image. It's used only once.
+
+ +

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 fillStyle or strokeStyle properties. For example:

+ +
var img = new Image();
+img.src = 'someimage.png';
+var ptrn = ctx.createPattern(img, 'repeat');
+
+ +
+

Note: Like with the drawImage() method, you must make sure the image you use is loaded before calling this method or the pattern may be drawn incorrectly.

+
+ +

A createPattern example

+ +

In this last example, we'll create a pattern to assign to the fillStyle property. The only thing worth noting is the use of the image's onload handler. This is to make sure the image is loaded before it is assigned to the pattern.

+ +
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);
+
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_createPattern_example", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}

+ +

Shadows

+ +

Using shadows involves just four properties:

+ +
+
{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}
+
Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
+
{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}
+
Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
+
{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}
+
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.
+
{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}
+
A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.
+
+ +

The properties shadowOffsetX and shadowOffsetY 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.

+ +

The shadowBlur 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.

+ +

The shadowColor property is a standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.

+ +
+

Note: Shadows are only drawn for source-over compositing operations.

+
+ +

A shadowed text example

+ +

This example draws a text string with a shadowing effect.

+ +
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);
+}
+
+ + + +

{{EmbedLiveSample("A_shadowed_text_example", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}

+ +

We will look at the font property and fillText method in the next chapter about drawing text.

+ +

Canvas fill rules

+ +

When using fill (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.
+
+ Two values are possible:

+ + + +

In this example we are using the evenodd rule.

+ +
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');
+}
+ + + +

{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}

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 +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}
+ +
+

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.

+
+ +

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.

+ +

Pasos básicos de animación

+ +

Estos son los pasos que necesitas para dibujar un cuadro:

+ +
    +
  1. Limpiar el canvas
    + 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()")}}.
  2. +
  3. Guardar el estado del canvas
    + 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. 
  4. +
  5. Dibujar formas animadas
    + El paso en el que realizas el renderizado del cuadro actual.
  6. +
  7. Restaurar el estado del canvas
    + Si has guardado el estado, restáuralo antes de dibujar un nuevo cuadro.
  8. +
+ +

Controlando una animación

+ +

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 for.

+ +

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.

+ +

Actualizaciones Programadas

+ +

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.

+ +
+
{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}
+
Ejecuta una función especificada por function cada delay milisegundos.
+
{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}
+
Ejecuta una función especificada por function dentro de delay milisegundos.
+
{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}
+
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.
+
+ +

Si no quieres ninguna interacción del usuario puedes usar la función setInterval() 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 setTimeout(). Al establecer los {{domxref("EventListener")}}, capturamos cualquier interacción del usuario y ejecutamos nuestras funciones de animación.

+ +
+

En los siguiente ejemplo,usaremos el método para controlar animaciones {{domxref("window.requestAnimationFrame()")}}. El método requestAnimationFrame 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 Anatomía de un videojuego en nuestra GameZona de desarrollo de Juegos.

+
+ +

Un sistema solar animado

+ +

Este ejemplo animado es un pequeño modelo de nuestro sistema solar.

+ +
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();
+
+ + + +

{{EmbedLiveSample("Un_sistema_solar_animado", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}

+ +

Un reloj animado

+ +

Este ejemplo dibuja una reloj animado, mostrando la hora actual.

+ +
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);
+ + + +

{{EmbedLiveSample("Un_reloj_animado", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}

+ +

Un panorama en bucle

+ +

En este ejemplo, una foto panorámica avanza de izquierda a derecha. Donde usaremos una imagen del Parque Nacional de Yosemite que tomamos de Wikipedia, pero tu podrías usar cualquier imagen que sea mas grande que el canvas.

+ +
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;
+}
+ +

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 CanvasXZSize y CanvasYSize.

+ +
<canvas id="canvas" width="800" height="200"></canvas>
+ +

{{EmbedLiveSample("Un_panorama_en_bucle", "830", "230")}}

+ +

Otros ejemplos

+ +
+
Un ray-caster básico
+
Un buen ejemplo de como hacer animaciones usando como control el teclado.
+
Animaciones avanzadas
+
Vamos a echar un vistazo a algunas técnicas de animación avanzadas y física en el próximo capítulo.
+
+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}

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 +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Dibujando_formas")}}
+ +
+

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.

+
+ +

El elemento <canvas>

+ +
<canvas id="tutorial" width="150" height="150"></canvas>
+
+ +

A primera vista, un elemento {{HTMLElement("canvas")}} es parecido al elemento {{HTMLElement("img")}}, con la diferencia que este no tiene los atributos src y alt. El elemento <canvas> tiene solo dos atributos - {{htmlattrxref("width", "canvas")}} y {{htmlattrxref("height", "canvas")}}. Ambos son opcionales y pueden ser definidos usando propiedades DOM. Cuando los atributos ancho y alto no estan especificados, el lienzo se inicializara con 300 pixels ancho y 150 pixels 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.

+ +
+

Nota: Si su renderizado se ve distorsionado, pruebe especificar los atributos width y height explícitamente en los atributos del <canvas> , y no usando CSS.

+
+ +

El atributo id no está especificado para el elemento  <canvas> pero es uno de los atributos globales de HTML el cual puede ser aplicado a cualquier elemento HTML (como class por ejemplo). Siempre es buena idea proporcionar un id porque esto hace más fácil identificarlo en un script.

+ +

El elemento <canvas> 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 capítulo dedicado en este tutorial. Cuando no tenemos reglas de estilo aplicadas al canvas, este será completamente transparente.

+ +
+

Contenido alternativo

+ +

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.

+ +

Proporcionar contenido alternativo es muy explicito: solo debemos insertar el contenido alterno dentro del elemento <canvas>. Los navegadores que no soporten <canvas> ignoraran el contenedor y mostrarán el contenido indicado dentro de este. Navegadores que soporten <canvas> ignorarán el contenido en su interior (de las etiquetas), y mostrarán el canvas normalmente.

+ +

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í:

+ +
<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>
+
+ +

Etiqueta </canvas> requerida

+ +

De manera distinta al elemento {{HTMLElement("img")}}, el elemento {{HTMLElement("canvas")}} requiere cerrar la etiqueta  (</canvas>).

+ +
+

Note: 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.

+
+ +

Si el contenido alternativo no se necesita, un simple <canvas id="foo" ...></canvas> es completamente compatible con todos los navegadores que soportan canvas.

+ +

El contexto de renderización

+ +

{{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, WebGL usa un 3D contexto ("experimental-webgl") basado sobre OpenGL ES.

+ +

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 method llamado  getContext(), usado para obtener el contexto a renderizar y sus funciones de dibujo. getContext() toma un parametro, el tipo de contexto. Para graficos 2D, como los que cubre este tutorial, su especificacion es "2d".

+ +
var canvas = document.getElementById('tutorial');
+var ctx = canvas.getContext('2d');
+
+ +

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 getContext().

+ +
+

Comprobando soporte

+ +

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 getContext(). Con un trozo de codigo parecido al que viene debajo:

+ +
var canvas = document.getElementById('tutorial');
+
+if (canvas.getContext){
+  var ctx = canvas.getContext('2d');
+  // drawing code here
+} else {
+  // canvas-unsupported code here
+}
+
+
+
+ +

Un esqueleto de plantilla

+ +

Aqui esta una plantilla minimalista, la cual usaremos como punto de partida para posteriores ejemplos.

+ +
<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>
+
+ +

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.

+ +

Aqui esta como la plantilla se ve en acción:

+ +

{{EmbedLiveSample("Un_esqueleto_de_plantilla", 160, 160)}}

+ +

Un simple ejemplo

+ +

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.

+ +
<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>
+
+ +

Este ejemplo quedaría así:

+ +

{{EmbedLiveSample("Un_simple_ejemplo", 160, 160, "https://mdn.mozillademos.org/files/228/canvas_ex1.png")}}

+ +

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial", "Web/Guide/HTML/Canvas_tutorial/Dibujando_formas")}}

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 +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
+ +
+

Ahora que hemos preparado nuestro entorno canvas, 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.

+
+ +

La cuadrícula

+ +

Antes de que podamos empezar a dibujar, necesitamos hablar sobre la cuadrícula del canvas o el espacio de coordenadas. 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.

+ +

Dibujando rectángulos

+ +

A diferencia de SVG, {{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.

+ +
+

Primero veamos el rectángulo. Aquí hay tres funciones que podemos usar en el canvas para dibujarlos:

+ +
+
fillRect(x, y, width, height)
+
Dibuja un rectángulo relleno.
+
strokeRect(x, y, width, height)
+
Dibuja el contorno de un rectángulo.
+
clearRect(x, y, width, height)
+
Borra un área rectangular especificada, dejándola totalmente transparente.
+
+ +

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.

+ +

A continuación se muestra la función draw() de la página anterior, pero ahora haciendo uso de estas tres funciones.

+ +

Ejemplo de forma rectangular

+ + + +
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);
+  }
+}
+ +

El resultado de este ejemplo se muestra a continuación.

+ +

{{EmbedLiveSample("Rectangular_shape_example", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}

+ +

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.

+ +

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.

+ +

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.

+ +

Dibujando trazos

+ +

Crear formas mediante trazos requiere algunos pasos adicionales.

+ +
    +
  1. Primero, se crea el trazo.
  2. +
  3. A continuación, se usan comandos de dibujo para dibujar dentro del trazo.
  4. +
  5. Después, se cierra el trazo.
  6. +
  7. Una vez el trazo ha sido creado, se le puede dar contorno o relleno para renderizarlo.
  8. +
+ +

Estas son las funciones que se usan para llevar a cabo estos pasos:

+ +
+
beginPath()
+
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.
+
closePath()
+
Cierra el trazo de tal forma que los comandos de dibujo futuros son, una vez más redireccionados al contexto.
+
stroke()
+
Dibuja el contorno de la forma.
+
fill()
+
Dibuja una forma solida rellenando el área del trazo.
+
+ +

El primer paso para crear un trazo es llamar la función beginPath(). 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.

+ +
Nota: Cuando el trazo actual este vacio, como aparece inmediatamente despues de llamar la función beginPath(), o en un canvas nuevo, el primer comando para la construcción del trazo es siempre tratada como un moveTo(), 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.
+ +

El segundo paso es llamar los métodos que específican los trazos a crear. Los veremos en seguida.

+ +

El tercero, y un paso opcional, es llamar a la función closePath(). 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.

+ +
Nota: Cuando llamas a la función fill(), cualquier forma abierta es cerrada automaticamente, de tal forma que no tendrás que llamar a la función closePath(). Este no es el caso cuando llamas a la función stroke().
+ +

Dibujando un triangulo

+ +

Por ejemplo, el código para dibujar un triangulo luciría como el siguiente:

+ + + +
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();
+  }
+}
+
+ +

El resultado lucirá así:

+ +

{{EmbedLiveSample("Drawing_a_triangle", 160, 160)}}

+ +

Moviendo la pluma

+ +

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 moveTo(). 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.

+ +
+
moveTo(x, y)
+
Mueve la pluma a las coordenadas específicadas por x e y.
+
+ +

Cuando el canvas es inicializado ó la función beginPath() es llamada, querrás usar la función moveTo() para colocar el punto de inicio en alguna otra parte. Podríamos usar moveTo() para dibujar trazos sin conectar. Toma un vistazo a la cara sonriente de abajo. He marcado los lugares donde use el método moveTo() (las líneas rojas).

+ +

Para intentar esto por tí mismo, puedes usar el pequeño código de abajo. Solo pégalo dentro de la función draw() que vimos antes.

+ + + +
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();
+  }
+}
+
+ +

El resultado luce así:

+ +

{{EmbedLiveSample("Moving_the_pen", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}

+ +

Si quisieras ver las líneas conectadas, puedes remover las líneas de código que llaman moveTo().

+ +
+

Nota: Para aprender más sobre la función arc(), vea los {{anch("Arcs")}} a continuación.

+
+ +

Líneas

+ +

Para dibujar lineas rectas usa el método lineTo().

+ +
+
lineTo(x, y)
+
Dibuja una línea desde la posición actual del dibujo a la posición específicada por x e y.
+
+ +

Este método toma dos argumentos x e y, 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 moveTo().

+ +

El ejemplo siguiente dibuja dos triángulos, uno rellenado y el otro contorneado.

+ + + +
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();
+  }
+}
+
+ +

Esto comienza llamando a beginPath() para empezar una nueva forma. Entonces usamos el método moveTo() 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.

+ +

{{EmbedLiveSample("Lines", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}

+ +

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 closePath() para el triángulo contorneado, solamente dos líneas serian dibujadas, no un triángulo completo.

+ +

Arcos

+ +

Para dibujar arcos o circulos usamos el método arc(). También puedes usar arcTo(), pero su implementación es un poco menos confiable, así que no lo cubriremos aquí.

+ +
+
arc(x, y, radius, startAngle, endAngle, anticlockwise)
+
Dibuja un arco.
+
+ +

Este método toma cinco parámetros: x e y son las coordenadas del centro del círculo en el cual el arco debería ser dibujado. radius se explica por sí solo. Los parámetros startAngle y endAngle 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 anticlockwise es un valor Booleano el cual cuando es verdadero (true) dibuja el arco al contrario de las manecillas del reloj, de lo contrario el arco es dibujado al sentido de las manecillas del reloj.

+ +
+

Nota: Los ángulos en la función del arco (arc) son medidos en radianes, no en grados. Para convertir grados a radianes puedes usar la siguiente expresión en Javascript: radians = (Math.PI/180)*degrees.

+
+ +

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.

+ +

Las dos sentencias for son para iterar a través de las filas y columnas de los arcos. Para cada arco, empezamos un nuevo trazo llamando beginPath(). 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.

+ +

Las coordenadas x e y deberían ser suficientemente claras. radius y startAngle estan arreglados. El endAngle 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.

+ +

El parámetro clockwise 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 if hace los arcos contorneados a la mitad desde arriba y los arcos hacia abajorellenados a la mitad.

+ + + +
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();
+        }
+      }
+    }
+  }
+}
+
+{{EmbedLiveSample("Arcs", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}} + +

Curvas Bezier curvas cuadráticas

+ +

El siguiente tipo de trazos disponibles son las  curvas Bézier, en sus dos variantes, cúbicas y cuadráticas. Son usadas generalmente para dibujar complejas formas orgánicas.

+ +
+
quadraticCurveTo(cp1x, cp1y, x, y)
+
Dibuja una curva cuadrática de Bézier desde la posición actual de la pluma hasta el punto final especificado por x e y, utilizando el punto de control especificado por cp1x y cp1y.
+
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+
Dibuja una curva cúbica de Bézier desde la posición actual de la pluma hasta el punto final especificado por x e y, utilizando los puntos de control especificados por (cp1x, cp1y) y (cp2x, cp2y).
+
+ +

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 punto de control (indicado por el punto rojo), mientras que una curva cúbica de Bézier utiliza dos puntos de control.

+ +

Los parámetros x e y de ambos métodos son las coordenadas del punto final. cp1x y cp1y son las coordenadas del primer punto de control, y cp2x y cp2y son las coordenadas del segundo punto de control.

+ +

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.

+ +

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.

+ +

Curvas de Bezier cuadraticas

+ +

Este ejemplo usa multiples curvas cuadraticas de Bézier para renderizar un globo de voz.

+ + + +
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();
+  }
+}
+
+ +

{{EmbedLiveSample("Quadratic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}

+ +

Curvas cúbicas Bezier

+ +

Este ejemplo dibuja un corazon usanco curvas cúbicas de Bézier.

+ + + +
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();
+  }
+}
+
+ +

{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}

+ +

Rectangles

+ +

In addition to the three methods we saw in {{anch("Drawing rectangles")}}, which draw rectangular shapes directly to the canvas, there's also the rect() method, which adds a rectangular path to a currently open path.

+ +
+
rect(x, y, width, height)
+
Draws a rectangle whose top-left corner is specified by (x, y) with the specified width and height.
+
+ +

When this method is executed, the moveTo() method is automatically called with the parameters (0,0). In other words, the current pen position is automatically reset to the default coordinates.

+ +

Making combinations

+ +

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.

+ + + +
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();
+}
+
+ +
+

The resulting image looks like this:

+ +

{{EmbedLiveSample("Making_combinations", 160, 160)}}

+ +

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 fillStyle property on the drawing context, and the use of a utility function (in this case roundedRect()). 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.

+ +

We'll take another look at fillStyle, 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.

+ +

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Basic_usage", "Web/Guide/HTML/Canvas_tutorial/Using_images")}}

+
+
+ +

 

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 +--- +
{{CanvasSidebar}} {{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}
+ +
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.
+ +
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.
+ +

Fallback content

+ +

The content inside the <canvas> ... </canvas> 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 html5accessibility.com demonstrates how this can be done:

+ +
<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> 
+ +

See the video how NVDA reads this example by Steve Faulkner.

+ +

ARIA rules

+ +

Accessible Rich Internet Applications (ARIA) 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 ARIA and ARIA techniques for more information.

+ +
<canvas id="button" tabindex="0" role="button" aria-pressed="false" aria-label="Start game"></canvas>
+
+ +

Hit regions

+ +

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).

+ +
+
{{domxref("CanvasRenderingContext2D.addHitRegion()")}} {{experimental_inline}}
+
Adds a hit region to the canvas.
+
{{domxref("CanvasRenderingContext2D.removeHitRegion()")}} {{experimental_inline}}
+
Removes the hit region with the specified id from the canvas.
+
{{domxref("CanvasRenderingContext2D.clearHitRegions()")}} {{experimental_inline}}
+
Removes all hit regions from the canvas.
+
+ +

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.

+ +
<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>
+ +

The addHitRegion() method also takes a control option to route events to an element (that is a descendant of the canvas):

+ +
ctx.addHitRegion({control: element});
+ +

This can be useful for routing to {{HTMLElement("input")}} elements, for example. See also this codepen demo.

+ +

Focus rings

+ +

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 drawFocusIfNeeded property can be used.

+ +
+
{{domxref("CanvasRenderingContext2D.drawFocusIfNeeded()")}} {{experimental_inline}}
+
If a given element is focused, this method draws a focus ring around the current path.
+
+ +

Additionally, the scrollPathIntoView() method can be used to make an element visible on the screen if focused, for example.

+ +
+
{{domxref("CanvasRenderingContext2D.scrollPathIntoView()")}} {{experimental_inline}}
+
Scrolls the current path or a given path into the view.
+
+ +

See also

+ + + +
{{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}
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 +--- +

+ +

<canvas> es un elemento HTML el cual puede ser usado para dibujar gráficos usando scripts (normalmente JavaScript). Este puede, por ejemplo, ser usado para dibujar gráficos, realizar composición de fotos o simples (y no tan simples) animaciones. Las imágenes a la derecha muestran algunos ejemplos de implementaciones <canvas>  las cuales se verán en un futuro en este tutorial.

+ +

<canvas>  fue introducido primero por Apple para el Mac OS X Dashboard y después implementado en Safari y Google Chrome. Navegadores basados en Gecko 1.8, tal como Firefox 1.5, que también soportan este elemento. El <canvas> es un elemento parte de las especificaciones de la WhatWG Web applications 1.0 mejor conocida como HTML5.

+ +

En este tutorial se describe cómo usar el elemento <canvas> 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.

+ +

Antes de Empezar

+ +

Usar el elemento <canvas> no es algo muy díficil pero necesita saber y entender los aspectos básicos del HTML y JavaScript. El elemento <canvas> 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. Con el fin de dibujar gráficos en el lienzo <canvas> se utiliza un objeto de contexto de JavaScript que crea gráficos sobre la marcha.

+ +

En este Tutorial

+ + + +

Vea también

+ + + +

Nota a los contribuyentes

+ +

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.

+ +
{{ Next("Web/Guide/HTML/Canvas_tutorial/Basic_usage") }}
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 +--- +

{{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. This article aims to provide suggestions for optimizing your use of the canvas element, to ensure that your Web site or app performs well.

+

A continuación una lista de tips par mejorar el rendimiento:

+ +

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Basic_animations")}}

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 +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}
+ +
+

Hasta ahora, no habíamos mirado los píxeles reales de nuestro canvas. Con el objeto ImageData, puedes leer y escribir directamente un array de datos para manipular píxeles.

+ +

También veremos cómo se puede controlar el suavizado de la imagen (antialiasing) y cómo guardar imágenes de tu canvas.

+
+ +

El objeto ImageData

+ +

El objeto {{domxref("ImageData")}} representa los datos pixelados subyacentes de un área de un objeto lienzo. Contiene los siguientes atributos de sólo lectura:

+ +
+
width
+
El ancho de la imagen en píxeles.
+
height
+
La altura de la imagen en píxeles.
+
data
+
Un objeto {{jsxref("Uint8ClampedArray")}} que representa un array unidimensional, contiene información en formato RGBA, con valores desde 0 hasta 255 (incluído).
+
+ +

La propiedad data 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.

+ +

El {{jsxref("Uint8ClampedArray")}} contiene alto × ancho × 4 bytes de datos, con valores de índice en el rango entre 0 y (alto×ancho×4)-1.

+ +

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:

+ +

blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];

+ +

Si se le da un conjunto de coordenadas (X e Y), puede que termine haciendo algo así:

+ +
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];
+
+ +

O, en ES6 sería algo así:

+ +
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;
+
+ +

You may also access the size of the pixel array in bytes by reading the Uint8ClampedArray.length attribute:

+ +
var numBytes = imageData.data.length;
+
+ +

Creando un objeto ImageData

+ +

Para crear un objeto nuevo y vacío tipo ImageData, debes usar el método  {{domxref("CanvasRenderingContext2D.createImageData", "createImageData()")}}. Hay dos versiones del método createImageData():

+ +
var myImageData = ctx.createImageData(width, height);
+ +

Esto crea un nuevo objeto ImageData con las dimensiones especificadas. Todos los pixels tienen valor correspondiente a negro - transparente (0,0,0,0).

+ +

También puedes crear un nuevo objeto ImageData con las mismas dimensiones que otro objeto, especificado por anotherImageData. Los píxels del nuevo objeto tienen valor negro - transparente. ¡Esto no es una copia de los datos de la imagen!

+ +
var myImageData = ctx.createImageData(anotherImageData);
+ +

Getting the pixel data for a context

+ +

To obtain an ImageData object containing a copy of the pixel data for a canvas context, you can use the getImageData() method:

+ +
var myImageData = ctx.getImageData(left, top, width, height);
+ +

This method returns an ImageData object representing the pixel data for the area of the canvas whose corners are represented by the points (left,top), (left+width, top), (left, top+height), and (left+width, top+height). The coordinates are specified in canvas coordinate space units.

+ +
+

Note: Any pixels outside the canvas are returned as transparent black in the resulting ImageData object.

+
+ +

This method is also demonstrated in the article Manipulating video using canvas.

+ +

A color picker

+ +

In this example we are using the getImageData() method to display the color under the mouse cursor. For this, we need the current position of the mouse with layerX and layerY, then we look up the pixel data on that position in the pixel array that getImageData() provides us. Finally, we use the array data to set a background color and a text in the <div> to display the color.

+ + + +
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);
+
+ +

{{ EmbedLiveSample('A_color_picker', 610, 240) }}

+ +

Painting pixel data into a context

+ +

You can use the putImageData() method to paint pixel data into a context:

+ +
ctx.putImageData(myImageData, dx, dy);
+
+ +

The dx and dy parameters indicate the device coordinates within the context at which to paint the top left corner of the pixel data you wish to draw.

+ +

For example, to paint the entire image represented by myImageData to the top left corner of the context, you can simply do the following:

+ +
ctx.putImageData(myImageData, 0, 0);
+
+ +

Grayscaling and inverting colors

+ +

In this example we iterate over all pixels to change their values, then we put the modified pixel array back to the canvas using putImageData(). 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 x = 0.299r + 0.587g + 0.114b, for example. See Grayscale on Wikipedia for more information.

+ + + +
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);
+}
+
+ +

{{ EmbedLiveSample('Grayscaling_and_inverting_colors', 330, 270) }}

+ +

Zooming and anti-aliasing

+ +

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.

+ +

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.

+ +
zoomctx.drawImage(canvas,
+                  Math.abs(x - 5), Math.abs(y - 5),
+                  10, 10, 0, 0, 200, 200);
+ +

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 imageSmoothingEnabled property (which needs prefixes for different browsers).

+ + + + + +
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);
+}
+ +

{{ EmbedLiveSample('Zoom_example', 620, 490) }}

+ +

Guardando las imágenes

+ +

The {{domxref("HTMLCanvasElement")}} provides a toDataURL() method, which is useful when saving images. It returns a data URI containing a representation of the image in the format specified by the type parameter (defaults to PNG). The returned image is in a resolution of 96 dpi.

+ +
+
{{domxref("HTMLCanvasElement.toDataURL", "canvas.toDataURL('image/png')")}}
+
Default setting. Creates a PNG image.
+
{{domxref("HTMLCanvasElement.toDataURL", "canvas.toDataURL('image/jpeg', quality)")}}
+
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.
+
+ +

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 download attribute to save it to disc, for example.

+ +

You can also create a {{domxref("Blob")}} from the canvas.

+ +
+
{{domxref("HTMLCanvasElement.toBlob", "canvas.toBlob(callback, type, encoderOptions)")}}
+
Creates a Blob object representing the image contained in the canvas.
+
+ +

See also

+ + + +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}

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 +--- +

Cada elemento {{web.link("/es/docs/Web/HTML", "HTML")}} es miembro de una o más categorías de contenido — estas categorías agrupan elementos que comparten características comunes. 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 ninguna de estas categorías.

+ +

Hay tres tipos de categorías de contenido:

+ + + +
+

Nota: 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 partes relevantes de la especificación HTML.

+
+ +

Un diagrama de Venn que muestra cómo se interrelacionan las distintas categorías de contenido. Las siguientes secciones explican estas relaciones en texto.

+ +

Categorías de contenido principal

+ +

Contenido de metadatos

+ +

Los elementos pertenecientes a la categoría contenido de metadatos modifican la presentación o el comportamiento del resto del documento, establecen enlaces a otros documentos o transmiten otra información fuera de banda.

+ +

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")}}.

+ +

Flujo de contenido

+ +

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.

+ +

Algunos otros elementos pertenecen a esta categoría, pero solo si se cumple una condición específica:

+ + + +

Contenido de sección

+ +

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")}}.

+ +

Los elementos que pertenecen a esta categoría son {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("nav")}} y {{HTMLElement("section")}}.

+ +
+

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.

+
+ +

Contenido del encabezado

+ +

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.

+ +

Los elementos que pertenecen a esta categoría son {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}} y {{HTMLElement("hgroup")}}.

+ +
+

Aunque es probable que tenga contenido de encabezado, {{HTMLElement("header")}} no es contenido de encabezado en sí mismo.

+
+ +
+

Nota: 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.

+
+ +

Contenido de redacción

+ +

El contenido de redacción define el texto y el marcado que contiene. Las series de contenido de redacción forman párrafos.

+ +

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).

+ +

Algunos otros elementos pertenecen a esta categoría, pero solo si se cumple una condición específica:

+ + + +

Contenido incrustado

+ +

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")}}.

+ +

Contenido interactivo

+ +

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")}}.
+ Algunos elementos pertenecen a esta categoría solo bajo condiciones específicas:

+ + + +

Contenido palpable

+ +

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.

+ +

Contenido asociado a formulario

+ +

El contenido asociado a un formulario comprende elementos que tienen un formulario de propietario, expuesto mediante un atributo form. El propietario de un formulario es el elemento {{HTMLElement("form")}} que lo contiene o el elemento cuya identificación se especifica en el atributo form.

+ + + +

Esta categoría contiene varias subcategorías:

+ +
+
enumerado
+
Elementos que se enumeran en las colecciones IDL {{DOMxRef("HTMLFormElement.elements", "form.elements")}} y fieldset.elements. Contiene: {{HTMLElement("button")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("input")}}, {{deprecated_inline()}} {{HTMLElement("keygen")}}, {{HTMLElement("object")}}, {{HTMLElement("output")}}, {{HTMLElement("select")}} y {{HTMLElement("textarea")}}.
+
etiquetable
+
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")}}.
+
transmisible
+
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")}}.
+
reiniciable
+
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")}}.
+
+ +

Categorías secundarias

+ +

Hay algunas clasificaciones secundarias de elementos que también puede ser útil tener en cuenta.

+ +

Elementos de soporte de scripts

+ +

Los elementos de soporte de scripts 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.

+ +

Los elementos que admiten scripts son:

+ + + +

Modelo de contenido transparente

+ +

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.

+ +

Por ejemplo, los elementos {{HTMLElement("del")}} y {{HTMLElement("ins")}} son transparentes:

+ +
<p>Sostenemos que estas verdades son <del><em>sagradas e innegablemente</em></del> <ins>evidentes por sí mismas</ins>.</p>
+
+ +

Si esos elementos fueran eliminados, este fragmento seguiría siendo HTML válido (si no es Español correcto).

+ +
<p>Sostenemos que estas verdades son <del><em>sagradas e innegablemente</em></del> <ins>evidentes por sí mismas</ins>.</p>
+
+ +

Otros modelos de contenido

+ +

Seccionado raíz.

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 +--- +

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.

+ +

¿Cómo funciona?

+ +

Todo lo que debes hacer es definir el atributo {{htmlattrxref("contenteditable")}} en cualquier elemento HTML que quieras hacer editable.

+ +

Este es un ejemplo simple con el cual puedes crear elementos {{HTMLElement("div")}} cuyo contenido pueda ser editado por el usuario.

+ +
<div contenteditable="true">
+  This text can be edited by the user.
+</div>
+ +

Aquí esta el HTML anterion en acción:

+ +

{{ EmbedLiveSample('How_does_it_work') }}

+ +

Ejecutando Comandos

+ +

Cuando un elemento HTML tiene el parametro contenteditable en true, se hace disponible el método {{ domxref("document.execCommand") }}. Esto te permite ejecutar comandos 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 contentEditable, estás llamando a execCommand que afectará al elemento editable activo.

+ +

Differences in markup generation

+ +

El uso de contenteditable 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")}}).

+ +

Afortunadamente, en los navegadores modernos las cosas son un poco más consistentes. A partir de Firefox 55, 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.

+ +

Pruebalo en el ejemplo de abajo.

+ +
+

Note: Internet Explorer ya no se está desarrollando y usa {{htmlelement("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:

+ +
document.execCommand("DefaultParagraphSeparator", false, "p");
+ +

Seguridad

+ +

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 about:config:

+ +
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");
+ +

Ejemplo: un simple pero completo editor de texto enriquecido

+ +
+
<!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>
+
+
+ +
Nota: si quieres ver cómo estandarizar la creación y la inserción de tu editor en tu página, puedes ver nuestro más completo ejemplo de editor de texto enriquecido.
+ +

Véase también

+ + 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 +--- +

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.

+ +

Varias tecnologías (como CSS, JavaScript, Flash, AJAX, JSON) 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 HTML (HyperText Markup Language). Sin HTML, no habría páginas web.

+ +

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.

+ +

Una breve historia del HTML

+ +

A finales de la década de los 80s, Tim Berners-Lee estuvo trabajando como físico en CERN (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, FTP (File Transfer Protocol), y Usenet- 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).

+ +

¿Qué es el HTML?

+ +

HTML es un lenguaje de etiquetas. 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 /.

+ +

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>Mi perro odia el pescado.</p>
+
+ +

Cuando este contenido se muestra en una página web, mediante un navegador, aparece así:

+ +

{{ EmbedLiveSample("Spl1", 400, 50) }}

+ +

El navegador emplea las etiquetas como guías para saber cómo debe ser mostrado el contenido que hay dentro de dichas etiquetas.

+ +

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>Mi perro <em>odia</em> el pescado.</p>
+
+ +

Cuando se muestre se verá del siguiente modo:

+ +

{{ EmbedLiveSample("Spl2", 400, 50) }}

+ +

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:

+ +
<img src="smileyface.jpg">
+ +

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 XHTML es obligatoria (que es un lenguaje que permite una forma de poder implementar XML en los elementos del HTML).

+ +

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 Mozilla Thimble, que es un editor online  interactivo que enseña cómo escribir HTML. Además, en el HTML Elements 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.

+ +

Elementos — los bloques básicos de construcción

+ +

El HTML consiste en una serie de elementos. Los Elementos definen el significado semántico 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 HTML Elements para ver una lista completa de todos los elementos.

+ +

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.

+ +

Muchos elementos contienen otros elementos, formando una estructura jerárquica. Un ejemplo simple, pero completo de una página web sería este:

+ +
<html>
+  <body>
+
+    <p>Mi perro <em>odia</em> el pescado.</p>
+
+  </body>
+</html>
+ +

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 DOM: siglas inglesas del Documento Objeto Modelo (Document Object Model).

+ +

Etiquetas

+ +

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 W3C (Asociación Global que vela por mantener los estándares HTML) recomiendan usar minúsculas (y además el XHTML requiere de las minúsculas).

+ +

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>Esto es texto dentro de un párrafo.</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 código válido.

+ +

Esto es un ejemplo de código válido:

+ +
<em>Me <strong>refiero</strong> a eso</em>.
+
+ +

Esto es un ejemplo de código inválido:

+ +
Invalido: <em>Me <strong>refiero</em> a eso</strong>.
+ +

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.

+ +
+

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 en todos los navegadores modernos.

+
+ +

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:

+ +
<img src="smileyface.jpg">
+ +

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).

+ +
<img src="smileyface.jpg" />
+ +

En HTML esta barra no aporta ninguna funcionalidad técnica y su uso es solamente una elección de estilo.

+ +

Atributos

+ +

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 atributos. Los atributos suelen consistir en dor partes:

+ + + +

Algunos atributos sólo pueden tener un único valor. Son atributos Booleanos 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:

+ +
<input required="required">
+
+<input required="">
+
+<input required>
+
+ +

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 class=foo bar> (Ten cuidado, esto probablemente no quiere decir lo que piensas que significa.)
+ +

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 class="foo" bar="">
+ +

Nombre de caracteres referenciados

+ +

Los Caraceteres Referenciados  (a veces llamados entidades) 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:

+ + + +

Hay muchas más entidades, pero estas cuatro son las más importantes por que representan caracteres que tienen un significado especial en HTML.

+ +

Tipo de documento y comentarios

+ +

Además de las etiquetas, el contenido y las entidades, un documento de HTML debe contener una declaración doctype en la primera línea. En el HTML actual esto se escribe del siguiente modo:

+ +
<!DOCTYPE html>
+ +

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 W3C y que no trate de emular que se trata de un Internet Explorer de los 90's. (Consultar peculiaridades.)

+ +

HTML tiene un mecanismo para poder introducir comentarios 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:

+ +
<!-- Esto es un comentario de texto -->
+ +

Un pequeño documento pero completo

+ +

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 myfirstdoc.html 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.

+ +
<!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>
+
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 +--- +
+
Este artículo proporciona información para ayudarte a hacer uso de tecnologías y APIs.
+
+ +
+
+
+
+
+
Área de aprendizaje HTML
+
HyperText Markup Language (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.
+
Guía del Desarrollador: CSS
+
CSS (hojas de estilo en cascada) es un lenguaje usado para describir la presentación gráfica de un documento escrito en HTML.
+
Guía de Eventos
+
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.
+
AJAX
+
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.
+
Elementos Gráficos en la Web
+
Las páginas web y aplicaciones modernas a menudo necesitan presentar elementos gráficos (2D, 3D o video).
+
Guía de Web APIs
+
Listado de todas las APIs web y qué hacen.
+
JavaScript
+
JavaScript es un poderoso lenguaje de scripting utilizado para crear aplicaciones para la Web.
+
Localización y codificación de Caracteres
+
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 recomendaciones de la especificación HTML 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.
+
Desarrollo Web Móvil
+
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 Firefox OS.  O puede que te interesen los detalles de Firefox para Android.
+
+ +
+
+
+ +
+
+
Progressive Web Apps (PWA)
+
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.
+
Optimización y Rendimiento
+
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.
+
Mapeo y Serialización XML
+
La Plataforma Web provee los diferentes métodos de parseo y serialización, cada uno con sus pros y contras.
+
SVG-in-OpenType
+
El SVG-in-OpenType está actualmente en manos del  MPEG group. Una vez listos para una más amplia adopción de información desde wiki.mozilla.org nos trasladaremos aquí, actualizados y expandidos.
+
El Web Open Font Format (WOFF)
+
WOFF ( Web Open Font Format) es un formato de tipografías para páginas web desarrollado por Mozilla en conjunto con Type Supply, LettError y otras organizaciones.
+
Utilizar FormData Objects
+
FormData  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 submit() de los formularios para enviarla si el tipo de codificación del formulario fuese "multipart/form-data".
+
Glosario
+
Define gran cantidad de términos técnicos relativos a las páginas Web e Internet.
+
+
+
+
+
+ +

Ver también

+ + 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 +--- +

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 Firefox OS. O podría estar interesado en detalles sobre Firefox para Android.

+ +

Hemos organizado esta documentación en dos secciones, diseñando para dispositivos móviles y desarrollo para diferentes navegadores. Vea también la guía a la amigabilidad móvil para desarrolladores web de Jason Grlicky.

+ +

Diseñando para dispositivos móviles

+ +

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.

+ +

Trabajando con pantallas pequeñas

+ +

Diseño web adaptable 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:

+ + + +

La etiqueta meta viewport ordena al navegador que muestre su sitio web a la escala adecuada para el dispositivo del usuario.

+ +

Trabajando con pantallas táctiles

+ +

Para usar una pantalla táctil necesitará trabajar con eventos DOM Touch. No tendrá la posibilidad de usar la pseudo-clase CSS :hover 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 diseñar para pantallas táctiles.

+ +

Puede usar el media query -moz-touch-enabled para cargar una CSS diferente en un dispositivo con pantalla táctil.

+ +

Optimizando imágenes

+ +

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 altura de pantalla, anchura y proporción de píxeles.

+ +

También puede hacer uso de propiedades CSS para implementar efectos visuales como gradientes y sombras sin utilizar imágenes para ello.

+ +

APIs móviles

+ +

Finalmente, puede aprovechar las nuevas posibilidades ofrecidas por los dispositivos móviles, como la orientación y la geolocalización.

+ +

Desarrollo para diferentes navegadores

+ +

Escribir código para diferentes navegadores (cross-browser)

+ +

Para crear sitios web que funcionen aceptablemente en diferentes navegadores móviles:

+ + + +

Por ejemplo, si establece un gradiente como fondo para cierto texto usando una propiedad prefijada por el proveedor (vendor-prefixed) como -webkit-linear-gradient, es mejor incluir las otras versiones prefijadas de la propiedad linear-gradient (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 linear-gradient.

+ +

Vea esta lista de propiedades específicas para Gecko, esta lista de propiedades específicas para WebKit y la tabla de propiedades específicas de proveedores (vendor-specific) de Peter Beverloo.

+ +

Usar herramientas como CSS Lint puede ayudar a encontrar problemas como este en el código y preprocesadores como SASS y LESS pueden ser de ayuda para crear código compatible con diferentes navegadores.

+ +

Precaución al husmear el agente de usuario (user agent)

+ +

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 (user agent) para intentar distinguir entre ordenadores de escritorio, tabletas y teléfonos, y servir diferente contenido a cada tipo de dispositivo.

+ +

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 guía para usar la cadena de agente de usuario para determinar el tipo de dispositivo.

+ +

Probar en múltiples navegadores

+ +

Compruebe su sitio web en múltiples navegadores. Esto significa probarlo en múltiples plataformas — al menos iOS y Android.

+ + 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 +--- +

La plataforma web proveé Los siguientes objetos para hacer parsing (convertir una cadena de texto a código) y serializing (visceversa) a un XML:

+ + + +

Parte 1: Como crear un documento XML 

+ +

Usar una de la siguientes opciones para crear un documento XML  (el cual es una instancia de Document).

+ +

Codificando textos al árbol del DOM

+ +
+
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);
+
+
+ +

Creando un documento XML empezando desde un árbol de Objetos JavaScript (JXON)

+ +

Por favor vea JXON algoritmos de reversa.

+ +

Codificando rexursos de URL direccionables en árboles del DOM

+ +

Usando XMLHttpRequest

+ +

Aquí hay un código de ejemplo que lee y codifica un archivo XML con  URL direccionable en un árbol del DOM:

+ +
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();
+
+ +

xhr.responseXML es una instancia de {{domxref("Document")}}.

+ +

Parte 2: Como serializar el contenido de un documento XML

+ +

Use the following approaches to serialize the contents of the XML document you created in Part 1.

+ +

Serializing DOM trees to strings

+ +

First, create a DOM tree as described in How to Create a DOM tree. Alternatively, use a DOM tree obtained from {{ domxref("XMLHttpRequest") }}.

+ +

Now, let's serialize doc — the DOM tree — to a string:

+ +
var oSerializer = new XMLSerializer();
+var sXML = oSerializer.serializeToString(doc);
+ +

The new XMLSerializer() constructor is not available from within a JS XPCOM component (or a JS module). Instead, write:

+ +
var oSerializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"]
+                            .createInstance(Components.interfaces.nsIDOMSerializer);
+var sXML = oSerializer.serializeToString(doc);
+
+ +

"Pretty" serialization of DOM trees to strings

+ +

You can pretty print a DOM tree using XMLSerializer and E4X. First, create a DOM tree as described in the How to Create a DOM tree article. Alternatively, use a DOM tree obtained from {{ domxref("XMLHttpRequest") }}. The doc variable contains the DOM tree.

+ +
var oSerializer = new XMLSerializer();
+var sPrettyXML = XML(oSerializer.serializeToString(doc)).toXMLString();
+ +

Indents consist of two spaces. To write a more efficient version or customize the indent string, use {{ domxref("treeWalker") }}.

+ +
Note: When using the E4X toXMLString method, your CDATA elements will be lost, and only the containing text will remain. So if you have CDATA elements in your XML, using the preceding method might not be useful.
+ +
<content><![CDATA[This is the content]]></content>
+
+ +

Becomes

+ +
<content>This is the content</content>
+ +

Serializing DOM trees to Javascript Object trees (JXON)

+ +

JXON (lossless JavaScript XML Object Notation) is a way to represent JavaScript Objects using XML. To address only parts of an XML document, use XPath instead of converting the whole document into JSON! Otherwise, read the article about JXON.

+ +

Serializing DOM trees to files

+ +

First, create a DOM tree as described in the How to Create a DOM tree article. If you already have a DOM tree from using {{ domxref("XMLHttpRequest") }}, skip to the end of this section.

+ +

Now, let's serialize doc, the DOM tree, to a file. For more information about files, see about using files in Mozilla):

+ +
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();
+
+ +

Serializing XMLHttpRequest objects to files

+ +

If you already have a DOM tree from using {{ domxref("XMLHttpRequest") }}, use the same code as above but replace serializer.serializeToStream(doc, oFOStream, "") with serializer.serializeToStream(xmlHttpRequest.responseXML.documentElement, oFOStream, "") where xmlHttpRequest is an instance of XMLHttpRequest.

+ +

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 xmlHttpRequest.responseText directly.

+ +

Serializing HTML documents

+ +

If the DOM you have is an HTML document, you can serialize it simply using

+ +
var serialized = document.documentElement.innerHTML;
+
+ +

See also

+ + 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 +--- +

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.

+ +

{{LandingPageListSubpages}}

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 +--- +

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. Sin embargo, los workers trabajan dentro de un contexto global diferente de la ventana actual (usar el atajo  {{ domxref("window") }} en lugar de {{ domxref("window.self","self") }} con el fin de obtener el scope actual dentro de un {{ domxref("Worker") }} retornaría, de hecho, un error).

+ +

El hilo worker puede realizar tareas sin interferir con la interfaz de usuario. Ademas, pueden realizar I/O usando XMLHttpRequest (aunque el responseXML y los atributos channel son siempre null).

+ +

Para documentacion de referencia acerca de workers busca {{ domxref("Worker") }} ; este articulo complementa ese ofreciendo ejemplos y detalles adicionales. Para una lista de las funciones disponibles sobre workers, visita  Functions and interfaces available to workers.

+ +

Acerca de seguridad de hilos

+ +

La interfaz  {{ 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.

+ +

Creando un web worker

+ +

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 (worker thread), 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.

+ +
+
var myWorker = new Worker("my_task.js");
+
+myWorker.onmessage = function (oEvent) {
+  console.log("Called back by the worker!\n");
+};
+
+ +

Alternativamente, puedes usar addEventListener() :

+ +
+
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.
+
+ +

La Línea 1 en  este ejemplo crea un nuevo worker (worker thread). La Línea 3 configura un manejador de eventos (listener) para encargarse de los eventos message 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 (worker thread).

+ +
Nota : La URI pasada como parámetro del constructor de Worker debe obedecer la política same-origin policy . 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.
+ +

Pasando datos

+ +

Los datos pasan entre la página principal y los workers son copiados, 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 no comparten la misma instancia, 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 structured cloning.

+ +

Antes de continuar, vamos a crear con fines didácticos una función llamada emulateMessage() que simulará el comportamiento de un valor el cual es clonado y no compartido durante el paso desde un worker a la página principal o viceversa:

+ +
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
+ +

A Un valor que es clonado y no compartido se denomina mensaje. De vuelta con los workers, los mensajes pueden ser enviados hacia y desde el hilo principal empleando postMessage(). Los eventos de mensaje {{domxref("MessageEvent.data", "data")}} atributo contienen datos devueltos desde el worker.

+ +

example.html: (la página principal):

+ +
var myWorker = new Worker("my_task.js");
+
+myWorker.onmessage = function (oEvent) {
+  console.log("Worker said : " + oEvent.data);
+};
+
+myWorker.postMessage("ali");
+ +

my_task.js (el worker):

+ +
postMessage("I\'m working before postMessage(\'ali\').");
+
+onmessage = function (oEvent) {
+  postMessage("Hi " + oEvent.data);
+};
+ +
Note: Como siempre, los hilos en segundo plano -incluyendo workers- no pueden manipular el DOM. 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.
+ +

The structured cloning algorithm can accept JSON and a few things that JSON can't like circular references.

+ +

Ejemplos pasando datos

+ +

Example #1: Crear un "eval() asíncrono" genérico

+ +

El siguiente ejemplo muestra como usar un worker para ejecutar asíncronamente cualquier tipo de código en Javascript a traves de eval dentro del worker:

+ +
// 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
+    });
+  };
+
+})();
+ +

Ejemplo de uso:

+ +
// 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})()");
+ +

Ejemplo #2: Paso avanzado de JSON Data y creación de un sistema de conmutación

+ +

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.

+ +

example.html (the main page):

+ +
<!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>
+ +

my_task.js (el worker):

+ +
// 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);
+  }
+};
+ +

Es un método posible para conmutar el contenido de cada mensaje de cada mainpage-worker y viceversa.

+ +

Pasando datos mediante transferencia de propiedades (objetos transferibles)

+ +

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, objetos que implementan la interfaz {{domxref("Transferable")}}. 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.

+ +
// 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]);
+
+ +

Para más información sobre los objetos transferibles, visita HTML5Rocks .

+ +

Spawning subworkers

+ +

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.

+ +

Subworkers are currently not supported in Chrome. See crbug.com/31666 .

+ +

Embedded workers

+ +

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 src attribute and has a type 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:

+ +
<!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>
+ +

The embedded worker is now nested into a new custom document.worker property.

+ +

Tiempos fuera e intervalos

+ +

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.

+ +

Ver setTimeout() , clearTimeout() , setInterval() , y clearInterval() para más detalles. Ver también: JavaScript Timers.

+ +

Terminating a worker

+ +

If you need to immediately terminate a running worker, you can do so by calling the worker's terminate() method:

+ +
myWorker.terminate();
+ +

The worker thread is killed immediately without an opportunity to complete its operations or clean up after itself.

+ +

Workers may close themselves by calling their own {{ ifmethod("nsIWorkerScope", "close") }} method:

+ +
self.close();
+ +

Manejo de errores

+ +

When a runtime error occurs in worker, its onerror event handler is called.  It receives an event named error which implements the ErrorEvent 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 preventDefault() method.

+ +

The error event has the following three fields that are of interest:

+ +
+
message
+
A human-readable error message.
+
filename
+
The name of the script file in which the error occurred.
+
lineno
+
The line number of the script file on which the error occurred.
+
+ +

Accediendo al objeto navigator

+ +

Los workers pueden acceder al objeto navigator, 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:

+ + + +

Importing scripts and libraries

+ +

Worker threads have access to a global function, importScripts() , 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:

+ +
importScripts();                        /* imports nothing */
+importScripts('foo.js');                /* imports just "foo.js" */
+importScripts('foo.js', 'bar.js');      /* imports two scripts */
+
+ +

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, NETWORK_ERROR 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 after the importScripts() method are also kept, since these are always evaluated before the rest of the code.

+ +
Note: Scripts may be downloaded in any order, but will be executed in the order in which you pass the filenames into importScripts() .  This is done synchronously; importScripts() does not return until all the scripts have been loaded and executed.
+ +

Examples

+ +

This section provides several examples of how to use DOM workers.

+ +

Performing computations in the background

+ +

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.

+ +

The JavaScript code

+ +

The following JavaScript code is stored in the "fibonacci.js" file referenced by the HTML in the next section.

+ +
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);
+  }
+ };
+ +

The worker sets the property onmessage  to a function which will receive messages sent when the worker object's  postMessage() is called.  (Note that this differs from defining a global variable of that name, or defining a function with that name.   var onmessage and function onmessage 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.

+ +

The HTML code

+ +
<!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>
+
+ +

The web page creates a div element with the ID  result , which gets used to display the result, then spawns the worker.  After spawning the worker, the onmessage handler is configured to display the results by setting the contents of the div element, and the onerror handler is set to dump the error message.

+ +

Finally, a message is sent to the worker to start it.

+ +

Try this example .

+ +

Performing web I/O in the background

+ +

You can find an example of this in the article Using workers in extensions .

+ +

Dividing tasks among multiple workers

+ +

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.

+ +

example coming soon

+ +

Creating workers from within workers

+ +

The Fibonacci example shown previously demonstrates that workers can in fact spawn additional workers.  This makes it easy to create recursive routines.

+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Dedicated workers{{CompatChrome(3)}}{{CompatGeckoDesktop(1.9.1)}}{{CompatIE(10)}}{{CompatOpera(10.60)}}{{CompatSafari(4)}}
Shared workers{{CompatChrome(3)}}{{CompatNo}}{{CompatNo}}{{CompatOpera(10.60)}}{{CompatSafari(5)}}
Passing data using structured cloning{{CompatChrome(13)}}{{CompatGeckoDesktop(8)}}{{CompatIE(10)}}{{CompatOpera(11.50)}}{{CompatSafari(5.1)}}
Passing data using  transferable objects17 {{ property_prefix("webkit") }}
+ {{CompatChrome(21)}}
{{CompatGeckoDesktop(18)}}{{CompatNo}}{{CompatOpera(15)}}{{CompatSafari(6)}}
Global {{ domxref("window.URL", "URL") }}10 as webkitURL
+ {{CompatChrome(23)}}
{{CompatGeckoDesktop(21)}}{{CompatIE(11)}}{{CompatOpera(15)}}6 as webkitURL
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Dedicated workers---0.163.5 (1.9.1)---115
Shared workers---{{ CompatNo() }}------------
Passing data using structured cloning---0.168---------
Passing data using  transferable objects---18---------
+
+ +

See also

+ + 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 +--- +

Los objetos FormData le permiten compilar un conjunto de pares clave/valor para enviar mediante XMLHttpRequest. 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 submit() del formulario para enviar los datos si el tipo de codificación del formulario se establece en "multipart/form-data".

+ +

Creación de un objeto FormData desde cero

+ +

Usted mismo puede construir un objeto FormData instanciándolo y después añadiendo campos a la instancia usando su método  append() , tal y como se muestra:

+ +
var formData = new FormData();
+
+formData.append("username", "Groucho");
+formData.append("accountnum", 123456); // number 123456 is immediately converted to string "123456"
+
+// HTML file input user's choice...
+formData.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([content], { type: "text/xml"});
+
+formData.append("webmasterfile", blob);
+
+var request = new XMLHttpRequest();
+request.open("POST", "http://foo.com/submitform.php");
+request.send(formData);
+
+ +
Nota: 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 FormData.append() (el valor del campo puede ser un {{ domxref("Blob") }}, {{ domxref("File") }}, o una cadena de texto; si el valor no es ni un Blob, ni un File, será convertido a un string).
+ +

Este ejemplo construye una instancia de FormData que almacenará los valores de los campos "username", "accountnum", "userfile" y "webmasterfile", entonces usará el método send() de XMLHttpRequest para enviar los datos del formulario. El campo "webmasterfile" es un Blob. Un objeto Blob 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 Blob, y hereda su funcionalidad y la amplía para dar soporte a archivos que estén en el sistema del usuario. Para construir un Blob, puede invocar al constructor del objeto Blob.

+ +

Recuperando un objeto FormData de un formulario HTML 

+ +

Para construir un objeto FormData que contenga los datos de un {{ HTMLElement("form") }} existente, especifique ese elemento form cuando cree el objeto FormData:

+ +
var formData = new FormData(someFormElement);
+
+ +

Por ejemplo:

+ +
var formElement = document.getElementById("myFormElement");
+var request = new XMLHttpRequest();
+request.open("POST", "submitform.php");
+request.send(new FormData(formElement));
+
+ +

También puede añadir datos adicionales al objeto FormData antes de enviarlo. Así:

+ +
var formElement = document.getElementById("myFormElement");
+formData = new FormData(formElement);
+formData.append("serialnumber", serialNumber++);
+request.send(formData);
+ +

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.

+ +

Enviando archivos usando objetos FormData

+ +

También puede enviar archivos usando FormData. Simplemente incluye un elemento {{ HTMLElement("input") }} de tipo {{ domxref("File") }}:

+ +
<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>
+
+ +

Luego puede enviarlo usando código como el siguiente:

+ +
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);
+
+ +
+

Nota: el método especificado en el formulario será usado por encima del método utilizado en en la llamada a open().

+
+ +

También puede añadir un {{ domxref("File") }} o un {{ domxref("Blob") }} directamente al objeto {{ domxref("XMLHttpRequest/FormData", "FormData") }} de la siguiente manera:

+ +
data.append("myfile", myBlob, "filename.txt");
+
+ +

Cuando se usa el método append es posible usar, de manera opcional, un tercer parámetro para pasarle un nombre de fichero dentro de la cabecera Content-Disposition que será enviada al servidor. Cuando no se especifica (o el parámetro no es soportado), el nombre "blob" es el que será utilizado.

+ +

Además, puede usar FormData con jQuery si asigna las opciones correctas:

+ +
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
+});
+
+ +

Envío de formularios y carga de archivos vía AJAX sin  objetos FormData

+ +

Si quiere saber cómo serializar y enviar vía AJAX un formulario sin utilizar objetos FormData, por favor leer este párrafo .

+ +

Vea también

+ + -- cgit v1.2.3-54-g00ecf