如何解决画布的元素旋转问题
好吧,我实际上无法找到一种方法来使画布旋转的圆居中。
我想将圆的原点与元素 (canna()
) 的原点相同,我尝试过,但效果不佳:
45 = 罐宽;
35 = 油箱高度;
50 = 灰条宽度 (canna());
10 = 灰条高度 (canna());
let c;
let player1;
function startGame() {
map.start();
c = new Console();
player1 = new Tank1();
}
let map = {
canvas: document.getElementById("game"),start: function() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight - 100;
this.context = this.canvas.getContext("2d");
this.interval = setInterval(updateMap,20);
},clear: function() {
this.context.clearRect(0,this.canvas.width,this.canvas.height);
}
}
function floor() {
this.ctx = map.context;
this.ctx.fillStyle = "#3D9970";
this.ctx.fillRect(0,(map.canvas.height - 50),map.canvas.width,50); //floor
}
class Console {
constructor() {
this.alpha = document.getElementById("angle");
}
deg() {
degRange.value = this.alpha.value;
}
}
class Tank1 {
constructor() {
this.colors = ["purple","red","yellow","green"];
this.moves = 3;
this.speedX = 0;
this.speedY = 0;
this.gravity = 0.05;
this.gravitySpeed = 0;
this.x = Math.floor(Math.random() * ((map.canvas.width / 2) - 50) + 50);
this.y = 100;
}
canna() {
let rad = parseInt(c.alpha.value) * Math.PI / 180;
this.ctx = map.context;
//THE PROBLEM IS RIGHT HERE
this.ctx.save();
this.ctx.fillStyle = "gray";
this.ctx.translate((this.x + 20 / 3.5) + 50 / 2,this.y + 10 / 2);
this.ctx.rotate(-rad);
this.ctx.translate(-((this.x + 20 / 3.5) + 50 / 2),-(this.y + 10 / 2));
this.ctx.fillRect((this.x + 22.5),(this.y - 12),50,10);
this.ctx.restore();
}
newPos() {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY + this.gravitySpeed;
this.hitBottom();
}
hitBottom() {
let floorBottom = (map.canvas.height - 50) - 25;
if (this.y > floorBottom) {
this.y = floorBottom;
}
}
update() {
this.canna();
this.ctx = map.context;
this.ctx.fillStyle = this.colors[0];
this.ctx.fillRect((this.x + 8),(this.y - 15),30,16);
this.ctx.fillRect(this.x,this.y,45,25);
}
}
function updateMap() {
map.clear();
floor();
player1.newPos();
player1.update();
}
//CONSOLE
startGame();
let degRange = document.querySelector('.displayAngle')
c.deg();
degRange.addEventListener('input',function() {
if (!check.test(degRange.value)) {
degRange.value = '';
} else {
c.alpha.value = degRange.value;
}
});
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html,body {
font-family: "Lato",sans-serif;
width: 100%;
height: 100%;
}
input[type="range"] {
-webkit-appearance: none;
background: #bdbdbd;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
input[type="range"]:hover {
opacity: 1;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #39CCCC;
cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
width: 25px;
height: 25px;
background: #39CCCC;
cursor: pointer;
}
#game {
display: block;
}
.console {
position: absolute;
display: flex;
bottom: 0;
width: 100%;
height: 100px;
background-color: #DDD;
}
.form-a {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
margin: auto;
}
.form-a>div {
display: flex;
}
.form-a>div>p {
padding-left: 10px;
}
.display {
text-align: center;
width: 50px;
height: 25px;
border: 0;
font-size: 1.2em;
outline-width: 0;
background-color: #DDD;
}
<canvas id="game"></canvas>
<div class="console">
<div class="form-a">
<label>Angolation</label>
<div>
<input id="angle" type="range" oninput="c.deg()" value="0" max="360" />
<input class="display displayAngle" type="text" />
</div>
</div>
</div>
我如何让整个事情居中?
解决方法
这可能是因为您在大炮上设置了 x 和 y 值,并且还试图将大炮平移相同的量。翻译字面意思是将整个画布上绘制的对象移动到您想要的位置。如果您还在对象上设置了 x 和 y,它的移动量将增加两倍。当您翻译时,您几乎是在说将这张画布的 (0,0)(左上角)放在可见画布的 x 和 y 坐标处。很难解释,因为它是一个画布,但可以将其想象为每个绘制的对象都有自己的可以移动和旋转的工作表。
试试这个,看看它是否是你想要做的
this.ctx.save();
this.ctx.fillStyle = "gray";
this.ctx.translate(this.x + 22.5,this.y - 5);
this.ctx.rotate(-rad);
this.ctx.fillRect(0,-5,50,10);
this.ctx.restore();
使用 save()
和 restore()
之后,您无需再翻译对象。我将大炮的 y 值设置为 -5,以便将大炮末端的中心定位在其画布的 (0,0) 上。旋转时,这将确保它从那一端的中心旋转。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。