背景
问题的起因是某项目中实现一个光标指向canvas后,捕捉当前鼠标位置色值的功能。功能完成后部分用户出现色值偏差,如图:
分析
fabricjs初始化canvas时,enableRetinaScalling默认开启,致使canvas getImageData()坐标错位,
问题解决:
修改前:
javascript
/**
* 获取canvas背景图中指定像素色值
* @param canvas canvas参数为new fabric.Canvas()实例
* @param x 鼠标x坐标位置
* @param y 鼠标y坐标位置
* @returns 当前鼠标所在像素的色值
*/
function getColorAtPosition(canvas, x, y) {
var canvasElement = canvas.getElement()
var context = canvasElement.getContext('2d')
let newX = x * canvas.backgroundImage.scaleX
let newY = y * canvas.backgroundImage.scaleY
var pixel = context.getImageData(newX, newY, 1, 1).data
const color = new fabric.Color(`rgba(${pixel.join(',')})`)
return {
array: pixel,
rgba: `rgba(${pixel.join(',')})`,
hex: `#${color.toHex()}`
}
}
为保证当前坐标在不同屏幕下都可以正常捕捉,需要乘以屏幕像素比的比例,window.devicePixelRatio
修改后:
javascript
// 获取canvas背景图中指定像素色值
function getColorAtPosition(canvas, x, y) {
var canvasElement = canvas.getElement()
var context = canvasElement.getContext('2d')
// 注:retina屏幕下需要乘以当前设备的devicePixelRatio值
let newX = x * canvas.backgroundImage.scaleX * window.devicePixelRatio
let newY = y * canvas.backgroundImage.scaleY * window.devicePixelRatio
var pixel = context.getImageData(newX, newY, 1, 1).data
const color = new fabric.Color(`rgba(${pixel.join(',')})`)
return {
array: pixel,
rgba: `rgba(${pixel.join(',')})`,
hex: `#${color.toHex()}`
}
}
可以根据不同屏幕像素比,计算在canvas图像中相应的准确坐标。