2011-10-21 74 views
0

我正在處理我的第一個畫布項目,並且它需要美國的部分貼圖,並且在單擊時以縮放和居中狀態。在HTML5畫布上按比例縮放點的X Y按百分比

我能夠找到繪製國家的X Y點數組,每個狀態都是自己的數組。我需要將這些狀態抽出大於這些維度,所以我引入了一個可變比例來乘以每個點。

我的下一個挑戰是客戶只想要13個狀態被抽出,但沒有放置在彼此之間。 (例如,將俄亥俄州和伊利諾斯州放在畫布上並忽略印第安納州)。我的解決方案是爲每個狀態引入一個固定的X,Y「常量」,在縮放發生後,爲該狀態添加X Y值並使該點能夠繪製。

for (var j = 0; j < state.myPolygons.length; ++j) { 
    context.beginPath(); 
    context.lineWidth = lineWidth; 
    context.strokeStyle = stateStroke; 
    context.fillStyle = stateFill; 
    for (var k = 0; k < state.myPolygons[j].myXVals.length; ++k) { 
     var x = parseFloat(state.myPolygons[j].myXVals[k]*state.scale)+state.posX; 
     var y = parseFloat(state.myPolygons[j].myYVals[k]*state.scale)+state.posY; 
     y = canvas.height - y; 
     if (k == 0) 
      context.moveTo(x,y); 
     else 
      context.lineTo(x,y); 
    } 
    context.closePath(); 
    context.fill(); 
    context.stroke(); 
} 

點擊一個狀態,並增長它並以畫布爲中心的效果是通過定義一個目標比例和步數來完成的。我得到了目標尺度和當前尺度之間的差異,並將其除以步驟的數量,以確定在每個「幀」處要增加多少狀態的尺度。例如:俄亥俄州的初始比例是發現的座標的1.97。我的俄亥俄州規模目標是3.75%。我得到差異(1.78),並將其除以45(所定義的一組步驟)來繪製。這給了我0.039作爲我的規模在每一幀的增量。然後我循環,而我的狀態當前比例小於目標比例。然而,由於我需要操縱渲染的X Y,我還需要爲每個狀態添加一個zoomx和zoomy常數,並將其添加到計算的X Y中,以便它可以「滑動」到畫布中心。

所有這些都很完美,我的加利福尼亞州從左到右縮放/滑動,俄亥俄州從右向左滑動等。---這是我的問題。

我有一系列的點來表示客戶在這個州的折扣。這些簡單的X Ys我畫了一個圓圈。地圖的初始渲染包括循環遍歷每個狀態位置集。我申請相同的比例因子,以及POSX,波西變量有關調整點的最終配售給國家

for (var loc in state.Locations) { 
    var locx = parseFloat(state.Locations[loc].x*state.scale)+state.posX 
    var locy =parseFloat(state.Locations[loc].y*state.scale)+state.posY; 
    var txt=state.Locations[loc].text; 
    var lnk=state.Locations[loc].link; 
    context.beginPath(); 
    context.arc(locx,locy,locationSize,0,Math.PI*2,true); 
    context.fillStyle = locationFill; 
    context.closePath(); 
    context.fill(); 
    context.stroke();       
} 

的最終渲染當狀態然而變焦,對於點縮放邏輯失敗。對於給定幀的狀態規模應用

x = parseFloat(activeState.myPolygons[j].myXVals[k]*activeState.scale)+activeState.posX; 
y = parseFloat(activeState.myPolygons[j].myYVals[k]*activeState.scale)+activeState.posY; 

當我將此運用到國家指定的位置,

locx = parseFloat(activeState.Locations[loc].x*activeState.scale)+activeState.posX; 
locy = parseFloat(activeState.Locations[loc].y*activeState.scale)+activeState.posY; 

我結束了X相當密切關注,但在俄亥俄州的例子,在Y在佛羅里達附近。像加利福尼亞州這樣的其他州甚至更糟糕,他們的點開始更多地「疊」在一起,最後更多地「彼此分開」。

我想弄清楚需要增長和縮小XY位置相對於當前的國家規模的位置的三角函數,並保持它的狀態通過相同的路徑動畫(放大和縮小)。

我來這裏之前的最後一次嘗試是獲取位置的初始X Y,並將它的距離與狀態數組的最後X Y進行比較。我試圖找到連接這兩點的線的角度,然後使用所有這些來縮放。我仍然覺得我可能會用這種方法來解決問題,但我無法做到這一點。

謝謝大家在百忙之中閱讀本文時,我任何並欣賞你的幫助可以提供

+0

您是否考慮過使用SVG?所有這些縮放和動畫都內置在SVG中。 – robertc

+0

非常感謝,不幸的是這個項目已經對這些功能產生了影響,現在我走得太遠了。最初是將狀態描繪爲「小」,然後是「大」 - 將動畫放置在目標中間的某個位置。我選擇帆布作爲獲得原始目標的機會,現在我面臨着比我想要的更多的經驗:-) – DHall

回答

0

你可以只是看我把你的辦公桌上,在一個與它的公式紙張。但是,SVG對於項目來說會更加優化,因爲您可以使用g標籤輕鬆地將所有東西組合在一起,然後可以縮放整個組。

但是,由於此時您不得不使用畫布,因此您必須按比例縮放導演,使用trig指定起點與位置點之間的角度,並從左邊或右邊的差異原始距離。我會用實際的方程式更詳細地解釋,當你讓我把那張紙給我的時候。但是,您現在唯一需要修改的行是:

locy = parseFloat(activeState.Locations[loc].y*activeState.scale)+activeState.posY;