如何在HTML5画布上旋转和滚动到底部背景的图像?

时间:2019-09-10 00:11:18

标签: javascript html canvas

//Green's background canvas
var canvasBG = document.getElementById("canvasBG");
var ctxBG = canvasBG.getContext("2d");

//Machine's canvas (black triangle)
var canvasFG = document.getElementById("canvasFG");
var ctxFG = canvasFG.getContext("2d");

var maquina, background;
var scale = grados = 0;

window.addEventListener("load", ()=>{

  //Setting canvases widths and heights 
  canvasBG.width  = canvasBG.offsetWidth;
  canvasBG.height = canvasBG.offsetHeight;
  canvasFG.width  = canvasFG.offsetWidth;
  canvasFG.height = canvasFG.offsetHeight;

  //Building app's initial state 
  setup();

});

//This code is to execute new coordinates movement pressing enter
$(document).keyup(function(event) {
    if ($(".input1").is(":focus") && event.key == "Enter") {
        maquina.move($("#coord").val().split(",")[0], $("#coord").val().split(",")[1]);
    }
});

function setup(){

  //Setting canva's center coordinates
  let centerX = canvasBG.width/2;
  let centerY = canvasBG.height/2;

  //Building background and machine
  // background = new Background();
  background = new Background('https://i.postimg.cc/cJ8BbZ95/background.png');
  maquina = new Maquina(centerX-15, canvasBG.height-100);

  //Drawing background and machine
  background.draw();
  maquina.draw();

  $("#coord").val(maquina.x+","+maquina.y);
  $("#currPos").text(maquina.x+","+maquina.y);

}

function Background(img){

  //Drawing all attributes
  // this.color1='#2f8a4d';
  // this.color2='#369c58';
  // this.cellSize = 40;
  // this.cellsX = Math.ceil(canvasBG.width/this.cellSize);
  // this.cellsY = Math.ceil(canvasBG.height/this.cellSize);
  // this.rotAngle = 0;
  // this.zoomVal = 0;

  //Loading image by file attributes
  this.imgSRC = img;
  this.img = "";
  this.x = 0;
  this.y = 0;
  this.width = canvasBG.width;
  this.height = canvasBG.height;

  //Drawing all methods
  // this.draw = function (){
  //   for (var i = 0; i <= background.cellsX; i++) {
  //     for (var j = 0; j <= background.cellsY; j++) {
  //
  //       if (i%2 == j%2) {
  //         ctxBG.fillStyle = background.color1;
  //       }else{
  //         ctxBG.fillStyle = background.color2;
  //       }
  //
  //       ctxBG.fillRect(this.cellSize*i, this.cellSize*j, this.cellSize, this.cellSize);
  //     }
  //   }
  // }
  //
  // this.rotate = function (angle){
  //   //Setting new background rotation's angle
  //   background.rotAngle = angle;
  //   //Cleaning canvas
  //   ctxBG.clearRect(0, 0, canvasBG.width, canvasBG.height);
  //   //Moving ctx origin the machine
  //   ctxBG.translate(maquina.x, maquina.y-15);
  //   //ctx rotation
  //   ctxBG.rotate(angle * Math.PI / 180);
  //   //Setting ctx origin to necessary point to draw the whole canvas
  //   let dx = Math.sin(angle)*canvasBG.height;
  //   let dy = Math.sin(angle)*canvasBG.width;
  //   // console.log("dx: "+dx);
  //   // console.log("dy: "+dy);
  //   ctxBG.translate((dx-maquina.x), (dy-(maquina.y-15)));
  //   // console.log("new x: "+(dx-maquina.x));
  //   // console.log("new y: "+(dy-(maquina.y-15)));
  //   canvasBG.width = canvasBG.width + dx/Math.cos(angle);
  //   canvasBG.height = canvasBG.height + dy/Math.cos(angle);
  //   // console.log("width: "+Math.cos(angle)*dx);
  //   // console.log("height: "+Math.cos(angle)*dy);
  //   //Drawing background
  //   background.draw();
  // }
  //
  // this.move = function (x, y){
  //
  // }

  //Loading image by file methods
  this.draw = function (){
    let img = new Image();
    img.src = this.imgSRC;
    img.onload = function(e){
      ctxBG.drawImage(img, this.x, this.y, this.width, this.height);
    }
    this.img = img;
  }

  this.drawBestFit = function (angle) {

    var dist = Math.sqrt(Math.pow(canvasBG.width, 2) + Math.pow(canvasBG.height, 2))
    var diagAngle = Math.asin(canvasBG.height / dist)

    var a1 = ((angle % (Math.PI * 2)) + Math.PI * 4) % (Math.PI * 2)
    if (a1 > Math.PI)
      a1 -= Math.PI
    if (a1 > Math.PI / 2 && a1 <= Math.PI)
      a1 = (Math.PI / 2) - (a1 - (Math.PI / 2))

    var ang1 = Math.PI / 2 - diagAngle - Math.abs(a1)
    var ang2 = Math.abs(diagAngle - Math.abs(a1))

    var scale1 = Math.cos(ang1) * dist / this.img.height
    var scale2 = Math.cos(ang2) * dist / this.img.width

    var scale = Math.max(scale1, scale2)

    var dx = Math.cos(angle) * scale
    var dy = Math.sin(angle) * scale

    ctxBG.setTransform(dx, dy, -dy, dx, canvasBG.width / 2, canvasBG.height / 2)

    ctxBG.drawImage(this.img, -this.img.width / 2, -this.img.height / 2, this.img.width, this.img.height)

    ctxBG.setTransform(1, 0, 0, 1, 0, 0) // reset transformations when done

  }

  this.move = function (x, y){

  }

}

