Измените родительский элемент компонента и сохраните позицию

Я использую AR.js и располагаю сферу в компоненте маркера.

<body style="margin : 0px; overflow: hidden;">
    <a-scene vr-mode-ui="enabled: false" embedded="" arjs="sourceType: webcam; debugUIEnabled: false;">
        <a-marker markerhandler id="marker" emitevents="true" cursor="rayOrigin: mouse" preset="hiro">
            <a-sphere id="sphere" color="green" radius="0.3" position="0 1 0" ></a-sphere>
        </a-marker>
        <!-- use this <a-entity camera> to support multiple-markers, otherwise use <a-marker-camera> instead of </a-marker>-->
        <a-entity camera="" id="camera">
                <a-entity geometry="primitive: plane; height: 0.1; width: 0.1" position="0.4 -0.2 -1"
                material="color: gray; opacity: 0.5"></a-entity>
                <a-entity id="sphere-button" geometry="primitive: plane; height: 0.1; width: 0.1" position="-0.4 -0.2 -1"
                material="color: green; opacity: 0.5"></a-entity>
        </a-entity>
    </a-scene>  
  </body>

При щелчке по # сфера-кнопка сфера должна отсоединиться от и прикрепить к камере. Во время перемещения в DOM позиция должна оставаться то же самое, но это не так. Я пробовал это:

let v = new THREE.Vector3();
v.copy(sphere.object3D.position);
sphere.object3D.localToWorld(v);
camera.object3D.worldToLocal(v);
sphere.parentNode.removeChild(entity);
camera.appendChild(sphere);
entity.setAttribute('position', v);

Как правильно перевести позицию между двумя родителями камера и маркер?

Взгляните на методы .attach() и .detach()THREE.SceneUtils.

prisoner849 13.09.2018 18:46

Вероятный дубликат: stackoverflow.com/questions/35364409/…

WestLangley 13.09.2018 18:59

Получаю ошибку THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js

Thmsbrhn 13.09.2018 19:01
1
3
725
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Для повторного родительства я бы сейчас сделал это на уровне three.js и не использовал DOM. Отсоединение и присоединение к атм DOM приведет к повторной инициализации всего и будет беспорядком.

let v = new THREE.Vector3();
v.copy(sphere.object3D.position);
sphere.object3D.localToWorld(v);
camera.object3D.worldToLocal(v);
camera.object3D.add(sphere.object3D);
sphere.object3D.position.copy(v);

В этом коде есть опечатка. camera.object3D.add(sphere); должен быть camera.object3D.add(sphere.object3D);

Richard Kennard 13.06.2019 06:41

Я пробовал другой подход, используя object3D.attach (как было предложено @ Prisoner849 в комментарии), чтобы получить положение, вращение и т. д. Объекта Three, связанного с предполагаемым родителем, а затем клонировать объект, используя это положение, вращение, ... под предполагаемым родителем (наконец, удалив исходный объект).

Вы можете увидеть компонент, реализующий этот подход, в этот ответ на «AFrame: повторное создание элемента с сохранением его положения в мире, вращение».

Другие вопросы по теме