javascript - 使用 css 设置后获取 Canvas 像素数据是错误的

标签 javascript html css canvas

我正在尝试从 painted canvas 获取 rgb 颜色数据。 具有此功能:

function pick(event) {
    var x = event.layerX;
    var y = event.layerY;
    var pixel = ctx.getImageData(x, y, 1, 1);
    var data = pixel.data;
    $("#color").val(pixel.data.toString());
    console.log(pixel.data.toString());
}

但是,当我将 canvas 元素设置为任何相对 width (80%/100%) 时,如下所示:

canvas {
    /*width: 100%;*/   /*when i set the width, the rgb values are incorrect .... */
    /*margin-left: auto;
    margin-right: auto;
    display: block;*/
}

我不再从此函数中获取正确的值。

附上我的 JS Fiddle: https://jsfiddle.net/iliran11/ay9nf1p9/

最佳答案

当你拉伸(stretch)并将其乘以坐标时,你需要找到宽度的差异。

//color names
var basecolors = ["(255,0,0)",
    "(255,128,0)",
    "(255,255,0)",
    "(128,255,0)",
    "(0,255,0)",
    "(0,255,128)",
    "(0,255,255)",
    "(0,128,255)",
    "(0,0,255)",
    "(128,0,255)",
    "(255,0,255)",
    "(255,0,128)",
    "(128,128,128)"
];
//init
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
var heightPerColor = height / basecolors.length;
//init cursor
var xCursor = 0;
var yCursor = 0;
drawPallete(width, height, "s");
function drawPallete(width, height, type) {
    canvas.width = width;
    canvas.height = height;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    var Grad = ctx.createLinearGradient(0, 0, canvas.width, 0);
    Grad.addColorStop(0 / 6, '#F00');
    Grad.addColorStop(1 / 6, '#FF0');
    Grad.addColorStop(2 / 6, '#0F0');
    Grad.addColorStop(3 / 6, '#0FF');
    Grad.addColorStop(4 / 6, '#00F');
    Grad.addColorStop(5 / 6, '#F0F');
    Grad.addColorStop(6 / 6, '#F00');
    ctx.fillStyle = Grad;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}
;
function pick(event) {
    var canvas = document.getElementById("canvas");
    //Here comes the stretch offset
    //var off = (1 / canvas.width) * canvas.offsetWidth;
    var off = (1 / canvas.offsetWidth) * canvas.width;
    //Applying offset
    var x = Math.floor(event.layerX * off) - Math.floor(canvas.offsetLeft * off);
    var y = Math.floor(event.layerY * off) - Math.floor(canvas.offsetTop * off);
    var pixel = ctx.getImageData(x, y, 1, 1);
    var data = pixel.data;
    $("#color").val([pixel.data[0], pixel.data[1], pixel.data[2], pixel.data[3]].join(','));
    //console.log("offset between", canvas.width, "and", canvas.offsetWidth, "is", off);
    console.log(off, canvas.offsetWidth, canvas.width, x);
}
// target the button
var btn = $("#myBtn");
var modal = $("#myModal");
btn.click(function () {
    modal.css("display", "block");
    var canvas = document.getElementById("canvas");
    canvas.addEventListener('mousemove', pick);
});
#myModal {
  display: none;
  /* Hidden by default */
  position: fixed;
  /* Stay in place */
  z-index: 1;
  /* Sit on top */
  padding-top: 100px;
  /* Location of the box */
  left: 0;
  top: 0;
  width: 100%;
  /* Full width */
  height: 100%;
  /* Full height */
  overflow: auto;
  /* Enable scroll if needed */
  background-color: rgb(0, 0, 0);
  /* Fallback color */
  background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
  background-color: #fefefe;
  margin: auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
}
canvas {
  width: 100%;
  /*margin-left: auto;
            margin-right: auto;
            display: block;*/
}
<form action="" method="post">
  <label for="POST-name">Name:</label>
  <input id="color" type="text">
</form>

<button id="myBtn">Open Color</button>
<div id="myModal" class="modal">
  <!-- Modal content -->
  <div class="modal-content">
    <!-- Set height and width -->
    <canvas id="canvas" width="1000" height="1000"></canvas>
  </div>

</div>

<script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script>

编辑 1

补偿 offsetLeftoffsetTop

关于javascript - 使用 css 设置后获取 Canvas 像素数据是错误的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41543815/

相关文章:

javascript - AngularJS $state 使用 ctrl + 单击在新选项卡中打开链接

javascript - JQuery Mobile 点击事件不起作用,具体取决于 HTML 中的元素位置

没有缩进的 HTML 项目符号点

asp.net - 如何截断行边界处的表溢出?

javascript:将函数作为参数传递给另一个函数,代码以另一种顺序调用,然后我期望

JavaScript 正则表达式 : Create regex with variable

html - 对齐多个 SVG 以创建可扩展容器

html - 如何在不滚动的情况下将布局固定到浏览器窗口

javascript - 使用 FileReader 选择和显示图像

java - AJAX:同时两个请求