三个JS:OrbitControls拖拽时图片像素跳跃
Three JS: OrbitControls the pixel of picture jumps when dragging
我最近开始处理3d,我想在场景中移动,但是拖动时,我看到图片中的像素如何在相机停止移动之前开始跳跃。这显然是错误的工作
为什么会这样?以及如何避免呢?
我的代码:https://codepen.io/davedev13/pen/zYEyxRX
const data = {
"objects": [
{
"img": "https://picsum.photos/400/500",
"title": "Creative",
"description": "lorem ipsum",
"url": "/1",
"position": {
"left": "-500",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Angles",
"description": "lorem ipsum",
"url": "/2",
"position": {
"left": "500",
"top": "-500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Awwards",
"description": "lorem ipsum",
"url": "/3",
"position": {
"left": "500",
"top": "0"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Conexe",
"description": "lorem ipsum",
"url": "/4",
"position": {
"left": "0",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Luxury",
"description": "lorem ipsum",
"url": "/5",
"position": {
"left": "-500",
"top": "0"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Develop",
"description": "lorem ipsum",
"url": "/6",
"position": {
"left": "0",
"top": "-500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Desing",
"description": "lorem ipsum",
"url": "/7",
"position": {
"left": "500",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Sociality",
"description": "lorem ipsum",
"url": "/8",
"position": {
"left": "-500",
"top": "-500"
}
}
]
}
class Drag {
drag = {
width: 2560,
height: 1440,
};
mouseOut = false;
constructor(container) {
this.container = container;
let w = container.clientWidth;
let h = container.clientHeight;
let viewSize = h;
let aspectRatio = w / h;
this.viewport = {
viewSize: viewSize,
aspectRatio: aspectRatio,
left: (-aspectRatio * viewSize) / 2,
right: (aspectRatio * viewSize) / 2,
top: viewSize / 2,
bottom: -viewSize / 2,
near: -10,
far: 100
}
this.initScene();
}
initScene() {
this.camera = new THREE.OrthographicCamera(
this.viewport.left, this.viewport.right,
this.viewport.top, this.viewport.bottom,
this.viewport.near, this.viewport.far
);
this.scene = new THREE.Scene();
this.renderer = new THREE.WebGLRenderer({
// alpha: true // чтобы сцена была прозрачной
});
this.renderer.domElement.id = 'canvasGrid';
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setClearColor(0xdcdcdc, 1);
this.container.appendChild(this.renderer.domElement);
// драг контейнер для сцены
const geometry = new THREE.PlaneGeometry(this.drag.width, this.drag.height);
const material = new THREE.MeshBasicMaterial({
color: 0xdcdcdc,
});
this.drag.plane = new THREE.Mesh(geometry, material);
// драг бокс по которому гранимац которого будет двигаться сцена при драге
this.dragBox = new THREE.Box3().setFromObject(this.drag.plane);
this.scene.add(this.drag.plane);
this.sceneObjects();
this.setControls();
this.animate();
window.addEventListener('mouseout', () => this.mouseOut = true, false);
window.addEventListener('mouseover', () => {
this.mouseOut = false;
this.animate();
}, false);
}
sceneObjects() {
// instantiate a loader
const loader = new THREE.TextureLoader();
data.objects.map((item) => {
const group = new THREE.Group();
group.name = item.title;
// load a resource
loader.load(
// resource URL
item.img,
// onLoad callback
function (texture) {
const width = texture.image.naturalWidth * 0.5;
const height = texture.image.naturalHeight * 0.5;
// in this example we create the material when the texture is loaded
const geometry = new THREE.BoxGeometry(width, height, 0);
const material = new THREE.MeshBasicMaterial({map: texture});
const mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
group.position.set(item.position.left, item.position.top, 0);
},
// onProgress callback currently not supported
undefined,
// onError callback
function (err) {
console.error('An error happened.', err);
}
);
this.scene.add(group);
});
const geometry1 = new THREE.BoxGeometry(550, 300, 0);
const texture = new THREE.TextureLoader().load("https://miro.medium.com/max/1400/1*Ynit7J26tXLwyq-sB3AUug.png");
console.log(texture)
const material1 = new THREE.MeshBasicMaterial({map: texture, opacity: 0.3});
const mesh = new THREE.Mesh(geometry1, material1);
this.scene.add(mesh);
}
render() {
// if (this.mouseDownPressed) {
let x1 = this.camera.position.x + (this.camera.left / this.camera.zoom);
let x1a = Math.max(x1, this.dragBox.min.x);
let pos_x = x1a - (this.camera.left / this.camera.zoom);
let x2 = pos_x + (this.camera.right / this.camera.zoom);
let x2a = Math.min(x2, this.dragBox.max.x);
pos_x = x2a - (this.camera.right / this.camera.zoom);
let y1 = this.camera.position.y + (this.camera.bottom / this.camera.zoom);
let y1a = Math.max(y1, this.dragBox.min.y);
let pos_y = y1a - (this.camera.bottom / this.camera.zoom);
let y2 = pos_y + (this.camera.top / this.camera.zoom);
let y2a = Math.min(y2, this.dragBox.max.y);
pos_y = y2a - (this.camera.top / this.camera.zoom);
this.camera.position.set(pos_x, pos_y, this.camera.position.z);
this.camera.lookAt(pos_x, pos_y, this.controls.target.z); // todo: what is it?
this.controls.target.set(pos_x, pos_y, 0);
this.controls.update();
// }
this.renderer.render(this.scene, this.camera);
}
setControls() {
// Need to be similar to what is in OrbitControls3Dpane.js constructor
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.controls.mouseButtons = {
LEFT: THREE.MOUSE.PAN,
MIDDLE: THREE.MOUSE.DOLLY,
RIGHT: THREE.MOUSE.PAN
}
//////////////////////////////////////
// Set rotate related parameters
//////////////////////////////////////
// No rotation.
this.controls.enableRotate = false;
this.controls.minPolarAngle = Math.PI / 2;
this.controls.maxPolarAngle = Math.PI / 2;
// No orbit horizontally.
this.controls.minAzimuthAngle = 0; // radians
this.controls.maxAzimuthAngle = 0; // radians
//////////////////////////////////////
// Set zoom related parameters
//////////////////////////////////////
this.controls.enableZoom = true;
this.controls.zoomSpeed = 0.9;
this.controls.minDistance = this.camera.near;
this.controls.maxDistance = this.camera.far;
this.controls.minZoom = window.innerWidth > window.innerHeight ?
window.innerWidth / this.drag.width : window.innerHeight / this.drag.height;
this.controls.maxZoom = 1 + this.controls.minZoom;
//////////////////////////////////////
// Set pan related parameters
//////////////////////////////////////
this.controls.enablePan = true;
this.controls.panSpeed = 0.6;
this.controls.screenSpacePanning = true;
this.controls.enableDamping = true;
// this.renderer.domElement.addEventListener('mousedown', () => {
// this.mouseDownPressed = true;
// }, false);
// this.renderer.domElement.addEventListener('mouseup', () => {
// setTimeout(() => {
// this.mouseDownPressed = false;
// }, 700);
// }, false);
}
animate() {
this.render();
if (!this.mouseOut) {
requestAnimationFrame(this.animate.bind(this));
}
}
}
function init() {
new Drag(document.querySelector('.canvas'));
}
init();
.canvas {
width: 100vw;
height: 100vh;
}
<!-- partial:index.partial.html -->
<div class="canvas"></div>
<!-- partial -->
<script src='https://threejs.org/build/three.js'></script>
<script src='https://threejs.org/examples/js/controls/OrbitControls.js'></script><script src="./script.js"></script>
我使用“OrthographicCamera”创建了一个场景,并将此相机与 OrbitControls 一起移动,也许这对我来说不是最佳选择,如果是这样 - 请告诉我如何正确操作?
antialias:真正在 WebGLRenderer 解决
所有相同的设置,场景立即变得更流畅,图片没有错误
也就是他降低性能滑出...
我最近开始处理3d,我想在场景中移动,但是拖动时,我看到图片中的像素如何在相机停止移动之前开始跳跃。这显然是错误的工作
为什么会这样?以及如何避免呢? 我的代码:https://codepen.io/davedev13/pen/zYEyxRX
const data = {
"objects": [
{
"img": "https://picsum.photos/400/500",
"title": "Creative",
"description": "lorem ipsum",
"url": "/1",
"position": {
"left": "-500",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Angles",
"description": "lorem ipsum",
"url": "/2",
"position": {
"left": "500",
"top": "-500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Awwards",
"description": "lorem ipsum",
"url": "/3",
"position": {
"left": "500",
"top": "0"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Conexe",
"description": "lorem ipsum",
"url": "/4",
"position": {
"left": "0",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Luxury",
"description": "lorem ipsum",
"url": "/5",
"position": {
"left": "-500",
"top": "0"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Develop",
"description": "lorem ipsum",
"url": "/6",
"position": {
"left": "0",
"top": "-500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Desing",
"description": "lorem ipsum",
"url": "/7",
"position": {
"left": "500",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Sociality",
"description": "lorem ipsum",
"url": "/8",
"position": {
"left": "-500",
"top": "-500"
}
}
]
}
class Drag {
drag = {
width: 2560,
height: 1440,
};
mouseOut = false;
constructor(container) {
this.container = container;
let w = container.clientWidth;
let h = container.clientHeight;
let viewSize = h;
let aspectRatio = w / h;
this.viewport = {
viewSize: viewSize,
aspectRatio: aspectRatio,
left: (-aspectRatio * viewSize) / 2,
right: (aspectRatio * viewSize) / 2,
top: viewSize / 2,
bottom: -viewSize / 2,
near: -10,
far: 100
}
this.initScene();
}
initScene() {
this.camera = new THREE.OrthographicCamera(
this.viewport.left, this.viewport.right,
this.viewport.top, this.viewport.bottom,
this.viewport.near, this.viewport.far
);
this.scene = new THREE.Scene();
this.renderer = new THREE.WebGLRenderer({
// alpha: true // чтобы сцена была прозрачной
});
this.renderer.domElement.id = 'canvasGrid';
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setClearColor(0xdcdcdc, 1);
this.container.appendChild(this.renderer.domElement);
// драг контейнер для сцены
const geometry = new THREE.PlaneGeometry(this.drag.width, this.drag.height);
const material = new THREE.MeshBasicMaterial({
color: 0xdcdcdc,
});
this.drag.plane = new THREE.Mesh(geometry, material);
// драг бокс по которому гранимац которого будет двигаться сцена при драге
this.dragBox = new THREE.Box3().setFromObject(this.drag.plane);
this.scene.add(this.drag.plane);
this.sceneObjects();
this.setControls();
this.animate();
window.addEventListener('mouseout', () => this.mouseOut = true, false);
window.addEventListener('mouseover', () => {
this.mouseOut = false;
this.animate();
}, false);
}
sceneObjects() {
// instantiate a loader
const loader = new THREE.TextureLoader();
data.objects.map((item) => {
const group = new THREE.Group();
group.name = item.title;
// load a resource
loader.load(
// resource URL
item.img,
// onLoad callback
function (texture) {
const width = texture.image.naturalWidth * 0.5;
const height = texture.image.naturalHeight * 0.5;
// in this example we create the material when the texture is loaded
const geometry = new THREE.BoxGeometry(width, height, 0);
const material = new THREE.MeshBasicMaterial({map: texture});
const mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
group.position.set(item.position.left, item.position.top, 0);
},
// onProgress callback currently not supported
undefined,
// onError callback
function (err) {
console.error('An error happened.', err);
}
);
this.scene.add(group);
});
const geometry1 = new THREE.BoxGeometry(550, 300, 0);
const texture = new THREE.TextureLoader().load("https://miro.medium.com/max/1400/1*Ynit7J26tXLwyq-sB3AUug.png");
console.log(texture)
const material1 = new THREE.MeshBasicMaterial({map: texture, opacity: 0.3});
const mesh = new THREE.Mesh(geometry1, material1);
this.scene.add(mesh);
}
render() {
// if (this.mouseDownPressed) {
let x1 = this.camera.position.x + (this.camera.left / this.camera.zoom);
let x1a = Math.max(x1, this.dragBox.min.x);
let pos_x = x1a - (this.camera.left / this.camera.zoom);
let x2 = pos_x + (this.camera.right / this.camera.zoom);
let x2a = Math.min(x2, this.dragBox.max.x);
pos_x = x2a - (this.camera.right / this.camera.zoom);
let y1 = this.camera.position.y + (this.camera.bottom / this.camera.zoom);
let y1a = Math.max(y1, this.dragBox.min.y);
let pos_y = y1a - (this.camera.bottom / this.camera.zoom);
let y2 = pos_y + (this.camera.top / this.camera.zoom);
let y2a = Math.min(y2, this.dragBox.max.y);
pos_y = y2a - (this.camera.top / this.camera.zoom);
this.camera.position.set(pos_x, pos_y, this.camera.position.z);
this.camera.lookAt(pos_x, pos_y, this.controls.target.z); // todo: what is it?
this.controls.target.set(pos_x, pos_y, 0);
this.controls.update();
// }
this.renderer.render(this.scene, this.camera);
}
setControls() {
// Need to be similar to what is in OrbitControls3Dpane.js constructor
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.controls.mouseButtons = {
LEFT: THREE.MOUSE.PAN,
MIDDLE: THREE.MOUSE.DOLLY,
RIGHT: THREE.MOUSE.PAN
}
//////////////////////////////////////
// Set rotate related parameters
//////////////////////////////////////
// No rotation.
this.controls.enableRotate = false;
this.controls.minPolarAngle = Math.PI / 2;
this.controls.maxPolarAngle = Math.PI / 2;
// No orbit horizontally.
this.controls.minAzimuthAngle = 0; // radians
this.controls.maxAzimuthAngle = 0; // radians
//////////////////////////////////////
// Set zoom related parameters
//////////////////////////////////////
this.controls.enableZoom = true;
this.controls.zoomSpeed = 0.9;
this.controls.minDistance = this.camera.near;
this.controls.maxDistance = this.camera.far;
this.controls.minZoom = window.innerWidth > window.innerHeight ?
window.innerWidth / this.drag.width : window.innerHeight / this.drag.height;
this.controls.maxZoom = 1 + this.controls.minZoom;
//////////////////////////////////////
// Set pan related parameters
//////////////////////////////////////
this.controls.enablePan = true;
this.controls.panSpeed = 0.6;
this.controls.screenSpacePanning = true;
this.controls.enableDamping = true;
// this.renderer.domElement.addEventListener('mousedown', () => {
// this.mouseDownPressed = true;
// }, false);
// this.renderer.domElement.addEventListener('mouseup', () => {
// setTimeout(() => {
// this.mouseDownPressed = false;
// }, 700);
// }, false);
}
animate() {
this.render();
if (!this.mouseOut) {
requestAnimationFrame(this.animate.bind(this));
}
}
}
function init() {
new Drag(document.querySelector('.canvas'));
}
init();
.canvas {
width: 100vw;
height: 100vh;
}
<!-- partial:index.partial.html -->
<div class="canvas"></div>
<!-- partial -->
<script src='https://threejs.org/build/three.js'></script>
<script src='https://threejs.org/examples/js/controls/OrbitControls.js'></script><script src="./script.js"></script>
我使用“OrthographicCamera”创建了一个场景,并将此相机与 OrbitControls 一起移动,也许这对我来说不是最佳选择,如果是这样 - 请告诉我如何正确操作?
antialias:真正在 WebGLRenderer 解决
所有相同的设置,场景立即变得更流畅,图片没有错误
也就是他降低性能滑出...