Raycasting support for French beginner please :)

Hello
I would like to add an “hover effect” if I can say this way. To be explicite, I would like, when the mouse is over one image, that this image stay visible and at the same place, but with just a big title added and a background color so that the original scene (other images and canvas)is no more visible. To be even more precise, my purpose is that those images are the main navigation system of my website.

What can I do ? I know that my writing sounds like neophyte, that’s because I am and French on top of that… Well I need a raycaster but I really don’t know how to begin, what specific code do I need ?

Hoping it’s clear enough, thanks for your help, you’re a love :wink:

Ps : I’ve already searched for similar topic, but I can’t understand anything so I need a help and hand on my specific situation, please be indulgent

This is my code (with just 2 images to not make it too long) :

import * as THREE from ‘https://cdn.jsdelivr.net/npm/three@0.118/build/three.module.js’;

const SCREEN_WIDTH = window.innerWidth;
        const SCREEN_HEIGHT = window.innerHeight;

        let container;

        let camera, scene, renderer;

        let mouseX = 0, mouseY = 0;

        const windowHalfX = window.innerWidth / 2;
        const windowHalfY = window.innerHeight / 2;

        init();
        animate();


        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 35, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 5000 );
            camera.position.z = 1500;

            scene = new THREE.Scene();
            scene.background = new THREE.Color( 0xffffff );
            scene.fog = new THREE.Fog( 0xffffff, 1500, 4000 );

            // GROUND

            const imageCanvas = document.createElement( "canvas" );
            const context = imageCanvas.getContext( "2d" );

            imageCanvas.width = imageCanvas.height = 128;

            context.fillStyle = "#ffffff";
            context.fillRect( 0, 0, 128, 128 );

            context.fillStyle = "#ffffff";
            context.fillRect( 0, 0, 64, 64 );
            context.fillRect( 64, 64, 64, 64 ); 

            const textureCanvas = new THREE.CanvasTexture( imageCanvas );
            textureCanvas.repeat.set( 1000, 1000 );
            textureCanvas.wrapS = THREE.RepeatWrapping;
            textureCanvas.wrapT = THREE.RepeatWrapping;
        

            const materialCanvas = new THREE.MeshBasicMaterial( { map: textureCanvas } );

            const geometry = new THREE.PlaneGeometry( 100, 100 );

            const meshCanvas = new THREE.Mesh( geometry, materialCanvas );
            meshCanvas.rotation.x = - Math.PI / 2;
            meshCanvas.scale.set( 1000, 1000, 1000 );
            

            // PAINTING 1

            const callbackPainting = function () {

                const image = texturePainting.image;

                scene.add( meshCanvas );

                const geometry = new THREE.PlaneGeometry( 100, 100 );
                const mesh = new THREE.Mesh( geometry, materialPainting );
                

                addPainting( scene, mesh );
                
                function addPainting( zscene, zmesh ) {
                    

                    zmesh.scale.x = image.width / 60;
                    zmesh.scale.y = image.height / 60;
                    zmesh.position.z = 300.0;
                    zmesh.position.x = -215.0;
                    zmesh.position.y = -80.0;
                    
                    zscene.add( zmesh );
                    
                
                    const floorHeight = - 8 * image.height / 2;
                    meshCanvas.position.y =  floorHeight;

                }
                


            };
            

            const texturePainting = new THREE.TextureLoader().load( "image/1.jpg", callbackPainting );
            const materialPainting = new THREE.MeshBasicMaterial( { color: 0xffffff, map: texturePainting } );
            
            
            // PAINTING 2

            const callbackPainting2 = function () {

                const image = texturePainting2.image;

                scene.add( meshCanvas );

                const geometry = new THREE.PlaneGeometry( 100, 100 );
                const mesh2 = new THREE.Mesh( geometry, materialPainting2 );
                

                addPainting( scene, mesh2 );
                
                function addPainting( zscene, zmesh2 ) {
                    

                    zmesh2.scale.x = image.width / 40;
                    zmesh2.scale.y = image.height / 40;
                    zmesh2.position.z = 70.0;
                    zmesh2.position.x = 0.0;
                    zmesh2.position.y = -100.0;
                    
                    
                    zscene.add( zmesh2 );
                    
                    const floorHeight = - 8 * image.height / 2;
                    meshCanvas.position.y =  floorHeight;

                }
                


            };
            
            const texturePainting2 = new THREE.TextureLoader().load( "image/2.jpg", callbackPainting2 );
            const materialPainting2 = new THREE.MeshBasicMaterial( { color: 0xffffff, map: texturePainting2 } );
            
            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
            renderer.autoClear = false;

            renderer.domElement.style.position = "relative";
            container.appendChild( renderer.domElement );

            document.addEventListener( 'mousemove', onDocumentMouseMove );

        }


        function onDocumentMouseMove( event ) {

            mouseX = ( event.clientX - windowHalfX );
            mouseY = ( event.clientY - windowHalfY );

        }


        function animate() {

            requestAnimationFrame( animate );

            render();

        }

        function render() {

            camera.position.x += ( mouseX - camera.position.x ) * .05;
            camera.position.y += ( - ( mouseY - 100 ) - camera.position.y ) * .05;

            camera.lookAt( scene.position );

            renderer.clear();
            renderer.setScissorTest( true );

            renderer.setScissor( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT );
            renderer.render( scene, camera );

        }

TBH, the code is already too complex for investigating the issue. I have copied your code into a fiddle to see the rendered output but it’s not clear to me what you are trying to achieve.

Do you mind simplifying the code?

In any event, the basic for raycasting are demonstrated by this simple official example. I always recommend it when beginners what to implement interaction in their app:

https://threejs.org/examples/#webgl_interactive_cubes

Thank you for your answer. I understand that the code is long and complex. To simplify I can say that my code structure is the same as this one : three.js examples

I would like, when mouse is over the painting that the all background (fog and canvas) is replaced by a background color and a title, something like this website : http://isaidicanshout.com

Thank you for this example (with interactive cubes), but to be honest, as it’s completely different from what I’m looking for, this makes thing too complicated for my neophyte understanding, I wish I could understand but for the moment I’m lost…

Thank you again for your help :slight_smile:

As a beginner, I would break the task into parts and then try to combine them.

On the one hand the raycasting with simple reactions and on the other hand the desired reaction. This could be tested first by keyboard event.

You can find a simple raycasting in the collection.

Beginner example step 10

2 Likes