gpt4 book ai didi

javascript - 获取 Canvas 中控制台位置处的像素颜色

转载 作者:行者123 更新时间:2023-11-28 17:58:21 25 4
gpt4 key购买 nike

我想在 Chrome 控制台中调试我的 html5 canvas。我想获取位置 (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

如何获得非空上下文?

最佳答案

Canvas 元素只能有一个附加渲染上下文。每次在第一次初始化后调用 getContext(type) 时,如果您使用相同的 type 参数,它将返回相同的上下文对象,或者 null code> 如果您使用了其他上下文的类型

从您的标记来看,您的 Canvas 似乎附加了一个 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);
});
});
<!-- 
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>

请注意,像素读取操作变为异步,并且在此实现中始终会晚一帧,因为 webgl 上下文未使用 preserveDrawingBuffer 选项进行初始化。如果是的话,您可以创建一个同步方法。

还有一种与类型无关的方法:使用屏幕外 2d 上下文并直接在此 2d 上下文上绘制 Canvas 。

// 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);
});
});
<!-- 
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>

关于javascript - 获取 Canvas 中控制台位置处的像素颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44055443/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com