我试图仅在画布中旋转一个对象,而不是整个画布。
我的代码如下:
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>
&#13;
因此,如果绘制了一个对象,我会显示按钮向左或向右旋转或删除它。如果我单击例如Rotate Left
按钮,它将执行下一个代码:
rotate_angle = rotate_angle - angle;
canvas.style.transform = 'rotate(' + rotate_angle + 'deg)';
但是这会旋转我的整个画布(黄色背景),但我想只旋转画布内的对象。
有什么想法吗?
答案 0 :(得分:1)
渲染矩形时,需要在画布中应用变换。
该代码段是代码的副本,但有一些更改。
渲染是通过requestAnimationFrame
完成的,以便在鼠标移动时不会有不必要的渲染。
只要需要更新画布,全局标记update
就会设置为true
。
rectangles
数组用于存储每个矩形。
矩形对象还存储其旋转rect.rotate
,以便每个矩形都有一个独立的旋转。
全局变量rect
包含当前矩形。
事件更改全局rect
对象并设置update = true
标志,它们不进行任何渲染。
矩形围绕其中心旋转
Canvas context 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();
&#13;
.hide{
display: none !important;
}
canvas{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display:inline-block;
background-color: yellow;
}
&#13;
<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>
&#13;
答案 1 :(得分:0)
对象需要一个单独的画布;在这个单独的画布上绘制对象然后,根据您实际打算做什么,您可以:
context.rotate()
结合context.drawImage()
; 然后,也许您可以使用context.rotate()
然后在主画布上绘制,如下所示:HTML5 Canvas Rotate Image