tareqanwar
tareqanwar

Reputation: 88

Is it possible to get position in Canvas where canvas is a css fixed element?

Right now when I set position: absolute; in css it gives:

Uncaught TypeError: Cannot read property 'x' of undefined
    at HTMLCanvasElement.getColor

It works when position: absolute; But I need the Canvas in fixed position.

My findPos() function to get the position of object:

function findPos(obj) {
  var curleft = 0, curtop = 0;
  if (obj.offsetParent) {
    do {
      curleft += obj.offsetLeft;
      curtop += obj.offsetTop;
    } while (obj = obj.offsetParent);
    return { x: curleft, y: curtop };
  }
  return undefined;
}

Please check the fiddle for my code: https://jsfiddle.net/ds6kug6r/8/

Upvotes: 2

Views: 207

Answers (1)

Kaiido
Kaiido

Reputation: 137044

That's because according to the specs (2.1), fixed positioned elements don't have an offsetParent element.

But you don't need it anyway, instead use Element.getBoundingClientRect() which doesn't suffer from the padding edge issue.

function getColor(e) {
  // getBoundingClientRect to retrieve the position of our canvas in the doc
  var rect = this.getBoundingClientRect();
  // we also need to use clientX and clientY values now
  var x = e.clientX - rect.left;
  var y = e.clientY - rect.top;
  var coord = "x=" + x + ", y=" + y;
  var c = this.getContext('2d');
  var p = c.getImageData(x, y, 1, 1).data;
  log(p);
}


/* Color Wheel */
var canvas = document.getElementById("picker");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 100;
var counterClockwise = false;

for (var angle = 0; angle <= 360; angle += 1) {
  var startAngle = (angle - 2) * Math.PI / 180;
  var endAngle = angle * Math.PI / 180;
  context.beginPath();
  context.moveTo(x, y);
  context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
  var gradient = context.createRadialGradient(x, y, 0, x, y, radius);
  gradient.addColorStop(0, 'hsl(' + angle + ', 10%, 100%)');
  gradient.addColorStop(1, 'hsl(' + angle + ', 100%, 50%)');
  context.fillStyle = gradient;
  context.fill();
}


document.getElementById("picker").addEventListener("click", getColor);


function log(m) {
  document.getElementById("viz").style.backgroundColor = 'rgba(' + m + ')';
  document.getElementById("log").append(m + '\n')
}
canvas {
  position: fixed;
  right: 10px;
  bottom: 10px;
  cursor: pointer;
}

#viz {
  display: inline-block;
  height: 20px;
  width: 20px;
}
<canvas class="colorWheel" id="picker" width="200" height="200"></canvas>

<div>
  Log: <span id="viz"></span>
  <pre id="log"></pre>
</div>

Upvotes: 3

Related Questions