我從用戶的網絡攝影機拍攝照片並在畫布上繪製。我使用CSS構建了視頻控件,例如縮放視頻,旋轉視頻,左右移動。它在直播中應用,但是當我在Canvas上拍照和畫畫時,這些功能(旋轉,縮放)不適用。 我知道,因爲我沒有改變帆布,這就是爲什麼它不適用。在畫布上繪製CSS轉換(比例,旋轉,左,右)
因此,任何想法如何使用相同的CSS代碼在畫布上繪製[旋轉,縮放,左移/右移]。 (或者可能是Canvas上下文特有的代碼)。
我從用戶的網絡攝影機拍攝照片並在畫布上繪製。我使用CSS構建了視頻控件,例如縮放視頻,旋轉視頻,左右移動。它在直播中應用,但是當我在Canvas上拍照和畫畫時,這些功能(旋轉,縮放)不適用。 我知道,因爲我沒有改變帆布,這就是爲什麼它不適用。在畫布上繪製CSS轉換(比例,旋轉,左,右)
因此,任何想法如何使用相同的CSS代碼在畫布上繪製[旋轉,縮放,左移/右移]。 (或者可能是Canvas上下文特有的代碼)。
轉換變得簡單。
不幸的是,給定的答案沒有描述正確使用比例,平移和旋轉函數。這些函數乘以現有的變換,因此結果是相對而非絕對的。例如從默認的轉換
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()
其替換爲新的一個當前變換。這不是相對的,而是絕對的。這使您可以確定地瞭解當前的轉換並大大簡化轉換圖像(或任何正在繪製的圖像)的過程。
通用功能。
要在這裏旋轉縮放和定位圖像是一個通用功能,爲您做到這一點。
的爭論
Math.PI/2
, Math.PI
,Math.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
);
謝謝@ blindman67 ... –
你不能通過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在他的評論中正確註釋,轉換適用於基於任何先前應用的轉換的上下文轉換狀態。我更新了代碼示例,以澄清這是在應用於乾淨上下文時沒有應用轉換的轉換的影響。
嗨巴里,謝謝你的答案。雖然,現在我認爲這需要額外的努力。所以,我正在取消控制。我喜歡如何繪製較小的圖像部分。我補充說。感謝您的快速響應。 :) –
@KalpeshSingh - :-) - 這是可以理解的。這有點痛苦。 –
你沒有提到旋轉和翻譯是相對於現有的變換。最後的代碼段完全不正確,第一次旋轉和平移是錯誤的方式,下面的轉換是相對於現有的,註釋並不反映實際的轉換。我只能因爲錯誤而投票,因爲它只會讓人們感到困惑。 – Blindman67
查看html2canvas腳本https://html2canvas.hertzen.com。 –
嗨@DariuszSikorski,不是添加許多scripts.libraries的忠實粉絲。 :) –