2012-02-14 15 views
17

के बाद किसी ऑब्जेक्ट को एनिमेट करना मैं कैनवास के लिए थोड़ा नया हूं और अगर यह मामूली सवाल है तो माफ कर दो।एचटीएमएल 5 कैनवास - पथ

मैं पथ (बीज़ियर पथ के रूप में परिभाषित) के बाद किसी ऑब्जेक्ट को एनिमेट करने में सक्षम होना चाहता हूं लेकिन मुझे यकीन नहीं है कि यह कैसे करें।

मैंने राफेल को देखा है लेकिन मैं समय के साथ पथ का पालन कैसे कर सकता हूं, यह नहीं कर सकता।

केक जेएस डेमो में आशाजनक दिख रहा था, लेकिन मैं वास्तव में दस्तावेज में संघर्ष कर रहा हूं, या इस मामले में इसकी कमी है।

क्या किसी को इसका कुछ उदाहरण मिल गया है?

उत्तर

20

कोड on my websitethis related question से उपयोग, लेकिन इसके बजाय कॉलबैक में .style.left और इस तरह बदलने की, मिटाने और नया स्थान (और वैकल्पिक रोटेशन) में आइटम के साथ अपने कैनवास को फिर से आकर्षित।

ध्यान दें कि यह बेजियर वक्र के साथ आसानी से बिंदुओं को आसानी से इंटरपोलेट करने के लिए आंतरिक रूप से एसवीजी का उपयोग करता है, लेकिन आप जो कुछ भी चाहते हैं उसके लिए आपको वह बिंदुओं का उपयोग कर सकते हैं (कैनवास पर चित्रण सहित)।

मामले में मेरी साइट, नीचे है यहाँ पुस्तकालय का एक वर्तमान स्नैपशॉट है:

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

... और यहाँ आप उसका कैसे उपयोग दे सकता है:

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

कार्रवाई में: http://jsfiddle.net/Z2YSt/

+0

hmmmm, दिलचस्प ... – Ben

+0

जो वास्तव में किसी भी svg पथ के साथ काम करता है ... किसी दिए गए पथ के साथ init में इस.path.setAttribute को बदलने की आवश्यकता है .. – Ben

+0

@Ben बेशक यह करता है। :) आपको [मेरा संबंधित पृष्ठ] में दिलचस्पी हो सकती है (http://phrogz.net/svg/convert_path_to_polygon.xhtml)। – Phrogz

1

मैं इसके लिए कैनवास का उपयोग नहीं करता जबतक कि आपको वास्तव में नहीं करना चाहिए। एसवीजी में एक पथ के साथ एनीमेशन है। कैनवास को इसे काम करने के लिए गणित की थोड़ी सी आवश्यकता होती है।

Here's one example of SVG animating along a path

यहाँ राफेल के लिए इसके बारे में कुछ चर्चा है: SVG animation along path with Raphael

कृपया ध्यान दें कि राफेल एसवीजी और नहीं HTML5 कैनवास का उपयोग करता है।


एक तरह से कैनवास में एक बेज़ियर मार्ग के किनारे चेतन करने के लिए लगातार बेज़ियर वक्र द्विभाजित को, मध्य बिन्दुओं recoring जब तक आप अंक (जैसे कि, वक्र प्रति 50 अंक) आप वस्तु के साथ चेतन कर सकते हैं की एक बहुत कुछ है अंक की सूची। उस पर संबंधित गणित के लिए bisecting beziers और इसी तरह के प्रश्नों के लिए खोजें।

+0

आपके इनपुट के लिए धन्यवाद .. svg एनीमेशन उदाहरण के अधिकांश मैंने पाया जा रहा है ... भद्दा – Ben

8

तो, यहां वर्बोज़ संस्करण है:

t 0 और 1 समय का प्रतिनिधित्व करने वाले 0 और 1 के बीच कोई संख्या होने के कारण;

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; 
: p0, p1, p2, p3 वस्तुओं शुरू बिंदु, 1 नियंत्रण बिंदु, 2 नियंत्रण बिंदु एक अंत बिंदु क्रमशः

यहां एक ball using <canvas> following a path in JSfiddle

है

चर के नाम आते हैं इस gif जो से बेज़ियर घटता लिए अच्छी व्याख्या है: http://en.wikipedia.org/wiki/File:Bezier_3_big.gif

कोड का एक लघु संस्करण, एक समारोह कॉपी करने के लिए तैयार/पेस्ट के अंदर:

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



संबंधित सामान:

+1

इस देर से योगदान के लिए धन्यवाद। लेकिन इतनी घमंडी होने की जरूरत नहीं है।@ phrogz का जवाब बहुत बढ़िया है, और किसी भी पथ पर काम करता है। – Ben

+0

बहुत बढ़िया से बहुत दूर है; यह एक मालिकाना पुस्तकालय का उपयोग करता है कि यह एक व्यक्ति द्वारा बहुत अधिक कोड को बचाता है और यह एसवीजी का उपयोग करता है जो धीमा है और एंड्रॉइड और अन्य उपकरणों पर समर्थित नहीं है। ---- और यह किसी भी पथ में भी काम करता है; बस पी 0, पी 1, पी 2 और पी 3 के मानों को बदलें। यदि आपको सही संख्या प्राप्त करने में सहायता की आवश्यकता है तो आप "संबंधित सामान" में पहले लिंक का उपयोग कर सकते हैं। –

+0

इसे कैनवास के बिना देखना चाहते हैं? यहां यह है: http://jsfiddle.net/aVwYL/1/ –

संबंधित मुद्दे