TSR*_*TSR 3 html javascript debugging canvas
我想在 Chrome 控制台中调试我的 html5 画布。我想获取位置 (445, 650) 处的像素颜色。
我尝试使用以下代码:
var example = document.getElementById('glcanvas');
var context = example.getContext('2d');
var data = context.getImageData(x, y, 1, 1).data;
Run Code Online (Sandbox Code Playgroud)
当我一行一行地运行这些行时,我得到:
example
<canvas class="topleft" id="glcanvas" width="479" height="616" tabindex="1" contenteditable="true" style="cursor: default; width: 479px; height: 616px;"></canvas>
context
null
Run Code Online (Sandbox Code Playgroud)
如何获得非空上下文?
画布元素只能附加一个渲染上下文。每次在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);
});
});
Run Code Online (Sandbox Code Playgroud)
// 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);
});
});
Run Code Online (Sandbox Code Playgroud)
<!--
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>
Run Code Online (Sandbox Code Playgroud)
请注意,像素读取操作变为异步,并且在此实现中始终会晚一帧,因为 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);
});
});
Run Code Online (Sandbox Code Playgroud)
// 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);
});
});
Run Code Online (Sandbox Code Playgroud)
<!--
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>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3873 次 |
最近记录: |