hakimel / reveal.js

The HTML Presentation Framework
https://revealjs.com
MIT License
67.27k stars 16.64k forks source link

Three.js in reveal.js slide #3131

Open a-i-m-a-r opened 2 years ago

a-i-m-a-r commented 2 years ago

Hi, I am embedding some three.js 3D models in different reveal.js slides this way:

<section>
    <script src="three_r84/model1.js"></script>
    <div id="model1" width="950" height="600" data-prevent-swipe></div>         
</section>

The loaded model1.js file is the following:

document.addEventListener('DOMContentLoaded', function(event) {
    window.requestAnimationFrame = (function() {
        return window.requestAnimationFrame;
    })();

    function animateScene() {
        requestAnimationFrame(animateScene);
        renderScene();
    }

    function startScene() {
        var canvas = document.getElementById('model1');
        render = new THREE.WebGLRenderer({
            antialias: true,
            alpha: true});

        render.setClearColor(0x191919, 0);

        var canvasWidth = canvas.getAttribute('width');
        var canvasHeight = canvas.getAttribute('height');
        render.setSize(canvasWidth, canvasHeight);

        canvas.appendChild(render.domElement);

        scene = new THREE.Scene();
        var aspect = canvasWidth / canvasHeight;

        camera = new THREE.PerspectiveCamera(45, aspect);
        camera.position.set(15, 10, 15);
        camera.lookAt(scene.position);
        scene.add(camera);

        controls = new THREE.OrbitControls(camera);
            controls.enableDamping = true;
            controls.dampingFactor = 0.25;
            controls.enableZoom = true;                                
// concrete columns             
            // define columns geometry
                var columnGeometry = new THREE.BoxGeometry(0.25, 3, 0.4);
            // define columns colors
                function hsl(h, s, l) {
                    return (new THREE.Color()).setHSL(h, s, l);
                }
            // define columns position & pass data (geometry, color, position) to create foundation function
                {
                    makeInstanceColumn(columnGeometry, hsl(0 / 8, 1, .5), 0, -0, 0);
                }            
            // create columns
                function makeInstanceColumn(columnGeometry, color, x, z, y) {
                    [THREE.BackSide, THREE.FrontSide].forEach((side) => {
                        var columnMaterial = new THREE.MeshPhongMaterial({
                            color,
                            opacity: 0.5,
                            transparent: true,
                            side,
                        });
                        var column = new THREE.Mesh(columnGeometry, columnMaterial);
                        scene.add(column);
                        column.position.set(x, z, y);
                    });
                }           
// light
  function addLight(x, z, y) {
    var color = 0xFFFFFF;
    var intensity = 1;
    var light = new THREE.DirectionalLight(color, intensity);
    light.position.set(x, z, y);
    scene.add(light);
  }
  addLight(-1,  2,  4);
  addLight( 1, -1, -2);
    }
    function renderScene() {
        controls.update();
        render.render(scene, camera);
    }
    startScene();
    animateScene();
    renderScene(); 
});

I know its not right because all the scripts in the various slides are loaded together and besides, and this is the main problem: the OrbitControls (zoom, pan, rotate) and gui.dat menu are only linked to the last model, so I can not interact with the models at all.

There is an old working example, but since it uses older versions of three.js and reveal.js, I am unable to understand how to modify it for my case.

I suppose that Chart plugin does something similar to what I seek. Also reveald3, but this seem to load the D3 charts as iframe. I suppose I could create HTML files based on my three.js scripts and load the HTML file as iframe but, is this a recommended procedure? Or should I link the loading of the script file itself to the "slidechanged" event? Personally I think the latter is the approach I am trying to achieve, but I do not know exactly how to code it :-( . Any advice or ideas?

Roberlanderrsilva commented 2 years ago

boa noite, infelizmente ainda não tenho conhecimento para ajudá-lo, pois ainda não cheguei neste ponto, então, parabéns, eu ainda chegarei ai. ;)

a-i-m-a-r commented 2 years ago

I have created a HTML file with the three.js 3D model and loaded it within iframes in my reveal.js presentation succesfully. AFAIK loading lazily iframes unloaded them when leaving the slide and I suppose this is good because it avoids overloading the browser (and this is a great concern to me because I use an old iPad (iOS9.3.5). However, in my great ignorance, I suppose that it requires more network traffic (I loaded the presentation from a server through WIFI) since the origin HTML must load three.js and OrbitControls.js each time I reach a slide with the iframe containing the three.js 3D model, right? For now, I achieve the desired result: interact with each 3D model independently. However, looking for improving the performance or the efriciency, I will continue digging to understand how can I load the three.js stuff only once (when loading the presentation) and direct to the corresponding model's script in each slide containing 3D models, so I can interact with them. Any advice, of course, is highly welcomed.

a-i-m-a-r commented 2 years ago

I meant "efficiency".

FayssalElonsri commented 2 years ago

شكراً جزيلاً

في السبت، 12 فبراير، 2022 21:56 a-i-m-a-r @.***> كتب:

I meant "efficiency".

— Reply to this email directly, view it on GitHub https://github.com/hakimel/reveal.js/issues/3131#issuecomment-1037511773, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARNZZXTNQZVG2XILNMGCT4LU23JSPANCNFSM5OBTR43A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>