JavaScript 控制 canvas 组件,如何设置绕图形中心旋转呢,用rotate()
方法不是绕中心点旋转角度的,接下来,做一个实验看看,自己动手,写好一个能用的方法。
1. 准备一个页面
拟写一个页面,用于实验,代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initcal-scale=1.0"/>
<title>对称图 Symmetric graph</title>
<style>
body{
margin: 0;
}
#box{
width: 100vw;
height: 100vw;
}
.control{
padding: 5px;
}
</style>
</head>
<body>
<div id="box"></div>
<div class="control">
<label>
旋转角度:<input type="range" value="0" id="input1" min="0" max="360" /> <small id="label1">0</small>°
</label>
</div>
<script>
window.onload = () => {
//...
}
</script>
</body>
</html>
2. 编写脚本代码
页面写好了,再写页面的一些脚本代码,把不会实现的方法放在最后写
let box = document.getElementById('box');
let canvas = document.createElement('canvas');
canvas.width=box.offsetWidth;
canvas.height=box.offsetHeight;
let ctx = canvas.getContext('2d');
let pCenter = {
x: canvas.width/2,
y: canvas.height/2,
r: canvas.width/2,
};
ctx.arc(pCenter.x,pCenter.y,pCenter.r*0.02,0,2*Math.PI);
ctx.arc(pCenter.x,pCenter.y,pCenter.r*0.2,0,2*Math.PI);
ctx.stroke();
ctx.beginPath();
let padding = canvas.width*0.2;
ctx.rect(0,0,canvas.width,canvas.height);
ctx.stroke();
ctx.fillStyle = 'rgba(0,0,0,0.2)';
ctx.fillRect(padding,padding,canvas.width-padding*2,canvas.height-padding*2);
let img = new Image();
img.onload = () => {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(img,0,0);
};
img.src = canvas.toDataURL();
box.appendChild(canvas);
const setCenterRotate = (angle) => {
//待实现...
};
const label = document.getElementById('label1');
document.getElementById('input1').addEventListener('change',(e)=>{
label.innerText = e.target.value;
setCenterRotate(parseInt(e.target.value));
})
3. 边修改边观察
需要实现setCenterRotate()
方法体,可试试边改边写,运行浏览器可实时观察效果,如下图所示
最后,观察没问题了,就是自己期望的,最终确认下来,方法体代码如下
//清除之前绘制的
ctx.clearRect(0,0,canvas.width,canvas.height);
//先保存一下设置
ctx.save();
//将画布向右下移动一半宽
ctx.translate(pCenter.r,pCenter.r);
//再旋转角度
ctx.rotate(angle/180*Math.PI);
//最后将画布移回来,摆正之前的位置
ctx.translate(-pCenter.r,-pCenter.r);
//最后画出来
ctx.drawImage(img,0,0);
//不要忘记恢复之前的设置
ctx.restore();