el elemento canvas de html5 – animación de un objeto siguiendo un camino

Soy un poco nuevo a la lona y tal así que perdonen si es una pregunta trivial.

Me gustaría ser capaz de animar un objeto siguiendo un camino (que se define como curva path) pero no estoy seguro de cómo hacerlo.

He mirado en Raphael, pero no puedo encontrar la manera de seguir el camino a lo largo del tiempo.

Pastel de JS parecía prometedor en la demo, pero realmente estoy luchando por la documentación, o la falta del mismo en este caso.

Ha alguien tiene algún ejemplo de esto?

InformationsquelleAutor Ben | 2012-02-14

3 Kommentare

  1. 20

    Utilizar el código en mi sitio web de esta pregunta relacionada con la, pero en lugar de cambiar el .style.left y como en la devolución de llamada, borrar y volver a dibujar el lienzo con el elemento en la ubicación nueva (y, opcionalmente, rotación).

    Tenga en cuenta que este utiliza SVG internamente fácilmente interpolar puntos a lo largo de una curva bézier, pero puede utilizar los puntos que te da para lo que quieras (incluyendo dibujo sobre un Lienzo).

    En caso de que mi sitio está abajo, he aquí una instantánea actual de la biblioteca:

    function CurveAnimator(from,to,c1,c2){
      this.path = document.createElementNS('http://www.w3.org/2000/svg','path');
      if (!c1) c1 = from;
      if (!c2) c2 = to;
      this.path.setAttribute('d','M'+from.join(',')+'C'+c1.join(',')+' '+c2.join(',')+' '+to.join(','));
      this.updatePath();
      CurveAnimator.lastCreated = this;
    }
    CurveAnimator.prototype.animate = function(duration,callback,delay){
      var curveAnim = this;
      //TODO: Use requestAnimationFrame if a delay isn't passed
      if (!delay) delay = 1/40;
      clearInterval(curveAnim.animTimer);
      var startTime = new Date;
      curveAnim.animTimer = setInterval(function(){
        var now = new Date;
        var elapsed = (now-startTime)/1000;
        var percent = elapsed/duration;
        if (percent>=1){
          percent = 1;
          clearInterval(curveAnim.animTimer);
        }
        var p1 = curveAnim.pointAt(percent-0.01),
            p2 = curveAnim.pointAt(percent+0.01);
        callback(curveAnim.pointAt(percent),Math.atan2(p2.y-p1.y,p2.x-p1.x)*180/Math.PI);
      },delay*1000);
    };
    CurveAnimator.prototype.stop = function(){
      clearInterval(this.animTimer);
    };
    CurveAnimator.prototype.pointAt = function(percent){
      return this.path.getPointAtLength(this.len*percent);
    };
    CurveAnimator.prototype.updatePath = function(){
      this.len = this.path.getTotalLength();
    };
    CurveAnimator.prototype.setStart = function(x,y){
      var M = this.path.pathSegList.getItem(0);
      M.x = x; M.y = y;
      this.updatePath();
      return this;
    };
    CurveAnimator.prototype.setEnd = function(x,y){
      var C = this.path.pathSegList.getItem(1);
      C.x = x; C.y = y;
      this.updatePath();
      return this;
    };
    CurveAnimator.prototype.setStartDirection = function(x,y){
      var C = this.path.pathSegList.getItem(1);
      C.x1 = x; C.y1 = y;
      this.updatePath();
      return this;
    };
    CurveAnimator.prototype.setEndDirection = function(x,y){
      var C = this.path.pathSegList.getItem(1);
      C.x2 = x; C.y2 = y;
      this.updatePath();
      return this;
    };

    …y he aquí cómo usted puede utilizar:

    var ctx = document.querySelector('canvas').getContext('2d');
    ctx.fillStyle = 'red';
    
    var curve = new CurveAnimator([50, 300], [350, 300], [445, 39], [1, 106]);
    
    curve.animate(5, function(point, angle) {
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        ctx.fillRect(point.x-10, point.y-10, 20, 20);
    });​

    En acción: http://jsfiddle.net/Z2YSt/

    • hmmm, interesante…
    • que realmente funciona con cualquier svg camino… sólo hay que cambiar esto.ruta de acceso.setAttribute a init con un determinado camino..
    • Por supuesto que sí. 🙂 Usted podría estar interesado en esta página de la mina.
    • Bueno, eso es genial
    • solución agradable…
    • Yo iba a votar hasta dos veces si pudiera
    • Gavin, trató de correo electrónico con respecto a su licencia de código en ! [en] phrogz.net pero se mantiene rebotando con no autorizado de relé. hay otra dirección que usted puede ser contactado en?
    • myfirstname en samedomain
    • Yo no sé mucho acerca de las Matemáticas ni; pero usted puede buscar en Google y darse cuenta de que esta solución es ridículo para un simple problema, especialmente si usted está usando canvas. Verificación de la matemática en mi respuesta a continuación.

  2. 8

    Así que, aquí está la versión detallado:

    t ser cualquier número entre 0 y 1 que representa tiempo; la p0, p1, p2, p3 los objetos son los inicio punto, el 1er control punto, el 2º de control de un punto de la punto final respectivamente:

    var at = 1 - t;
    var green1x = p0.x * t + p1.x * at;
    var green1y = p0.y * t + p1.y * at;
    var green2x = p1.x * t + p2.x * at;
    var green2y = p1.y * t + p2.y * at;
    var green3x = p2.x * t + p3.x * at;
    var green3y = p2.y * t + p3.y * at;
    var blue1x = green1x * t + green2x * at;
    var blue1y = green1y * t + green2y * at;
    var blue2x = green2x * t + green3x * at;
    var blue2y = green2y * t + green3y * at;
    var finalx = blue1x * t + blue2x * at;
    var finaly = blue1y * t + blue2y * at;

    Aquí es un balón con el <lienzo> siguiendo un camino en JSfiddle

    Los nombres de las variables que provienen de este gif, que es la mejor explicación para las curvas de bézier: http://en.wikipedia.org/wiki/File:Bezier_3_big.gif

    Una versión corta del código dentro de una función listo para copiar/pegar:

    var calcBezierPoint = function (t, p0, p1, p2, p3) {
        var data = [p0, p1, p2, p3];
        var at = 1 - t;
        for (var i = 1; i < data.length; i++) {
            for (var k = 0; k < data.length - i; k++) {
                data[k] = {
                    x: data[k].x * at + data[k + 1].x * t,
                    y: data[k].y * at + data[k + 1].y * t
                };
            }
        }
        return data[0];
    };


    Cosas relacionadas con:

    • Gracias por esta tarde contribución. Pero no hay necesidad de ser tan arrogante. @phrogz la respuesta es bastante impresionante, y funciona en cualquier ruta.
    • Está muy lejos de impresionante; se utiliza una propiedad de la biblioteca que tienen mucho código por un solo individuo y se utiliza SVG que es la forma más lenta y no es compatible con Android y otros dispositivos. —- Y esto también funciona en cualquier ruta de acceso; sólo cambian los valores de p0, p1, p2 y p3. Usted puede utilizar el primer eslabón en «cosas relacionadas con» si usted necesita ayuda para obtener los números de la derecha.
    • La quiero ver sin lienzo? aquí es: jsfiddle.net/aVwYL/1
    • Gracias. La buena suerte.
    • Necesitamos ayuda gratuita y tenemos que ser humildes hacerlo? Dime todo lo que necesitamos para ser.
    • Gracias por esta muy buena solución y sus ejemplos! Me ayudó mucho
    • Si cambia la primera frase de «Aquí es una respuesta alternativa,» te voy a dar la solución de un +1.
    • He eliminado… pero sólo porque es una buena idea.
    • La función es concisa, y el gif de la wikipedia es super útil!

  3. 1

    Yo no lo uso Lienzo para esto a menos que usted realmente tiene que. SVG ha animación a lo largo de un camino construido en. Lienzo requiere un poco de matemáticas para que funcione.

    He aquí un ejemplo de SVG animación a lo largo de una ruta.

    He aquí una discusión sobre el mismo rafael de: Animación SVG a lo largo de la ruta con Raphael

    Por favor, tenga en cuenta que Raphael utiliza SVG y no el elemento Canvas de HTML5.


    Una manera de animar a lo largo de una curva de ruta de acceso en el Lienzo es continuamente bisecar la curva de bezier, recoring los puntos medios hasta que usted tiene un montón de puntos (es decir, 50 puntos por curva) que puede animar el objeto a lo largo de la lista de puntos. La búsqueda de la bisección beziers y consultas similares para los relacionados con las matemáticas en la eso.

    • Gracias por tu aporte.. la Mayoría de la animación svg ejemplos que me he encontrado mirada torpe …

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...