title: Three JS: OrbitControls the pixel of picture jumps when dragging
body: <p>I recently started to deal with 3d, I want to move around the scene, but when dragging, I see how the pixels in the pictures start jumping before the camera stops moving. This is clearly the wrong job</p>
  <p>Why is this happening? And how to avoid it?
  My code: <a href="https://codepen.io/davedev13/pen/zYEyxRX" rel="nofollow noreferrer">https://codepen.io/davedev13/pen/zYEyxRX</a></p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>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', () =&gt; this.mouseOut = true, false);
          window.addEventListener('mouseover', () =&gt; {
              this.mouseOut = false;
              this.animate();
          }, false);
      }
  
  
  
      sceneObjects() {
          // instantiate a loader
          const loader = new THREE.TextureLoader();
  
          data.objects.map((item) =&gt; {
              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 &gt; 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', () =&gt; {
          //  this.mouseDownPressed = true;
          // }, false);
  
          // this.renderer.domElement.addEventListener('mouseup', () =&gt; {
          //  setTimeout(() =&gt; {
          //      this.mouseDownPressed = false;
          //  }, 700);
          // }, false);
      }
  
      animate() {
          this.render();
  
          if (!this.mouseOut) {
              requestAnimationFrame(this.animate.bind(this));
          }
      }
  }
  
  function init() {
      new Drag(document.querySelector('.canvas'));
  }
  
  init();</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.canvas {
    width: 100vw;
    height: 100vh;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!-- partial:index.partial.html --&gt;
  &lt;div class="canvas"&gt;&lt;/div&gt;
  &lt;!-- partial --&gt;
    &lt;script src='https://threejs.org/build/three.js'&gt;&lt;/script&gt;
  &lt;script src='https://threejs.org/examples/js/controls/OrbitControls.js'&gt;&lt;/script&gt;&lt;script  src="./script.js"&gt;&lt;/script&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>I created a scene using &quot;OrthographicCamera&quot; and move this camera along with OrbitControls, perhaps this is not the best option in my case, if so - tell me how to do it correctly?</p>