我想在Chrome控制台中调试我的html5画布。我想在位置(445,650)获得像素颜色。
我尝试使用此代码:
var example = document.getElementById('glcanvas');
var context = example.getContext('2d');
var data = context.getImageData(x, y, 1, 1).data;
当我一个接一个地运行这些行时,我得到:
example
<canvas class="topleft" id="glcanvas" width="479" height="616" tabindex="1" contenteditable="true" style="cursor: default; width: 479px; height: 616px;"></canvas>
context
null
如何获得非null 上下文?
答案 0 :(得分:1)
Canvas元素可以附加仅一个渲染上下文。每次在第一次初始化后调用getContext(type)
时,如果您使用相同的type
参数,它将返回相同的上下文对象,如果您使用了其他上下文,则返回null
type
。
从您的标记中可以看出,您的画布上附有了webgl上下文
因此,当您致电getContext('2d')
时,它会返回null
。
以下是一个示例,说明如何在未直接初始化的上下文中使用它。
webgl的getImageData
等效方法为readPixels()
。
// we have access to the DOM element
var canvas = document.querySelector('canvas');
// we need to get the correct context type, or it will return null
var gl = canvas.getContext('webgl') || canvas.getContext('webgl2');
// where we'll store our pixels info
var pixels = new Uint8Array(4);
canvas.addEventListener('click', function(e) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
// we need to call it in the same execution flow as 'render' because webgl erase the drawing buffer by default
// this can be done by stacking our code in the next frame.
requestAnimationFrame(function() {
gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(pixels);
});
});
// we have access to the DOM element
var canvas = document.querySelector('canvas');
// we need to get the correct context type, or it will return null
var gl = canvas.getContext('webgl') || canvas.getContext('webgl2');
// where we'll store our pixels info
var pixels = new Uint8Array(4);
canvas.addEventListener('click', function(e) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
// we need to call it in the same execution flow as 'render' because webgl erase the drawing buffer by default
// this can be done by stacking our code in the next frame.
requestAnimationFrame(function() {
gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(pixels);
});
});
&#13;
<!--
Example of external code, on which we don't have direct access.
Taken from https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_cube.html
-->
<base href="https://threejs.org/examples/">
<script src="../build/three.js"></script>
<script>
(function(){
var camera, scene, renderer;
var mesh;
init();
animate();
console.clear();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
scene = new THREE.Scene();
var geometry = new THREE.BoxBufferGeometry(200, 200, 200);
var material = new THREE.MeshBasicMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
})();
</script>
&#13;
请注意,像素读取操作变为异步,并且在此实现中将始终为一帧,因为webgl上下文未使用preserveDrawingBuffer
选项进行初始化。如果是,你可以制作同步方法。
还有一种类型不可知的方法:使用屏幕外2d上下文并直接在这个2d上下文中绘制画布。
// the canvas we want to read
var target = document.querySelector('canvas');
// the canvas we'll use to read the target on
var reader = document.createElement('canvas');
var ctx = reader.getContext('2d');
target.addEventListener('click', function(e) {
var x = e.clientX - target.offsetLeft;
var y = e.clientY - target.offsetTop;
// same preserveDrawingBuffer workaround
requestAnimationFrame(function() {
// move the target image in the top left corner of our reader,
// because we want only a single pixel
ctx.drawImage(target, -x, -y);
var pixels = ctx.getImageData(0, 0, 1, 1);
console.log(pixels);
});
});
// the canvas we want to read
var target = document.querySelector('canvas');
// the canvas we'll use to read the target on
var reader = document.createElement('canvas');
var ctx = reader.getContext('2d');
target.addEventListener('click', function(e) {
var x = e.clientX - target.offsetLeft;
var y = e.clientY - target.offsetTop;
// same preserveDrawingBuffer workaround
requestAnimationFrame(function() {
// move the target image in the top left corner of our reader,
// because we want only a single pixel
ctx.drawImage(target, -x, -y);
var pixels = ctx.getImageData(0, 0, 1, 1);
console.log(pixels);
});
});
&#13;
<!--
Example of external code, on which we don't have direct access.
Taken from https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_cube.html
-->
<base href="https://threejs.org/examples/">
<script src="../build/three.js"></script>
<script>
(function() {
var camera, scene, renderer;
var mesh;
init();
animate();
console.clear();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
scene = new THREE.Scene();
var geometry = new THREE.BoxBufferGeometry(200, 200, 200);
var material = new THREE.MeshBasicMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
})();
</script>
&#13;
答案 1 :(得分:0)
实际上您的代码工作正常。
这是一个HTML /脚本代码,其中包含您问题的给定信息。
<html>
<canvas class="topleft" id="glcanvas" width="479" height="616" tabindex="1" contenteditable="true" style="cursor: default; width: 479px; height: 616px;"></canvas>
<script>
var example = document.getElementById('glcanvas');
var context = example.getContext('2d');
var x=445;
var y=650;
var data = context.getImageData(x, y, 1, 1).data;
alert('R:' + data[0] + ' G:' + data[1] + ' B:' + data[2]);
</script>
</html>
可能是在glcanvas-Object初始化之前运行脚本。