2016-01-02 149 views
0

我從用戶的網絡攝影機拍攝照片並在畫布上繪製。我使用CSS構建了視頻控件,例如縮放視頻,旋轉視頻,左右移動。它在直播中應用,但是當我在Canvas上拍照和畫畫時,這些功能(旋轉,縮放)不適用。 我知道,因爲我沒有改變帆布,這就是爲什麼它不適用。在畫布上繪製CSS轉換(比例,旋轉,左,右)

因此,任何想法如何使用相同的CSS代碼在畫布上繪製[旋轉,縮放,左移/右移]。 (或者可能是Canvas上下文特有的代碼)。

+0

查看html2canvas腳本https://html2canvas.hertzen.com。 –

+0

嗨@DariuszSikorski,不是添加許多scripts.libraries的忠實粉絲。 :) –

回答

0

轉換變得簡單。

不幸的是,給定的答案沒有描述正確使用比例,平移和旋轉函數。這些函數乘以現有的變換,因此結果是相對而非絕對的。例如從默認的轉換

ctx.setTransform(1, 0, 0, 1, 0, 0); // set the transformation to the default identity matrix 
ctx.scale(2, 2); // scale the transform. Objects are now drawn 2 time larger 
ctx.scale(2, 2); // This is applied to the existing scale 
        // objects are now draw 4 times as large not 2 times 
ctx.rotate(Math.PI/2); // rotate the transformation 90 deg clockwise 
         // objects are drawn with the x axis down the screen 
ctx.rotate(Math.PI/2); // Rotate a further 90 deg clockwise 
         // objects are drawn with the x axis from right to left 
         // and the y axis moves up 

ctx.translate(x, y)功能也是相對的,更復雜,因爲您提供由現有的改造轉化的座標,以鍛鍊身體。因此,如果在上述代碼之後應用100平移100的翻譯將首先縮放並旋轉4和180度。結果位置將位於畫布座標x:-400和y:-400處。要翻譯成所需的座標(100,100)將需要首先應用逆變換,這將導致ctx.translate(-25, -25)

因爲無法確定地知道當前變換,所以計算逆變換是非常困難的並且應用這一點,以便您可以在畫布座標中工作。

的setTransform

並非一切都失去了畫布2D API提供了一個功能ctx.setTransform()其替換爲新的一個當前變換。這不是相對的,而是絕對的。這使您可以確定地瞭解當前的轉換並大大簡化轉換圖像(或任何正在繪製的圖像)的過程。

通用功能。

要在這裏旋轉縮放和定位圖像是一個通用功能,爲您做到這一點。

的爭論

  • CTX:該2D畫布上下文提請。
  • 圖片:要繪製的圖像。
  • x,y:絕對畫布座標,放置中心 座標爲,以畫布左上角的像素爲單位度量。
  • centerX,centerY:以像素爲單位的圖像原點座標相對於協調的圖像。如果圖像是100乘100,那麼將centerX,centerY設置爲50,50將縮放並圍繞圖像中心旋轉,並將該中心繪製在由參數x和y給定的座標處。如果centerX,centerY被賦值爲0,0,則圖像將圍繞左上角進行旋轉和縮放。
  • 比例尺:繪製圖像的比例。 1的值不是刻度,2是 的兩倍大0.5是一半的大小。負數REVERS在x圖像 和y方向
  • 旋轉:以弧度0是沒有 旋轉和給出的旋轉量,然後在90度步驟順時針是Math.PI/2Math.PIMath.PI * 1.5,並返回到啓動Math.PI * 2

它能做什麼

的功能設置與所需的規模和T是絕對轉型ranslation。將旋轉應用於該變換,然後繪製圖像偏移以將centerX,centerY放置在所需座標處。最後,函數將轉換設置回默認值。如果對所有轉換使用函數或setTransform,則這是絕對不需要的,但是我已經將它添加到80%的現有代碼中,而這些代碼依賴於當前的默認轉換。

函數源代碼。

function drawImage(ctx, image, x, y, centerX, centerY, scale, rotate){ 
    ctx.setTransform(scale, 0, 0, scale, x, y); // resets transform and 
               // set scale and position 
    ctx.rotate(rotate); // apply the rotation to the above transformation 
    ctx.drawImage(image, -centerX, -centerY); // draw the image offset to its center 
    ctx.setTransform(1, 0, 0, 1, 0, 0); // restore the transformation to default. 
} 