function Maquina(x, y){
  //Attributes
  this.x = x;
  this.y = y;

  //Methods
  this.draw = function() {
    let img = new Image();
    img.src = 'https://i.postimg.cc/JnV5wgS7/maquina.png';
    img.onload = function(e){
      ctxFG.drawImage(img, maquina.x, maquina.y);
    }
  }

  this.move = function(x, y) {
  
  }
}
html, body {
  width:  100%;
  height: 100vh;
  margin: 0;
}

#info{
  position: absolute;
  left: 75%;
  top: 10px;
  z-index: 5;
}

button{
  cursor: pointer;
}

canvas{
  position:absolute;
  left:0px;
  top:0px;
  width: 100%;
  height: 100vh;

}

#canvasBG{
  z-index: 1;
}
#canvasFG{
  z-index: 2;
}
#canvasSU{
  z-index: 3;
}
#canvasTR{
  z-index: 4;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Monitor</title>
  	<meta name="viewport" content="width=device-width, initial-scale=1">  
  	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  
  </head>
  <body>

    <div class="container-fluid" style='height: 100vh;'>
      <div class="row">
        <div class="col-sm-12" style='position:relative;'>
          <!-- Background's canvas -->
          <canvas id="canvasBG">
          </canvas>

          <!-- Machine's canvas -->
          <canvas id="canvasFG">
          </canvas>

          <div id='info'>
            <b>Posicion actual:</b> <span id='currPos'></span>
            <br><br>
            <div class="btn-group" role="group" aria-label="Basic example">
              <button type="button" class="btn btn-primary" onclick='maquina.A()'>A</button>
              <button type="button" class="btn btn-danger" onclick='maquina.B()'>B</button>
            </div>
            <br><br>
            <div class="input-group mb-3">
              <div class="input-group-prepend">
                <button class="btn btn-outline-light" type="button" onclick="maquina.move($('#coord').val().split(',')[0], $('#coord').val().split(',')[1])">Mover</button>
              </div>
              <input type="text" class="form-control" placeholder="Mov -> x,y" aria-label="Small" id='coord'>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

想象一下任何游戏的小地图,例如《魔兽世界》或《侠盗猎车手》,您可以在其中看到玩家的光标在中心,并且背景按照玩家的命令旋转。我在canvas html5中编写类似的代码。它是否使用canva的工具绘制并加载了图像文件(在代码中,注释了绘制图样)。

现在,我需要在用户移动“播放器”时将背景滚动到底部,并在用户转动“播放器”时旋转背景。因此,背景总是会滚动到底部(是否旋转)。我知道如何翻译画布并重新绘制背景,但是我不确定该怎么做,图像会重复自身以不显示白色。

如果我的代码进展顺利或以某种方式对其进行了更改,我需要一些有关如何做的建议。

您可以在代码中看到,有一个旋转背景的功能,它可以完美运行,我已经here了。但是,有了该功能,我还有另一个问题,锚点的旋转位于中心,我需要使其位于机器的(黑色三角形)位置。

0 个答案:

没有答案