簡體   English   中英

如何旋轉畫布中的對象

[英]How to rotate object in the canvas

我正在嘗試僅旋轉畫布中的一個對象,而不旋轉整個畫布。

我的代碼如下:

 var canvas = document.getElementById('canvas'); var buttons = document.getElementById('buttons'); var img = document.getElementById('photo'); var ctx = canvas.getContext('2d'); var rect = {}; var drag = false; var buttons_shown = false; var angle = 10; var rotate_angle = 0; var original_source = img.src; img.src = original_source; function init() { img.addEventListener('load', function(){ canvas.width = img.width; canvas.height = img.height; canvas.addEventListener('mousedown', mouseDown, false); canvas.addEventListener('mouseup', mouseUp, false); canvas.addEventListener('mousemove', mouseMove, false); document.addEventListener("keydown", keyDownPressed, false); }); } function keyDownPressed(e) { var keyCode = e.keyCode; var left_arrow = 37; var right_arrow = 39; var up_arrow = 38; var down_arrow = 40; if(keyCode === left_arrow) { onRotateLeft() } if(keyCode === right_arrow){ onRotateRight() } } function mouseDown(e) { rect.startX = e.offsetX; rect.startY = e.offsetY; drag = true; buttons_shown = false; buttons.classList.add("hide"); } function mouseUp() { drag = false; buttons_shown = true; } function onRemoveSelectionClick(e) { ctx.clearRect(0, 0, canvas.width, canvas.height); drag = false; buttons_shown = false; buttons.classList.add("hide"); } function onRotateLeft(){ rotate_angle = rotate_angle - angle; canvas.style.transform = 'rotate(' + rotate_angle + 'deg)'; } function onRotateRight(){ rotate_angle = rotate_angle + angle; canvas.style.transform = 'rotate(' + rotate_angle + 'deg)'; } function mouseMove(e) { if (drag) { ctx.clearRect(0, 0, canvas.width, canvas.height); rect.w = (e.pageX - this.offsetLeft) - rect.startX; rect.h = (e.pageY - this.offsetTop) - rect.startY; ctx.shadowBlur = 5; ctx.filter = 'blur(10px)'; ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h); ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h); }else{ if(buttons_shown && buttons.classList.contains("hide")){ buttons.classList.remove("hide"); } } } // init(); 
 .hide{ display: none !important; } canvas{ position: absolute; left: 0; right: 0; top: 0; bottom: 0; display:inline-block; background-color: yellow; } 
 <div style="position: relative; overflow: hidden;display:inline-block;"> <img id="photo" src="http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg"/> <canvas id="canvas"></canvas> </div> <div id="buttons" class="hide"> <button onclick="onRotateLeft()">Rotate Left</button> <button onclick="onRotateRight()">Rotate right</button><br /> <button onclick="onRemoveSelectionClick()">Remove Selection</button> </div> 

因此,如果繪制了一個對象,我將顯示向左或向右旋轉或刪除它的按鈕。 例如,如果我單擊“ Rotate Left按鈕,它將執行下一個代碼:

rotate_angle = rotate_angle - angle;
canvas.style.transform = 'rotate(' + rotate_angle + 'deg)';

但這會旋轉整個畫布(黃色背景),但我只想旋轉畫布內的對象。

任何想法?

使用畫布轉換而不是CSS轉換。

渲染矩形時,需要在畫布上應用變換。

該代碼段是您的代碼副本,但有一些更改。

  • 渲染是通過requestAnimationFrame完成的,以便在鼠標移動時不會產生不必要的渲染。

  • 每當需要更新畫布時,全局標志update均設置為true

  • rectangles數組用於存儲每個矩形。

  • 矩形對象還存儲其旋轉rect.rotate以便每個矩形具有獨立的旋轉。

  • 全局變量rect保存當前矩形。

  • 事件會更改全局rect對象並設置update = true標志,它們不執行任何渲染。

  • 矩形圍繞其中心旋轉

  • 畫布上下文ctx.rotate使用弧度而不是度