還是簡化版本,不做不必要的重置爲默認轉換

function drawImage(ctx, image, x, y, centerX, centerY, scale, rotate){ 
    ctx.setTransform(scale, 0, 0, scale, x, y); // resets transform and 
               // set scale and position 
    ctx.rotate(rotate); // apply the rotation to the above transformation 
    ctx.drawImage(image, -centerX, -centerY); // draw the image offset to its center 
} 

或者這是假設你一直使用的圖像中心

function drawImageCentered(ctx, image, x, y, scale, rotate){ 
    ctx.setTransform(scale, 0, 0, scale, x, y); // resets transform and 
               // set scale and position 
    ctx.rotate(rotate); // apply the rotation to the above transformation 
    ctx.drawImage(image, -image.width/2, -image.height/2); // draw the image offset to its center 
} 

使用

// image; is a 200 by 200 pixel image 
// ctx; is the canvas 2D context 
// canvas; is the canvas element 

// call the function 
drawImage(
    ctx,   // the context 
    image,  // the image to draw 
    canvas.width/2, canvas.height/2, //draw it at the center of the canvas 
    image.width/2, image.height/2, // at the image center 
    2,   // scale to twice its size 
    Math.PI/4 // and rotated clockwise 45 deg 
); 
+0

謝謝@ blindman67 ... –

0

你不能通過CSS來做到這點,但是在繪製到畫布上時有一些javascript。對於縮放,您需要半手動處理它,使用canvas.getContext()上下文中的參數drawImage。基本上參數2-5是從中提取圖像的區域(按順序),x,y,寬度和高度,參數6-9與圖像的放入方式相同。

因此,舉例來說,如果你的基礎圖像是2000×2000,你是成像成畫布是1000×1000:

下面將剛剛繪製整個圖像到較小的圖像。

var ctx = canvas.getContext("2d"); 
ctx.drawImage(img,0,0,2000,2000,0,0,1000,1000); 

雖然這將繪製基本圖像的中間1000×1000到畫布(即2倍變焦):

var ctx = canvas.getContext("2d"); 
ctx.drawImage(img,500,500,1000,1000,0,0,1000,1000); 

在上文中,跟它,提取(500,500)的區域,以(1500,1500)並將其「打印」到畫布中。

旋轉是一個更多的參與,因爲如果你只是rotate圖像和從畫布的原點(0,0)繪製,圖像將結束在畫布外。您還需要在畫布上執行translate

var ctx = canvas.getContext("2d"); 
ctx.rotate(90 * Math.PI/180); //rotate 90 degrees 
ctx.translate(0, -canvas.height); //translate down the height of the canvas 

OR

var ctx = canvas.getContext("2d"); 
ctx.rotate(180 * Math.PI/180); //rotate 180 degrees 
ctx.translate(-canvas.width,-canvas.height); // translate down and over 

OR

var ctx = canvas.getContext("2d"); 
ctx.rotate(270 * Math.PI/180); //rotate 270 degrees 
ctx.translate(-canvas.width,0); // translate down and over 

注意周圍的左上角發生旋轉。如果你想支持自由旋轉,它會變得更加複雜。

編輯:由於Blindman67在他的評論中正確註釋,轉換適用於基於任何先前應用的轉換的上下文轉換狀態。我更新了代碼示例,以澄清這是在應用於乾淨上下文時沒有應用轉換的轉換的影響。

+0

嗨巴里,謝謝你的答案。雖然,現在我認爲這需要額外的努力。所以,我正在取消控制。我喜歡如何繪製較小的圖像部分。我補充說。感謝您的快速響應。 :) –

+0

@KalpeshSingh - :-) - 這是可以理解的。這有點痛苦。 –

+0

你沒有提到旋轉和翻譯是相對於現有的變換。最後的代碼段完全不正確,第一次旋轉和平移是錯誤的方式,下面的轉換是相對於現有的,註釋並不反映實際的轉換。我只能因爲錯誤而投票,因爲它只會讓人們感到困惑。 – Blindman67