gpt4 book ai didi

javascript - 缩放后居中 Canvas 上下文

转载 作者:行者123 更新时间:2023-11-30 20:19:33 24 4
gpt4 key购买 nike

我一直在尝试在 three.js 中使用 Canvas 作为纹理。由于 three.js 要求纹理是 2 的幂,因此 Canvas 宽度和高度设置为 [512, 512] 但是我希望输出 Canvas 是 2 的非幂。为了保持缩放比例,我按纵横比缩放高度,这会将绘制的对象的中心向下移动。我试图通过一些任意数字来转换高度备份(即像 ctx.transform(0, -height/(1 -(height/width))) 但一直没能找到最佳点。有人知道如何处理吗?

var camera, scene, renderer, mesh, material, ctx, texture, canvas, dimensions;
init();
animate();

function init() {
canvas = document.createElement("canvas")
canvas.width = 512;
canvas.height = 512;
ctx = canvas.getContext("2d");
texture = new THREE.CanvasTexture(canvas)


renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);

camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
scene = new THREE.Scene();
material = new THREE.MeshBasicMaterial({map: texture});

var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
dimensions = renderer.getSize()
}

function animate() {

ctx.save()
ctx.scale(1, dimensions.width / dimensions.height)
// ctx.translate(0, -height * ??);
ctx.fillStyle = "#FF0000"
ctx.fillRect((canvas.width / 2) - 25, (canvas.height / 2) - 25, 50, 50);
ctx.restore()

texture.needsUpdate = true;
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>

正方形应该被缩放(仍然是正方形)并居中

最佳答案

我们可以通过移动到中心并在每次绘制时调整渲染器的大小来解决您的问题,这样您就可以看到正方形剩余的正方形,并且通过在每次绘制轮次清除 Canvas 以便多次绘制不会停留在周围并且混淆正方形的位置。

function init() {

canvas = document.createElement( 'canvas' );
ctx = canvas.getContext( '2d' );

renderer = new THREE.WebGLRenderer;
renderer.setSize( innerWidth, innerHeight);

texture = new THREE.Texture( canvas );
camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );
scene = new THREE.Scene;

scene.add( new THREE.Mesh(
new THREE.PlaneBufferGeometry( 2, 2 ),
new THREE.MeshBasicMaterial({ map: texture })
) );

document.body.appendChild( renderer.domElement );

}
function animate() {

// Always update your renderer size.
// This might be better off in the window.onresize event.
renderer.setSize( innerWidth, innerHeight );

// This will clear all draw data from your canvas, so we can draw on an empty canvas
canvas.width = 512;
canvas.height = 512;

ctx.save();
// Move the origin to the center of the canvas
ctx.translate( canvas.width / 2, canvas.height / 2 );
// Scale the canvas like you did, except we know the size as we just set it.
ctx.scale( 1, innerWidth / innerHeight );
ctx.fillStyle = "#FF0000";
// Draw the rectangle as if you want its center at the origin
ctx.fillRect( -25, -25, 50, 50 );
ctx.restore();

texture.needsUpdate = true;
requestAnimationFrame( animate );
renderer.render( scene, camera );

}

// I have removed some of the globals we don't need
// as the animate() function only needs access to some.
// I mostly do this because it clarifies what the functions share of resources.

var renderer, scene, camera, texture, canvas, ctx;

init();
animate();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/95/three.min.js"></script>

老实说,由于 OrthographicCamera 的工作原理,这似乎与您要了解的内容相反。最好将相机缩放到视口(viewport)而不是纹理(我知道出于目的这是一种检查缩放能力的好方法)。在这种情况下,您的网格 被拉伸(stretch)到一个不自然的比例并且您的纹理对其进行了修正。但是,您可能应该正常设置您的相机和网格并确保您的相机做正确的事情并缩放到您的视口(viewport)(就像 PerspectiveCamera 上的 .aspect 值一样给你看正确的视觉)

function dispatch_draw( time ){

window.dispatchEvent( new CustomEvent( 'draw' ) );

window.requestAnimationFrame( dispatch_draw );

}
function event_draw(){

renderer.render( scene, camera );

}
function event_resize(){

dimensions.set( innerWidth, innerHeight );
renderer.setSize( dimensions.x, dimensions.y );

camera.left = -dimensions.x / 2;
camera.right = dimensions.x / 2;
camera.top = dimensions.y / 2;
camera.bottom = -dimensions.y / 2;
camera.near = -1;
camera.far = 1;
camera.updateProjectionMatrix();

}

const renderer = new THREE.WebGLRenderer;
const camera = new THREE.OrthographicCamera;
const scene = new THREE.Scene;
const mesh = new THREE.Mesh(
new THREE.PlaneGeometry( 200, 200 ),
new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
const dimensions = new THREE.Vector2( innerWidth, innerHeight );

scene.add( mesh );

window.addEventListener( 'resize', event_resize );
window.addEventListener( 'draw', event_draw );

event_resize();
dispatch_draw();

document.body.appendChild( renderer.domElement );
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/95/three.min.js"></script>

关于javascript - 缩放后居中 Canvas 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51600837/

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