2013-05-20 387 views
1

說我們有一個帆布:旋轉畫布順時針旋轉90度,並更新寬度高度

<canvas id="one" width="100" height="200"></canvas> 

而上的按鈕點擊畫布被順時針旋轉90度(圍繞中心)和畫布的尺寸也得到更新,所以在某種意義上,它看起來像這樣算賬:

<canvas id="one" width="200" height="100"></canvas> 

注意畫布的ID是一樣的。

想象一下,簡單地順時針旋轉圖像,而不會裁剪或填充圖像。

任何建議之前,我這樣做創建一個新的畫布和逐個像素的像素旋轉和複製的漫長方式?

UPDATE樣品與建議代碼註釋仍然沒有工作:

function imageRotatecw90(){ 

    var canvas = document.getElementById("one"); 
    var context = canvas.getContext("2d"); 

    var cw=canvas.width; 
    var ch=canvas.height; 

    var myImageData = context.getImageData(0,0, cw,ch); 

    context.save(); 

    context.translate(cw/2, ch/2); 
    context.rotate(Math.PI/2); 

    context.putImageData(myImageData, 0, 0); 

    context.restore(); 

    canvas.width=ch; 
    canvas.height=cw; 
} 

FiddleJS

+1

爲什麼通過像素複製像素?爲什麼不把圖像作爲圖像數據抓取,調整畫布大小,旋轉上下文,然後將畫布圖像設置爲之前的圖像數據?這是關於十幾行非常簡單的代碼。 – Stephen

+0

@Stephen我會試試看。希望沒有陷阱。 – zaf

+0

@Stephen我試過使用ImageData,但它沒有做任何改變畫布尺寸的部分 – zaf

回答

8

看這個DEMO

爲了達到演示中看到的效果,我使用了canvas.toDataURL將畫布緩存到圖像中,然後將畫布重新設置爲新尺寸,正確翻譯和旋轉上下文,最後將緩存圖像繪製回修改後的畫布。

通過這種方式,您可以輕鬆地旋轉畫布而無需重新繪製所有內容。但是,由於瀏覽器使用的方法,每次完成此操作時,您都會注意到結果中存在一些模糊現象。如果你不喜歡這種行爲,我唯一能找出的解決方案就是重新繪製一切,追蹤起來更難。

這裏如下代碼:

var canvas = document.getElementById("one"); 
var context = canvas.getContext("2d"); 
var cw = canvas.width; 
var ch = canvas.height; 

// Sample graphic 
context.beginPath(); 
context.rect(10, 10, 20, 50); 
context.fillStyle = 'yellow'; 
context.fill(); 
context.lineWidth = 7; 
context.strokeStyle = 'black'; 
context.stroke(); 

// create button 
var button = document.getElementById("rotate"); 
button.onclick = function() { 
    // rotate the canvas 90 degrees each time the button is pressed 
    rotate(); 
} 

var myImageData, rotating = false; 

var rotate = function() { 
    if (!rotating) { 
     rotating = true;    
     // store current data to an image 
     myImageData = new Image(); 
     myImageData.src = canvas.toDataURL(); 

     myImageData.onload = function() { 
      // reset the canvas with new dimensions 
      canvas.width = ch; 
      canvas.height = cw; 
      cw = canvas.width; 
      ch = canvas.height; 

      context.save(); 
      // translate and rotate 
      context.translate(cw, ch/cw); 
      context.rotate(Math.PI/2); 
      // draw the previows image, now rotated 
      context.drawImage(myImageData, 0, 0);    
      context.restore(); 

      // clear the temporary image 
      myImageData = null; 

      rotating = false;    
     } 
    } 
} 
+0

謝謝你。我設法得到了與你的想法非常相似的工作代碼。我使用輔助畫布來保存像素,而不是使用中間圖像。這避免了onload的複雜性,我的代碼只有5行。 – zaf

+0

不錯。我也是這樣做了一些代碼。使用輔助畫布的另一個優點是可以避免不斷創建圖像對象,從而減少垃圾收集器的操作。 –

1

旋轉

注意它是不是可以旋轉的單個元素。

ctx.save(); 
ctx.rotate(0.17); 

// Clear the current drawings. 
ctx.fillRect() 

// draw your object 
ctx.restore(); 

寬度/高度調節

我曾經發現,正確地顯示比例,屏幕大小等處理的唯一方法:

canvas.width = 20;// DO NOT USE PIXELS 
canvas.height = 40; // AGAIN NO PIXELS 

通知我故意使用canvas.style.widthcanvas.style.height。同樣,對於可調整的畫布,不依賴於CSS或媒體查詢來進行轉換,但由於像素比率的差異,它們令人頭疼。 JavaScript會自動解決這些問題。

更新

您還可以在繪製之前更新的寬度和高度。不知道你想什麼來實現的,但我想這不是一個問題:

Demo here

var canvas = document.getElementById("one"); 
var context = canvas.getContext("2d"); 
var cw = canvas.width; 
var ch = canvas.height; 

canvas.width = 200; 
canvas.height = 400; 

// Sample graphic 
context.beginPath(); 
context.rect(10,10,20,50); 
context.fillStyle = 'yellow'; 
context.fill(); 
context.lineWidth = 7; 
context.strokeStyle = 'black'; 
context.stroke(); 


var myImageData = context.getImageData(0, 0, cw, ch); 

context.save(); 

context.translate(cw/2, ch/2); 
context.putImageData(myImageData, 0, 0); 
context.rotate(0.20); 
+0

謝謝你。我添加了一些不起作用的示例代碼。 – zaf

+0

http://jsfiddle.net/ziqbal/wmyUS/1/ – zaf