Javascript画布运动



我的画布上有这个动作:Gif

我正试着移动除了黑灰色方块以外的所有东西。我试了很多次,但我不知道如何得到我需要的结果,轮换是这样的:

ctx.translate(x, y);
if (or == 'R') {
ctx.rotate(Math.PI / movementSpeed);
}
else if (or == 'L'){
ctx.rotate(-Math.PI / movementSpeed);
}
ctx.translate(-x, -y);
drawRect();
drawRect2();
drawCircle();

我试图不移动的黑灰色方块是这样做的:

function drawRect() {
ctx.fillStyle = "#393939";
ctx.fillRect(x-35, y-30, 180, 60);
ctx.stroke();
ctx.fill();
ctx.restore();
}

代码片段:

<!DOCTYPE html>
<html lang="en">
<head>
<style type="text/css">
@import url('https://fonts.googleapis.com/css2?family=Jost:wght@500&display=swap');
body
{
overflow: hidden;
}
div#cerradura {
position: absolute;
width: 100%;
left:5%;
text-align: center;
font-size: 18px;
}
</style>
</head>
<body>
<div onclick="" id="cerradura">
<canvas id="myCanvas" width="1600" height="800">

</canvas>
</div>
</body>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
let tensorAdentro = false;
let movimiento = 500;
let rotacion = 0;
let x = 1100;
let y = 400;

function dibujarGanzua() {
// Ganzúa
ctx.lineWidth = 7;
ctx.strokeStyle = "#595959";
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x, y+190);
ctx.stroke();
ctx.restore();
}
function dibujarManija() {
// Rectangulo de la cerradura
ctx.fillStyle = "#393939";
ctx.fillRect(x-35, y-30, 180, 60);
ctx.stroke();
ctx.fill();
ctx.restore();
}
function dibujarCerradura() {
ctx.strokeStyle = "#000000";
// Circulo de la cerradura
ctx.fillStyle = '#909090';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(x, y, 20, 0, 2 * Math.PI);
ctx.stroke();
ctx.fill();
ctx.restore();
// Hueco de la cerradura
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(x-10, y);
ctx.lineTo(x+10, y);
ctx.stroke();
ctx.restore();
}
function girarGanzua(or) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.translate(x, y);
if (or == 'R') {
ctx.rotate(Math.PI / movimiento);
rotacion += (((Math.PI / movimiento)*180)/Math.PI);
}
else if (or == 'L'){
ctx.rotate(-Math.PI / movimiento);
rotacion += (-((Math.PI / movimiento)*180)/Math.PI);
}
ctx.translate(-x, -y);
dibujarManija();
dibujarCerradura();
dibujarGanzua();
}

window.addEventListener('mousedown', (e) => {
if (!tensorAdentro && e.button === 0) {
dibujarGanzua();
tensorAdentro = !tensorAdentro;
}
});
// Lee input de mouse
var direction = "",
oldx = 0,
mousemovemethod = function (e) {
dx = e.clientX - oldx;
if (dx < 0 && tensorAdentro) {
if (rotacion <= 90) {
girarGanzua('R')
}
}
else if (dx > 0 && tensorAdentro){
if (rotacion > 0) {
girarGanzua('L')
}
}
oldx = e.clientX;
}
document.addEventListener('mousemove', mousemovemethod);
dibujarManija();
dibujarCerradura();
</script>
</html>

我怎样才能做到这一点?谢谢

这里发生的情况是,上下文在每次鼠标移动时都会旋转,而不会恢复到原始状态。最好在绘制之前保存上下文,并在绘制完成后恢复上下文。而且,要将其旋转正确的角度,每次只需将其旋转rotacion * Math.PI / 180即可。

function girarGanzua(or) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();      // Save the context
dibujarManija(); // Draw the large Rect before rotating
ctx.translate(x, y);
ctx.rotate(rotacion * Math.PI / 180);
if (or == 'R') {
rotacion += (((Math.PI / movimiento)*180)/Math.PI);
}
else if (or == 'L'){
rotacion += (-((Math.PI / movimiento)*180)/Math.PI);
}
ctx.translate(-x, -y);
dibujarCerradura();
dibujarGanzua();
ctx.restore();   // Restore the context
}

此外,在绘制每个图元后,无需恢复上下文。

工作代码段:

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
let tensorAdentro = false;
let movimiento = 500;
let rotacion = 0;
let x = 200;
let y = 200;
function dibujarGanzua() {
// Ganzúa
ctx.lineWidth = 7;
ctx.strokeStyle = "#595959";
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x, y+190);
ctx.stroke();
//ctx.restore(); No Need
}
function dibujarManija() {
// Rectangulo de la cerradura
ctx.fillStyle = "#393939";
ctx.fillRect(x-35, y-30, 180, 60);
ctx.stroke();
ctx.fill();
//ctx.restore(); No Need
}
function dibujarCerradura() {
ctx.strokeStyle = "#000000";
// Circulo de la cerradura
ctx.fillStyle = '#909090';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(x, y, 20, 0, 2 * Math.PI);
ctx.stroke();
ctx.fill();
//ctx.restore(); No Need
// Hueco de la cerradura
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(x-10, y);
ctx.lineTo(x+10, y);
ctx.stroke();
//ctx.restore(); No Need
}
function girarGanzua(or) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
dibujarManija();
ctx.translate(x, y);
ctx.rotate(rotacion * Math.PI / 180);
if (or == 'R') {
rotacion += (((Math.PI / movimiento)*180)/Math.PI);
}
else if (or == 'L'){
rotacion += (-((Math.PI / movimiento)*180)/Math.PI);
}
ctx.translate(-x, -y);
dibujarCerradura();
dibujarGanzua();
ctx.restore();
}

window.addEventListener('mousedown', (e) => {
if (!tensorAdentro && e.button === 0) {
dibujarGanzua();
tensorAdentro = !tensorAdentro;
}
});
// Lee input de mouse
var direction = "",
oldx = 0,
mousemovemethod = function (e) {
dx = e.clientX - oldx;
if (dx < 0 && tensorAdentro) {
if (rotacion <= 90) {
girarGanzua('R')
}
}
else if (dx > 0 && tensorAdentro){
if (rotacion > 0) {
girarGanzua('L')
}
}
oldx = e.clientX;
}
document.addEventListener('mousemove', mousemovemethod);
dibujarManija();
dibujarCerradura();
@import url('https://fonts.googleapis.com/css2?family=Jost:wght@500&display=swap');
body
{
overflow: hidden;
}
div#cerradura {
position: absolute;
width: 100%;
left:5%;
text-align: center;
font-size: 18px;
}
<div onclick="" id="cerradura">
<canvas id="myCanvas" width="1600" height="800"></canvas>
</div>

最新更新