請參閱代碼以獲取更多信息。

 var canvas = document.getElementById('canvas'); var buttons = document.getElementById('buttons'); var img = document.getElementById('photo'); var ctx = canvas.getContext('2d'); var rect = {}; var drag = false; var buttons_shown = false; var angle = 10 * (Math.PI / 180) ; var rotate_angle = 0; var update = true; // when true updates canvas var original_source = img.src; img.src = original_source; function init() { img.addEventListener('load', function(){ canvas.width = img.width; canvas.height = img.height; canvas.addEventListener('mousedown', mouseDown, false); canvas.addEventListener('mouseup', mouseUp, false); canvas.addEventListener('mousemove', mouseMove, false); document.addEventListener("keydown", keyDownPressed, false); }); // start the rendering loop requestAnimationFrame(updateCanvas); } // main render loop only updates if update is true function updateCanvas(){ if(update){ drawCanvas(); update = false; } requestAnimationFrame(updateCanvas); } // array of rectangles const rectangles = []; // adds a rectangle function addRectangle(rect){ rectangles.push(rect); } // draws a rectangle with rotation function drawRect(rect){ ctx.setTransform(1,0,0,1,rect.startX + rect.w / 2, rect.startY + rect.h / 2); ctx.rotate(rect.rotate); ctx.beginPath(); ctx.rect(-rect.w/2, -rect.h/2, rect.w, rect.h); ctx.fill(); ctx.stroke(); } // clears canvas sets filters and draws rectangles function drawCanvas(){ // restore the default transform as rectangle rendering does not restore the transform. ctx.setTransform(1,0,0,1,0,0); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.shadowBlur = 5; ctx.filter = 'blur(10px)'; rectangles.forEach(drawRect); } function keyDownPressed(e) { var keyCode = e.keyCode; var left_arrow = 37; var right_arrow = 39; var up_arrow = 38; var down_arrow = 40; if(keyCode === left_arrow) { onRotateLeft() } if(keyCode === right_arrow){ onRotateRight() } } // create new rect add to array function mouseDown(e) { rect = { startX : e.offsetX, startY : e.offsetY, w : 1, h : 1, rotate : 0, }; drag = true; buttons_shown = false; buttons.classList.add("hide"); addRectangle(rect); update = true; } function mouseUp() { drag = false; buttons_shown = true; update = true; } // removes top rectangle and sets next down as current or if none then hides controls function onRemoveSelectionClick(e) { rectangles.pop(); if(rectangles.length === 0){ drag = false; buttons_shown = false; buttons.classList.add("hide"); }else{ rect = rectangles[rectangles.length -1]; } update = true; } // rotate current rectangle function onRotateLeft(){ rect.rotate -= angle; update = true; } function onRotateRight(){ rect.rotate += angle; update = true; } function mouseMove(e) { if (drag) { rect.w = (e.pageX - this.offsetLeft) - rect.startX; rect.h = (e.pageY - this.offsetTop) - rect.startY; update = true; }else{ if(buttons_shown && buttons.classList.contains("hide")){ buttons.classList.remove("hide"); } } } // init(); 
 .hide{ display: none !important; } canvas{ position: absolute; left: 0; right: 0; top: 0; bottom: 0; display:inline-block; background-color: yellow; } 
 <div style="position: relative; overflow: hidden;display:inline-block;"> <img id="photo" src="http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg"/> <canvas id="canvas"></canvas> </div> <div id="buttons" class="hide"> <button onclick="onRotateLeft()">Rotate Left</button> <button onclick="onRotateRight()">Rotate right</button><br /> <button onclick="onRemoveSelectionClick()">Remove Selection</button> </div> 

您將需要一個單獨的畫布作為對象。 在此單獨的畫布上繪制對象,然后根據您的實際意圖執行以下操作:

  • 使用context.rotate()結合context.drawImage()在主畫布上繪制輔助畫布的內容;
  • 使用CSS在一個畫布上覆蓋另一個畫布。

再說一次,也許您可​​以只使用context.rotate()然后在主畫布上進行繪制,如下所示: HTML5 Canvas Rotate Image

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM