Logo

Complementos y nuevas tendencias en la programación web

Manuales web avanzados

Por Anyelguti

Este curso forma parte del proyecto Aprende Web

logo

Canvas VIII

Escalado

El método scale()

El escalado es otro de los métodos de transformación. Crea una imagen del canvas a escala, es decir aumenta o disminuye los objetos del canvas en la proporción indicada.

Para escalar un canvas emplearemos el método scale(), que tiene la siguiente sintaxis:

cxt.scale(x,y);

Donde el parámetro x indica la proporción de escalado en el eje X u horizontal, y el parámetro y la proporción de escalado en el eje vertical o Y.

Los parámetros X e Y son números que indican la proporción en que se aumenta o reduce el canvas. Por tanto los números entre 0 y 1 disminuyen el tamaño del canvas, y los números mayores que 1 lo aumentan. El número 1 deja el canvas en el mismo tamaño.

Por ejemplo scale(0.5,1) reduce la anchura del canvas a la mitad, mientras que la altura será la misma. Otro ejemplo: scale(1,2) aquí se conserva la misma anchura, pero la altura será el doble.

El valor 0 hace desaparecer los objetos del canvas a los que afecta. y los valores negativos voltean los objetos como si estuvieran vistos en un espejo.

Al igual que con los otros métodos de transformación, el escalado no afecta al código escrito antes del método, sino sólo a lo escrito después de el. Conviene guardar el estado del canvas mediante save() antes de aplicar el método scale(), ya que de este modo podremos recuperar el estado anterior mediante restore().

Ejemplo de escalado

Planteamiento

Flecha Arriba Flecha Abajo

Vamos a hacer un ejemplo en el que el usuario interactua con el canvas. Unas flechas de arriba y abajo harán de controles para disminuir o aumentar el tamaño de la foto.

foto_coche

Aquí a la derecha tenemos todas las imágenes que necesitamos para crear nuestro ejemplo.

Los controles harán que al pulsar el raton encima de ellos la imagen aumente o disminuya. Debemos poner dos tipos de control, uno para el escalado en horizontal y otro para el vertical. Los escalados irán desde 1 hasta -1, por lo que permitirá voltear la imagen con valores negativos.

Por último también pondremos dos botones para voltear la imagen (efecto espejo), uno para el volteo horizontal, y otro para el vertical.

Códigos HTML y CSS

Empezamos por el código HTML. En el crearemos un banner o div donde además del canvas incluiremos los controles.

<div id="marco">
   <canvas id="micanvas" width="300" height="200">
   </canvas>
   <div id="hor">
      <span class="texto">Horizontal:</span>
      <img src="objetos/flechaArriba.gif" alt="x+" id="arribax" 
           onmousedown="subex()" onmouseup="parax1()">
      <div id="escalaX">1.00</div>
      <img src="objetos/flechaAbajo.gif" alt="x-" id="abajox" 
           onmousedown="bajax()" onmouseup="parax2()">
   </div>
   <div id="ver">
      <span class="texto">Vertical:</span>
      <img src="objetos/flechaArriba.gif" alt="y+" id="arribay" 
           onmousedown="subey()" onmouseup="paray1()">
      <div id="escalaY">1.00</div>
      <img src="objetos/flechaAbajo.gif" alt="y-" id="abajoy" 
           onmousedown="bajay()" onmouseup="paray2()">
   </div>
   <div id="voltear">
      <input type="button" onclick="espejo1()" value="Volteo horizontal">
      <input type="button" onclick="espejo2()" value="Volteo vertical">
   </div>
</div>

En el HTML, además del canvas hemos incluido unas líneas que aparecen debajo y que incluyen los controles.

Tanto en las imágenes de las flechas como en los botones input hemos incluido los eventos javascript con el nombre de las funciones que desarrollaremos luego.

En Cada flecha tenemos un evento onmousedown que hará que al mantener pulsado el ratón sobre la flecha el canvas se siga escalando. El evento onmouseup registra que hemos dejado de pulsar el ratón sobre la flecha. y por tanto se para el escalado.

Entre las dos flechas de "subir" y "bajar" hemos puesto un contador que irá cambiando y nos dirá la proporción del escalado que tiene el canvas.

Para completar el banner le aplicamos el código CSS que coloca cada elemento en su sitio y le da estilo:

#marco {  margin: 10px 3em 10px 1em;}
#marco { float: right; border: 1px solid black; width: 300px; height: 300px;}   
canvas { background:#ffffcc  }
#hor, #ver { width: 280px; height: 20px; float: left; margin: 7px  }
#arribax, #abajox, #arribay, #abajoy { 
     float: left; cursor: pointer; width: 18px;}
#escalaX, #escalaY  { width: 60px; heigth:20px; border: 1px solid black;
      float: left; font: bold 14px arial;
      text-align: right; padding-right: 5px; }
.texto { font: bold 16px arial; color: navy; float: left;}
#marco input { font: bold 14px arial }
Horizontal: x+
1.00
x-
Vertical: y+
1.00
y-

De momento tenemos sólo el marco vacío, tal como lo vemos aquí a la derecha. Ahora tenemos que completarlo en javascript con la foto del canvas y las funciones que ponen en marcha los eventos.

javascript del canvas.

Ponemos en primer lugar el código javascript que inicia el canvas e inserta la foto. El en código buscamos también en el DOM los divs de los contadores, los cuales necesitaremos más tarde para que éstos puedan modificarse

window.onload=function() {
cuadrox=document.getElementById("escalaX") //contador eje x
cuadroy=document.getElementById("escalaY") //contador eje y
cxt=iniciaCanvas("micanvas") //buscar contexto canvas.
cxt.beginPath() //nueva ruta
cxt.translate(150,100); //trasladamos el origen al centro del canvas.
coche=new Image(); //nueva imagen para el coche
coche.src="objetos/coche.jpeg";
coche.onload=function() { //insertar la imagen del coche.
   cxt.drawImage(coche,-145,-90);
   }
}

Observa que hemos trasladado el origen al centro del canvas. Esto es así porque el origen es el único punto que se mantiene en su sitio durante el escalado. los demás se acercan o se alejan de él.

a continuación vamos a crear las funciones que controlan el escalado desde los eventos de las flechas. Al mantener pulsado el ratón encima de la flecha (onmousedown), se pondrá en marcha un temporizador que va aumentando o disminuyendo la foto, hasta que al soltar el botón del ratón (onmouseout) éste se para. Para ello utilizamos los métodos de javascript setInterval() y clearInterval(). Empezamos poniendo el código pàra la flecha arriba del eje horizontal, el cual viene comentado. Este código lo ponemos ya fuera de la función window.onload=function():

//variables iniciales:
x=100; //control variación en eje x
y=100; //control variación en eje y
numx=1; //proporción inicial en eje x
numy=1; //proporción inicial en eje y
//aumentar en horizontal:
function subex(){ 
     x1=setInterval(subirx,40);	//ir a función del temporizador:	 
     }
function subirx() { //temporizador: cada 40 ms:
     if (numx<1) { //no aumentar más de 1.
         x+=1; //aumentar en 1 unidad
         if (x==0) {x=1} //evitar el valor 0
         numx= x/100; numx=numx.toFixed(2); //nueva proporción para escalado
         cuadrox.innerHTML=numx; //indicar nueva proporción en marcador.
         mover(numx,numy) //ir a función para variar el tamaño foto.
         }
		  }
function parax1() {	 //al soltar el ratón:
      clearInterval(x1);//parar el temporizador.
			}
//variar tamaño del canvas. nos pasan nuevo tamaño en los parámetros.
function mover(numx,numy) {
      cxt.clearRect(-150,-100,300,200); //borrar foto anterior
      cxt.save(); //salvar estado
      cxt.scale(numx,numy); //escalar en nuevo tamaño
      cxt.drawImage(coche,-145,-90); //insertar la foto
      cxt.restore(); //recuperar estado.
      }	

En primer lugar creamos unas variables inciales que coinciden con el escalado inicial por defecto del canvas.

La función subex() es llamada por el evento al pulsar la flecha. en ella iniciamos el temporizador que está en la función subir().

El temporizador repetirá, mientras no se pare, la función subir(), en la cual cambiamos cada 40ms el valor del tamaño del canvas. Cambiamos ahí el número del contador y ayudados por la función mover() a la que llamamos, primero guardamos el estado del canvas, borramos después la foto del canvas, escalamos con los nuevos valores, y volvemos a poner otra vez la foto; por último recuperamos el estado del canvas.

La función parax1 es la que para el temporizador al soltar el botón del ratón.

El código para la flecha hacia abajo (o disminuir tamaño) en horizontal es muy similar al anterior, ya que creamos también un temporizador que disminuye progresivamente el tamaño del canvas:

//disminuir en horizontal
function bajax(){ 
      x2=setInterval(bajarx,40); //llamar al temporizador
      }
function bajarx() { //temporizador; cada 40 ms:
      if (numx>-1) { //tamaño mínimo: -1
          x-=1; //disminuir una unidad
          if (x==0) {x=-1} //evitar valor 0
          numx= x/100; numx=numx.toFixed(2); //nueva proporción de escalado
          cuadrox.innerHTML=numx; //indicar nueva proporción en marcador
          mover(numx,numy); //ir a función para variar tamaño
          }
       }
function parax2() {	//al soltar el ratón
        clearInterval(x2); //parar el temporizador
        }	

Horizontal: x+
1.00
x-
Vertical: y+
1.00
y-

Estas últimas funciones hacen que al pulsar la flecha "bajar" del contador horizontal la figura disminuya de tamaño. Las funciones son similares a las creadas anteriormente para la flecha "subir"; La anterior función mover() la utilizamos aquí también para cambiar el tamaño del canvas, esta vez disminuyéndolo.

