[英]How to rotate object in the canvas
I'm trying to rotate only one object in the canvas, not the whole canvas. 我正在尝试仅旋转画布中的一个对象,而不旋转整个画布。
My code is as follows: 我的代码如下:
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>
Thus, if an object is drawn, I show the buttons to rotate it left or right or to delete it. 因此,如果绘制了一个对象,我将显示向左或向右旋转或删除它的按钮。 If I click on for example
Rotate Left
button, it executes the next code: 例如,如果我单击“
Rotate Left
按钮,它将执行下一个代码:
rotate_angle = rotate_angle - angle;
canvas.style.transform = 'rotate(' + rotate_angle + 'deg)';
But that rotates my whole canvas (yellow background) but I want to rotate only the object inside the canvas. 但这会旋转整个画布(黄色背景),但我只想旋转画布内的对象。
Any idea? 任何想法?
You need to apply the transform in the canvas when you render the rectangle. 渲染矩形时,需要在画布上应用变换。
The snippet is a copy of your code with some changes. 该代码段是您的代码副本,但有一些更改。
The rendering is done via requestAnimationFrame
so as not to have needless renders when the mouse moves. 渲染是通过
requestAnimationFrame
完成的,以便在鼠标移动时不会产生不必要的渲染。
A global flag update
is set to true
whenever there is need to update the canvas. 每当需要更新画布时,全局标志
update
均设置为true
。
An array of rectangles
is used to store each rectangle. rectangles
数组用于存储每个矩形。
The rectangle object also stores its rotation rect.rotate
so that each rectangle has an independent rotation. 矩形对象还存储其旋转
rect.rotate
以便每个矩形具有独立的旋转。
The global variable rect
holds the current rectangle. 全局变量
rect
保存当前矩形。
Events change the global rect
object and set the update = true
flag, they do not do any rendering. 事件会更改全局
rect
对象并设置update = true
标志,它们不执行任何渲染。
The rectangle is rotated about its center 矩形围绕其中心旋转
Canvas context ctx.rotate
uses radians not degrees 画布上下文
ctx.rotate
使用弧度而不是度
See code for more info. 请参阅代码以获取更多信息。
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>
You will need a separate canvas for the object; 您将需要一个单独的画布作为对象。 draw the object on this separate canvas and then, depending on what you actually intend to do, you can either:
在此单独的画布上绘制对象,然后根据您的实际意图执行以下操作:
context.rotate()
combined with context.drawImage()
; context.rotate()
结合context.drawImage()
在主画布上绘制辅助画布的内容; Then again, perhaps you could just use context.rotate()
then draw on the main canvas as cited in: HTML5 Canvas Rotate Image 再说一次,也许您可以只使用
context.rotate()
然后在主画布上进行绘制,如下所示: HTML5 Canvas Rotate Image
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.