Холст (Three.js) сценарий с Angular

0

Я создаю серию веб-приложений внутри Angular SPA. Каждое из этих приложений расположено внутри шаблона с угловыми углами, а между ними перемещается полоска и заменяет соответствующие элементы DOM и запускает скрипты из контроллеров.

Мой вопрос здесь более общий: при переходе от сцены Three.js и навигации назад, очевидно, что элементы DOM и сами скрипты перезапускаются, в результате чего сцена начинается с "нуля". Есть ли способ сохранить сцену в фоновом режиме, чтобы пользователь мог вернуться к приложению и быть там, где они остановились?

Это даже целесообразно? Я знаю, что метод requestAnimationFrame останавливает анимацию, когда пользователь переходит на другую вкладку, но как это работает в угловом контексте?

Например, здесь веб-страница WIP. Попробуйте перейти от вкладки StarFinder, а затем обратно, и вы поймете, что я имею в виду.

EDIT: Здесь JSFiddle, чтобы продемонстрировать, что я имею в виду (в этом случае он изменяет DOM без углового).

Действительно, бит, о котором идет речь, - это средство визуализации, которое получает повторное инициирование при навигации назад:

function render() {
        requestAnimationFrame(render);
        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
        renderer.render(scene, camera);
    }
render();
Теги:
canvas
three.js

2 ответа

0

Если вы используете ui-router, вы можете загрузить остальную часть своего сайта во вложенном виде, а затем просто скрыть div в родительском представлении, в котором есть ваша анимация, без фактической разгрузки. Поместите requestAnimationFrame(render); в выражении if который проверяет логический флаг. Затем обновите этот флаг, когда ваш маршрут изменится. См. Мой ответ здесь, чтобы узнать, как определить изменения маршрута. Если вы переходите к своей сцене, а затем вызовите render() чтобы снова запустить анимацию.

Другой вариант может состоять в том, чтобы разрешить его выгрузку, но сохранить любые большие активы и/или настройки для вашей анимации в localStorage, чтобы время запуска было меньше.

  • 0
    Мне бы хотелось, чтобы в анимации снова был доступ, поэтому я проверю ваше первое предложение. Приветствия.
0

угловое уничтожение DOM при перекомпиляции шаблона, а THREE.js использует средство рендеринга webGL, привязанное к холсту.

Если у вас есть только один рендеринг холста за один раз для THREE.js, я бы рекомендовал использовать внешний холст и перенести его в директиву при создании и вернуться к статическому контейнеру при удалении (с помощью $ destroy)

попробуй это:

создать директиву, которая будет прослушивать испускания для отображения/скрытия событий и создания функционального трехмерного холста

затем поместите этот селектор директивы в DOM за пределы изменяющегося шаблона

как это

app.directive('threejsCanvas', function directive() {
  return {
    link: function(scope){
      var scene = new THREE.Scene();
      
      // create a temp holder to save the canvas outside of canvas
      var tempHolder = document.createElement('div');
      tempHolder.style.display = 'none';
      window.document.body.appendChild(tempHolder);
      
      var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
      var renderer = new THREE.WebGLRenderer();
      document.body.appendChild( renderer.domElement );
      
      scope.$on('start:webgl', function(view, callback) {
        view.appendChild(renderer.domElement);
        
        // you may do somthing like ...
        // renderer.setSize( view.innerWidth, view.innerHeight );
        // and change camera ratio if it have to change
        
        // pass the arguments to the caller callback so the script can interact with the canvas singleton
        callback({
          scene: scene,
          camera: camera,
          renderer: renderer
        });
      });  
      
      scope.$on('$destroy', function() {
        // move canvas away from template so it not destroyed
        tempHolder.appendChild(renderer.domElement);
      });
    }
  };
});
<div class="container">
  <threejs-canvas></threejs-canvas>
  <div ng-view></div>
</div>

поэтому вам просто нужно исправить из вашего контроллера элемент, в котором вы хотите, чтобы холст отображал и передал обратный вызов, чтобы получить объекты THREE.js

  • 0
    Мне тоже нравится такой подход. Может быть, вы могли бы объединить его с моим решением и приостановить рендеринг, пока он находится в tempHolder чтобы сохранить tempHolder работы сайта.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню