What is causing the blue outliner cube to get into the right position after I hit a key on the keyboard in my code?

I have this Three.js code and like for as basic as it is, is working fine at some degree. Whenever I drag the blue cube with TransformControls the blue cube detect collision but leaves a big gap in between while moving the cube with arrows is much better and correct. What is causing this behavior on this code?


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js Configurator with Collision Detection</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/TransformControls.js"></script>
    <script>
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        camera.position.z = 5;

        window.addEventListener('resize', () => {
            const width = window.innerWidth;
            const height = window.innerHeight;
            renderer.setSize(width, height);
            camera.aspect = width / height;
            camera.updateProjectionMatrix();
        });

        const ambientLight = new THREE.AmbientLight(0x404040);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
        directionalLight.position.set(1, 1, 1).normalize();
        scene.add(directionalLight);

        const geometry1 = new THREE.BoxGeometry(1, 1, 1);
        const material1 = new THREE.MeshStandardMaterial({ color: 0x4caf50 });
        const cube1 = new THREE.Mesh(geometry1, material1);
        scene.add(cube1);

        const geometry2 = new THREE.BoxGeometry(1, 1, 1);
        const material2 = new THREE.MeshStandardMaterial({ color: 0x4caf50 });
        const cube2 = new THREE.Mesh(geometry2, material2);
        cube2.position.set(2, 0, 0);
        scene.add(cube2);

        const boxHelper1 = new THREE.BoxHelper(cube1, 0xff0000);
        scene.add(boxHelper1);

        const boxHelper2 = new THREE.BoxHelper(cube2, 0x0000ff);
        scene.add(boxHelper2);

        const transformControls = new THREE.TransformControls(camera, renderer.domElement);
        transformControls.attach(cube2);
        scene.add(transformControls);

        let isDragging = false;
        let previousPosition = cube2.position.clone();

        transformControls.addEventListener('dragging-changed', (event) => {
            controls.enabled = !event.value;
            isDragging = event.value;
        });

        transformControls.addEventListener('objectChange', () => {
            if (isDragging) {
                if (checkCollision(cube1, cube2)) {
                    cube2.position.copy(previousPosition);
                    transformControls.detach();
                    isDragging = false;
                } else {
                    previousPosition.copy(cube2.position);
                }
            }
        });

        function checkCollision(obj1, obj2, tolerance = 0.01) {
            const box1 = new THREE.Box3().setFromObject(obj1).expandByScalar(-tolerance);
            const box2 = new THREE.Box3().setFromObject(obj2).expandByScalar(-tolerance);
            return box1.intersectsBox(box2);
        }

        function snapToGrid(position, gridSize = 0.1) {
            return Math.round(position / gridSize) * gridSize;
        }

        function animate() {
            requestAnimationFrame(animate);
            boxHelper1.update();
            boxHelper2.update();

            if (!isDragging) {
                if (checkCollision(cube1, cube2)) {
                    cube2.material.color.set(0xf44336);
                } else {
                    cube2.material.color.set(0x4caf50);
                }
            }

            renderer.render(scene, camera);
        }

        animate();

        document.addEventListener('keydown', (event) => {
            const speed = 0.1;

            if (!cube1 || !cube2) return;

            const originalPosition = cube2.position.clone();

            switch (event.key) {
                case 'ArrowUp':
                    cube2.position.y += speed;
                    break;
                case 'ArrowDown':
                    cube2.position.y -= speed;
                    break;
                case 'ArrowLeft':
                    cube2.position.x -= speed;
                    break;
                case 'ArrowRight':
                    cube2.position.x += speed;
                    break;
            }

            cube2.position.x = snapToGrid(cube2.position.x);
            cube2.position.y = snapToGrid(cube2.position.y);

            if (checkCollision(cube1, cube2)) {
                cube2.position.copy(originalPosition);
            }
        });
    </script>
</body>
</html>