El resultado puedes verlo aquí a la derecha. Donde las flechas "subir" y "bajar" del horizontal, hacen que aumente o disminuya el tamaño de la foto.

Para completar el escalado en vertical, el código que utilizaremos es similar al anterior, ya que utilizaremos también temporizadores que activan y desactivan el escalado. Veamos el código para el escalado en el eje Y o vertical:

//aumentar en vertical
function subey(){
    y1=setInterval(subiry,40) //activar temporizador.
    }
function subiry() { //función temporizador cada 40 ms:
    if (numy<1) { //tamaño máximo: proprocion 1.
        y+=1; //aumentar una unidad
        if (y==0) {y=1} //evitar valor 0
        numy= y/100; numy=numy.toFixed(2); //nueva proporcion de escalado
        cuadroy.innerHTML=numy; //cambiar número de contador
        mover(numx,numy); //ir a función para variar tamañó.
        }
    }
function paray1() {	//al soltar el ratón: 
    clearInterval(y1); //parar el temporizador.
    }	
//disminuir en vertical
function bajay(){ 
    y2=setInterval(bajary,40) //activar temporizador
    }
function bajary() { //función temporizador: cada 40 ms:
    if (numy>-1) { //tamaño mínimo: proporcion -1
        y-=1; //disminuir una unidad
        if (y==0) {y=-1} //evitar valor 0
        numy= y/100; numy=numy.toFixed(2); //nueva proporción de escalado
        cuadroy.innerHTML=numy; //cambiar valor de contador.
        mover(numx,numy); //ir a función para variar tamañó
        }
    }
function paray2() {	//al soltar el ratón: 
    clearInterval(y2); //parar el temporizador.
    }

Ya sólo nos quedan los botones de voltear en horizontal y vertical. Estos botones cambiarán la imagen de forma que el lado izquierdo pasa al derecho y viceversa en horizontal, y la parte superior pasa a la inferior y viceversa en el vertical. Esto se consigue cambiando el signo del valor del escalado, es decir si el valor x u horizontal es positivo lo cambiamos a negativo, y viceversa. Lo mismo haremos con el valor vertical.

Para ello crearemos las funciones espejo1() y espejo2() que están ya relacionadas con los botones mediante el evento onclick. En estas funciones cambiamos de signo las variables relacionadas con el eje horizontal y vertical del escalado, y reinsertamos la imagen. El código javascript es:

function espejo1(){ //volteo horizontal
    cxt.clearRect(-150,-100,300,200); //borrar imagen anterior
    cxt.save(); //salvar estado del canvas
    numx=-numx; //cambiar signo de valor horizontal
    cxt.scale(numx,numy); //escalar con nuevos valores
    cxt.drawImage(coche,-145,-90); //reinsertar imagen.
    x=-x; //cambiar signo a valor de referencia de X
    cuadrox.innerHTML=numx; //cambiar valor en contador
    cxt.restore(); //recuperar estado del canvas.
    } 
function espejo2(){ //volteo vertical
    cxt.clearRect(-150,-100,300,200); //borrar imagen anterior
    cxt.save(); //salvar estado del canvas
    numy=-numy; //cambiar signo valor vertical
    cxt.scale(numx,numy); //escalar con nuevos valores.
    cxt.drawImage(coche,-145,-90); //reinsertar imagen
    y=-y; //cambiar signo a valor de contador
    cuadroy.innerHTML=numy; //cambiar valor en contador
    cxt.restore(); //recuperar estado del canvas.
    }

Horizontal: x+
1.00
x-
Vertical: y+
1.00
y-

El resultado puedes verlo aquí a la derecha.

Para realizar el ejercicio en primer lugar hemos llevado el origen del canvas al centro del recuadro, y hemos puesto la foto de manera que el centro de la foto coincide con el origen del canvas. de esta manera al escalar el canvas, escalamos también la foto de manera que se amplia o reduce lo mismo por los dos lados de la misma.

No sólo hemos visto el uso del método scale(), sino también el uso de los temporizadores para poner en marcha o parar una pequeña animación.

Los métodos setInterval() y clearInterval nos permiten hacer animaciones en javascript, El método crea un bucle en el que la función se repite. El truco para hacer animaciones consiste en ir borrando el dibujo y volverlo a poner ligeramente variado. esto a una gran velocidad produce la sensación de movimiento.






En la siguiente página veremos otro método de transformación: el método transform.

El método transform



Manual Canvas avanzado

Anterior siguiente     Siguiente siguiente

Ver estadísticas

Free counter and web stats
Visita nuestro foro:

Puedes consultar tus dudas y sugerencias:

sobre el foro (info y entrar)

Página creada por ANYELGUTI.

Manda tus sugerencias:
aprendeweb@ymail.com ... manda un correo