Un calendario de hojas que se pueden arrancar, con física de tela propia
Cada mes es una hoja simulada en 3D: tiras de ella, se curva, se rasga por donde tires y los trozos sueltos caen. Escrito desde cero en JavaScript y WebGL, sin librerías, sin imágenes de terceros y sin enviar nada a ningún servidor.
Pruébalo: arranca la hoja
Agarra una esquina de la hoja y tira hacia abajo. Si sueltas a medias, se queda colgando de lo que no se ha roto; si la arrancas entera, cae y aparece el mes siguiente. Con el teclado, Intro sobre la hoja la arranca.
Reescrito desde cero
Una versión anterior de este experimento partía de una demo de tela desgarrable de otro desarrollador. Esta versión no usa su código, ni sus imágenes, ni librerías: la simulación, el dibujo, las hojas del calendario y la interfaz están escritos para este proyecto.
No se carga ninguna tipografía, imagen ni script de terceros. Las notas, colores y emojis que añadas a un día se guardan solo en el localStorage de tu navegador: no se envían a ningún servidor y puedes borrarlos limpiando los datos del sitio.
Un almanaque que se puede usar
No es solo un efecto: es un calendario completo con la física encima.
Cada hoja se dibuja por código a la medida de la pantalla: nombre del mes, iniciales de los días, cuadrícula con años bisiestos y el día de hoy marcado. Botón «Volver» para el mes anterior, también entre años, y «Hoy» para saltar al mes actual.
Texto libre de hasta 300 caracteres, un color de fondo y un emoji para cada día, con paneles accesibles que se cierran con el teclado.
La hoja se rompe por donde tires y el corte sigue la dirección del tirón. Lo que queda suelto cae por gravedad desde el punto de ruptura. Cuando casi nada cuelga de las anillas, la hoja se desprende y entra la siguiente.
Funciona con el dedo y con el ratón, usa 100dvh para que no se rompa cuando aparecen o desaparecen las barras del móvil y, si el navegador no tiene WebGL o no consigue pintar, muestra la hoja plana con un aviso en lugar de una pantalla en blanco.
Cómo está construido
La hoja es una malla de partículas en 3D. La posición siguiente se calcula a partir de las dos anteriores y unas restricciones de distancia (horizontales, verticales, diagonales y de flexión) mantienen la forma. La flexión es la que hace que se curve como papel y no como una tela suelta.
Una restricción se elimina cuando se estira más de su umbral, que varía un poco de una a otra para que el corte no siga la cuadrícula. Junto a un corte ya abierto el papel cede con menos esfuerzo, así la grieta avanza en la dirección del tirón. La fila de arriba, junto a las anillas, es una perforación más débil.
Cámara con perspectiva, luz difusa suave, reverso de la hoja como papel casi blanco y una sombra en tres pasadas sobre la hoja de debajo. El borde rasgado sale de un mapa de las celdas que siguen enteras, suavizado y con ruido, para que un corte en diagonal no se vea en escalera.
Cada mes se pinta en un lienzo 2D y se sube como textura de la malla. No hay imágenes: cambian los colores de cada mes, las notas y los emojis, y todo se redibuja al instante.
Eventos de puntero y teclado con compensación de la perspectiva, para que el punto agarrado siga bajo el dedo. Guarda las notas en localStorage y detecta si WebGL no pinta para pasar a la hoja plana.
La simulación no depende del navegador, así que se prueba con Node: reposo, rotura progresiva, caída, tirón corto sin rotura, profundidad y normales.
Un experimento de física web
Lo que más trabajo dio no fue romper la tela, sino que el papel pareciera papel: una tela suelta se arruga, y un papel se curva. Hacer que el corte siguiera el tirón sin dibujar la cuadrícula de la malla, y que un trozo diminuto no desapareciera al plegarse, fueron los problemas que más iteraciones llevaron.
github.com/yelmartinezseo/tyel-tear-test: el código es propio de Yel Martínez / Greentech y se publica con licencia MIT. También puedes leerlo tal cual se ejecuta en la demo: cloth.js (física), gl.js (WebGL), sheet.js (hojas) y app.js (interfaz). Si reutilizas partes significativas, mantén el aviso de copyright y la licencia.