javascript - 如何使图像完全适合 HTML5 Canvas ?

标签 javascript css html html5-canvas

我有这个滑动益智游戏的代码。 当我使用恰好 500x500 像素的图像时,一切正常,但是当我插入大图像时,只有图像的左上角可见,并且只有这部分被分成 16 个拼图部分。如何使整个图像适合 Canvas ?

      <!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta charset="utf-8">
  <style>
  .picture {
    border: 1px solid black;
  }
  </style>
</head>
<body>
  <div id="title">
    <h2>Sliding Puzzle</h2>
  </div>
  <div id="slider">
    <form>
      <label>Easy</label>
      <input type="range" id="scale" value="4" min="3" max="5" step="1">
      <label>Hard</label>
    </form>
    <br>
  </div>
  <div id="main" class="main">
    <canvas id="puzzle" width="500px" height="500px"></canvas>
  </div>
  <script>
  var context = document.getElementById('puzzle').getContext('2d');
var img = new Image();
img.src = 'http://www.antilimit.com/nature/i/37.jpg';

img.addEventListener('load', drawTiles, false);

var boardSize = document.getElementById('puzzle').width;
var tileCount = 4

var tileSize = boardSize / tileCount;

var clickLoc = new Object;
clickLoc.x = 0;
clickLoc.y = 0;

var emptyLoc = new Object;
emptyLoc.x = 0;
emptyLoc.y = 0;

var solved = false;

var boardParts;
setBoard();

document.getElementById('scale').onchange = function() {
  tileCount = this.value;
  tileSize = boardSize / tileCount;
  setBoard();
  drawTiles();
};

document.getElementById('puzzle').onclick = function(e) {
  clickLoc.x = Math.floor((e.pageX - this.offsetLeft) / tileSize);
  clickLoc.y = Math.floor((e.pageY - this.offsetTop) / tileSize);
  if (distance(clickLoc.x, clickLoc.y, emptyLoc.x, emptyLoc.y) == 1) {
    slideTile(emptyLoc, clickLoc);
    drawTiles();
  }
  if (solved) {
    setTimeout(function() {alert("You solved it!");}, 500);
  }
};

function setBoard() {
  boardParts = new Array(tileCount);
  for (var i = 0; i < tileCount; ++i) {
    boardParts[i] = new Array(tileCount);
    for (var j = 0; j < tileCount; ++j) {
      boardParts[i][j] = new Object;
      boardParts[i][j].x = (tileCount - 1) - i;
      boardParts[i][j].y = (tileCount - 1) - j;
    }
  }
  emptyLoc.x = boardParts[tileCount - 1][tileCount - 1].x;
  emptyLoc.y = boardParts[tileCount - 1][tileCount - 1].y;
  solved = false;
}

function drawTiles() {
  context.clearRect ( 0 , 0 , boardSize , boardSize );
  for (var i = 0; i < tileCount; ++i) {
    for (var j = 0; j < tileCount; ++j) {
      var x = boardParts[i][j].x;
      var y = boardParts[i][j].y;
      if(i != emptyLoc.x || j != emptyLoc.y || solved == true) {
        context.drawImage(img, x * tileSize, y * tileSize, tileSize, tileSize,
            i * tileSize, j * tileSize, tileSize, tileSize);
      }
    }
  }
}

function distance(x1, y1, x2, y2) {
  return Math.abs(x1 - x2) + Math.abs(y1 - y2);
}

function slideTile(toLoc, fromLoc) {
  if (!solved) {
    boardParts[toLoc.x][toLoc.y].x = boardParts[fromLoc.x][fromLoc.y].x;
    boardParts[toLoc.x][toLoc.y].y = boardParts[fromLoc.x][fromLoc.y].y;
    boardParts[fromLoc.x][fromLoc.y].x = tileCount - 1;
    boardParts[fromLoc.x][fromLoc.y].y = tileCount - 1;
    toLoc.x = fromLoc.x;
    toLoc.y = fromLoc.y;
    checkSolved();
  }
}

function checkSolved() {
  var flag = true;
  for (var i = 0; i < tileCount; ++i) {
    for (var j = 0; j < tileCount; ++j) {
      if (boardParts[i][j].x != i || boardParts[i][j].y != j) {
        flag = false;
      }
    }
  }
  solved = flag;
}

  </script>


</body></html>

最佳答案

您在示例中使用的图像是 1000 像素 x 1000 像素,因此将其分成 16 个图 block 需要将每个图像分成 16 个部分,每个部分的大小为 250 像素 x 250 像素。目前您正在使用 16 个部分,每个部分为 125px x 125px,因此您只复制图像的左上四分之一。

获取宽度为 W 和高度为 H 的矩形图像,然后从左上角开始,您可以获取 imgSize = W if W<=H 或 imgSize = H if H 的正方形图像

你求比例因子imgScale = imgSize/500

在您的示例中 imgSize = 1000 等 imgScale = 2 因此您要复制的部分是图 block 宽度和高度的两倍

将drawTiles函数改为

function drawTiles() {
  var imgSize=Math.min(img.width,img.height);
  var imgScale=imgSize/500;     
  context.clearRect ( 0 , 0 , boardSize , boardSize );
  for (var i = 0; i < tileCount; ++i) {
    for (var j = 0; j < tileCount; ++j) {
      var x = boardParts[i][j].x;
      var y = boardParts[i][j].y;
      if(i != emptyLoc.x || j != emptyLoc.y || solved == true) {
        context.drawImage(img, x * tileSize*imgScale, y * tileSize*imgScale, tileSize*imgScale, tileSize*imgScale,
            i * tileSize, j * tileSize, tileSize, tileSize);
      }
    }
  }
}

这是一个jsfiddle

关于javascript - 如何使图像完全适合 HTML5 Canvas ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28543775/

相关文章:

html - 相关帖子代码导致错误的帖子评论在 Wordpress 中加载

javascript - 有没有更好的方法来执行此 jQuery 功能

javascript - 除了取决于查询的 URL 的一个变量的值之外,如何在多个 URL 中使用相同的 HTML 页面?

javascript - 根据 d3.js 中的矩形大小调整文本字体大小

html - 相对大小的表格单元格元素的定位(IE 错误?)

javascript - 使用 Protractor 测试 Chart.js Canvas

javascript - 通过滚动到达导航栏区域时要剪切的元素

html - 我可以在没有 css 的情况下更改标签的文本颜色吗?

javascript - 如何通过数组 Javascript 拆分对象数组

javascript - 根据嵌套值按字典顺​​序对对象数组进行排序