Efecto linterna básico

Este ejemplo muestra como podemos usar el efecto sombra para algo más que dar relieve a la pa´goina, se trata de crear una especie de linterna que ilumnia un fondo oscuro para mostar el texto escondido en él

Usamos la propiedad shadow de CSS y el evento de movimiento del ratón

Solución

Vamos a colocar en la página un bloque div (pizarra) relleno con texto (el socorrido lorem ipsum ), pero este texto no se verá porque estará oculto bajo un manto negro.

Ese manto negro proviene de otro bloque div (linterna), redondo, con sombra muy ancha que oculta el bloque pizarra, pero con una zona central por que se ve el texto de pizarra

Un click del ratón coge la linterna y la arrastra por toda la pizarra y otro click la sueta.

<body>

<div class="pizarra" id="pizarra">

   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae consequat erat, id luctus mi. Maecenas metus magna, tristique a fringilla nec, blandit sit amet ex. In quis elit pellentesque, facilisis nisl mollis, tempor augue. Maecenas vel consectetur mauris. Vivamus feugiat metus tempus libero ornare, non ornare tortor efficitur.

   </p>

    <img src="/imgs/funciones-concepto.jpg" style="margin:0 auto" alt="">

   <div class="foco" id="foco"></div>
</div>

</body>

El códgo script lo puedes poner al final de la sección body

<script>

let foco = document.getElementById('foco');

let pizarra = document.getElementById('pizarra');

pizarra.addEventListener('mousedown', toggle);

pizarra.addEventListener('mousemove', mover);

foco.encendida = false;

pizarra.foco = foco;

function toggle(ev){

   let piz = ev.currentTarget;

   let foco = piz.foco;

   foco.encendida = !foco.encendida;

   foco.style.width = (foco.encendida)?"100px":"0";

   foco.style.height = (foco.encendida)?"100px":"0"

   if(foco.encendida){

      mover(event);

      piz.addEventListener('mousemove', mover);

   }else{

      piz.removeEventListener('mousemove', mover)

   }

}

function mover(ev){

   let piz = ev.currentTarget

   let pX = ev.clientX - piz.foco.clientWidth/2 - piz.offsetLeft;

   let pY = ev.clientY - piz.foco.clientHeight/2 - piz.offsetTop;

   piz.foco.style.left = pX + "px";

   piz.foco.style.top = pY + "px";

}

</script>

Y un poco de CSS, fíjate en el ancho de la sombra (box-shadow). La linterna incialmente está apagada (ancho y alto 0)

<style>

.foco {

    position: absolute;

    width: 0px;

    height: 0px;

    box-shadow: 0 0 0 99999px rgb(0, 0, 0);

    border-radius: 50%;

}

.pizarra{

    display: block;

    position: relative;

    overflow: hidden;

    width: 50vw;

    height: 60vh;

    margin: 0 auto;

    cursor: grab;

}

</style>

Explicación

Para crear este efecto se aprovecha la proieadad shadow de CSS para crear una sombra al bloque foco que cubre todo el bloque pizarra.

Si el foco tiene alto y ancho cero no se verá nada porque pizarra está cubierto por la sombra

Cuando el foco tiene dimensiones distintas de cero será visible y al ser transparente se podrá ver toda la pizarra.

Basta con dos eventos :

  • mousedown: para encender la llinterna
  • mousemove para desplazarla.

Al bloque del foco le asignamos la propiedad encendida, un valor booleano para comprobar si es visible (true) o no (false).

Y este bloque foco lo ponemos como propiedad del bloque pizarra para acceder a él directamente dentro de las funciones gestoras de los eventos.

Encender la linterna (al hacer click en el área de la pizarra) significa que el foco se vea, eso se consigue poniéndole su tamaño  a un valor mayor que cero y apagarla es ponerlo a 0, tanto el alto como el ancho. Una vez encendida lo colocamos en su lugar, que es donde haya cllickado el ratón.

Para mover el foco con el ratón usamos el evento mousemove cuya función gestora (mover) mira la posición del cursor en la ventana (posiciones del ratón cuando lo pulsamos) y calcula a partir de ella la posición la del bloque foco:

La posición del cursor es relativa a la ventana del navegador, le restamos la posición del bloque pizarra para referirla a éste y luego el radio para poner el centro del foco donde esté el cursor.

Dentro de los gestores de eventos accedemos a la pizarra a través de currentTarget de esta manera podemos acceder al objeto foco (la luz de la linterna) porque la pusimos como propiedad de la pizarra.

Tienes otra forma de crear est efecto usando un objeto, objeto linterna, es aonsejable verlo también si quieres practicar con los objetos en Javasript