Más curvatura al agarrar la hoja por arriba o por abajo, con el lomo fijo
- Curvatura de 14° en el plano de la página y 10° hacia quien lee. - La tira del lomo no se curva, así que la hoja no se separa del libro. - Más solape entre tiras al curvarse, para que no se abran huecos. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+10
-9
@@ -1571,12 +1571,13 @@ async function viewReader(mangaId, chapterId, startPage) {
|
|||||||
// Hoja de papel que se dobla: tiras verticales anidadas, cada una girada un poco respecto a la anterior,
|
// Hoja de papel que se dobla: tiras verticales anidadas, cada una girada un poco respecto a la anterior,
|
||||||
// así que la hoja forma una curva. Cada tira enseña su trozo de la página por delante y del reverso
|
// así que la hoja forma una curva. Cada tira enseña su trozo de la página por delante y del reverso
|
||||||
// (la página siguiente en doble página, o papel en blanco) por detrás.
|
// (la página siguiente en doble página, o papel en blanco) por detrás.
|
||||||
function paperCurl(r, frontSrc, backSrc, spineLeft) {
|
function paperCurl(r, frontSrc, backSrc, spineLeft, bent = false) {
|
||||||
const N = Math.max(10, Math.min(22, Math.round(r.w / 24)))
|
const N = Math.max(10, Math.min(22, Math.round(r.w / 24)))
|
||||||
const w = r.w / N
|
const w = r.w / N
|
||||||
// Cada cara se sale OV px por los lados de su tira para tapar la unión con la vecina: sin solape,
|
// Cada cara se sale OV px por los lados de su tira para tapar la unión con la vecina: sin solape,
|
||||||
// Safari deja una rendija oscura entre tiras.
|
// Safari deja una rendija oscura entre tiras.
|
||||||
const OV = 1.5
|
// Curvada, las tiras dejan de encajar justas lejos del punto fijo: hace falta más solape.
|
||||||
|
const OV = bent ? 4 : 1.5
|
||||||
const sgn = spineLeft ? -1 : 1 // hacia dónde gira: el borde libre se levanta hacia quien mira
|
const sgn = spineLeft ? -1 : 1 // hacia dónde gira: el borde libre se levanta hacia quien mira
|
||||||
const el = document.createElement('div')
|
const el = document.createElement('div')
|
||||||
el.className = 'curl'
|
el.className = 'curl'
|
||||||
@@ -1610,15 +1611,15 @@ async function viewReader(mangaId, chapterId, startPage) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
// Devuelve cuánto está levantada la hoja (0 a 1), para la sombra de debajo.
|
// Devuelve cuánto está levantada la hoja (0 a 1), para la sombra de debajo.
|
||||||
// tiltZ/tiltX: curvatura total de la hoja agarrada por arriba o por abajo. Se reparte entre las tiras, de modo
|
// tiltZ/tiltX: curvatura total de la hoja agarrada por arriba o por abajo. Se reparte entre las tiras salvo la
|
||||||
// que junto al lomo apenas se nota y el borde libre se lleva todo: la hoja sigue pegada al libro. Cambia de
|
// del lomo, que no se curva, y el borde libre se lleva todo: la hoja sigue pegada al libro. Cambia de
|
||||||
// signo con la cara visible para que la parte agarrada vaya siempre por delante.
|
// signo con la cara visible para que la parte agarrada vaya siempre por delante.
|
||||||
function set(g, reverse, tiltZ = 0, tiltX = 0) {
|
function set(g, reverse, tiltZ = 0, tiltX = 0) {
|
||||||
let prev = 0, lift = 0
|
let prev = 0, lift = 0
|
||||||
angles(g, reverse).forEach((a, i) => {
|
angles(g, reverse).forEach((a, i) => {
|
||||||
const t = strips[i]
|
const t = strips[i]
|
||||||
const c = Math.cos((a * Math.PI) / 180)
|
const c = Math.cos((a * Math.PI) / 180)
|
||||||
const bend = tiltZ || tiltX ? ` rotateZ(${((tiltZ * c) / N).toFixed(3)}deg) rotateX(${((tiltX * c) / N).toFixed(3)}deg)` : ''
|
const bend = i && (tiltZ || tiltX) ? ` rotateZ(${((tiltZ * c) / (N - 1)).toFixed(3)}deg) rotateX(${((tiltX * c) / (N - 1)).toFixed(3)}deg)` : ''
|
||||||
t.s.style.transform = `${i ? `translateX(${step}px) ` : ''}rotateY(${(sgn * (a - prev)).toFixed(2)}deg)${bend}`
|
t.s.style.transform = `${i ? `translateX(${step}px) ` : ''}rotateY(${(sgn * (a - prev)).toFixed(2)}deg)${bend}`
|
||||||
prev = a
|
prev = a
|
||||||
// Se oscurece al inclinarse. Con un filtro en la propia cara y no con una capa negra encima: en Safari
|
// Se oscurece al inclinarse. Con un filtro en la propia cara y no con una capa negra encima: en Safari
|
||||||
@@ -1654,7 +1655,7 @@ async function viewReader(mangaId, chapterId, startPage) {
|
|||||||
const pivot = y => strips.forEach(t => { t.s.style.transformOrigin = `${spineLeft ? 'left' : 'right'} ${y}` })
|
const pivot = y => strips.forEach(t => { t.s.style.transformOrigin = `${spineLeft ? 'left' : 'right'} ${y}` })
|
||||||
return { el, set, span, solve, pivot }
|
return { el, set, span, solve, pivot }
|
||||||
}
|
}
|
||||||
const GRAB_TILT_Z = 8, GRAB_TILT_X = 6 // curvatura total, en grados, de la hoja agarrada por arriba o por abajo
|
const GRAB_TILT_Z = 14, GRAB_TILT_X = 10 // curvatura total, en grados, de la hoja agarrada por arriba o por abajo
|
||||||
// drag: la página sigue al dedo; devuelve el control (move/release) en vez de animarse sola.
|
// drag: la página sigue al dedo; devuelve el control (move/release) en vez de animarse sola.
|
||||||
function turnPage(old, stage, dir, drag = false) {
|
function turnPage(old, stage, dir, drag = false) {
|
||||||
// "Delante" es hacia la izquierda en izq→der (la hoja derecha pasa a la izquierda) y al revés en der→izq.
|
// "Delante" es hacia la izquierda en izq→der (la hoja derecha pasa a la izquierda) y al revés en der→izq.
|
||||||
@@ -1731,7 +1732,9 @@ async function viewReader(mangaId, chapterId, startPage) {
|
|||||||
const drop = document.createElement('i')
|
const drop = document.createElement('i')
|
||||||
drop.className = `curldrop ${spineLeft ? 'l' : 'r'}`
|
drop.className = `curldrop ${spineLeft ? 'l' : 'r'}`
|
||||||
place(drop, rect)
|
place(drop, rect)
|
||||||
const curl = paperCurl(rect, frontSrc, backSrc, spineLeft)
|
const grabAt = drag && grabY != null ? (grabY - B.top - rect.t) / rect.h : 0.5
|
||||||
|
const grab = grabAt < 1 / 3 ? -1 : grabAt > 2 / 3 ? 1 : 0
|
||||||
|
const curl = paperCurl(rect, frontSrc, backSrc, spineLeft, !!grab)
|
||||||
place(curl.el, rect)
|
place(curl.el, rect)
|
||||||
box.append(drop, curl.el)
|
box.append(drop, curl.el)
|
||||||
extra.push(drop, curl.el)
|
extra.push(drop, curl.el)
|
||||||
@@ -1739,8 +1742,6 @@ async function viewReader(mangaId, chapterId, startPage) {
|
|||||||
// Agarrada por arriba o por abajo (tercio superior o inferior), esa parte va por delante: la hoja se curva
|
// Agarrada por arriba o por abajo (tercio superior o inferior), esa parte va por delante: la hoja se curva
|
||||||
// sin separarse del lomo. Sin capas nuevas; es 0 al principio y al final del giro, así que cae exacta.
|
// sin separarse del lomo. Sin capas nuevas; es 0 al principio y al final del giro, así que cae exacta.
|
||||||
// Por el centro, como siempre.
|
// Por el centro, como siempre.
|
||||||
const grabAt = drag && grabY != null ? (grabY - B.top - rect.t) / rect.h : 0.5
|
|
||||||
const grab = grabAt < 1 / 3 ? -1 : grabAt > 2 / 3 ? 1 : 0
|
|
||||||
if (grab) curl.pivot(grab < 0 ? 'bottom' : 'top')
|
if (grab) curl.pivot(grab < 0 ? 'bottom' : 'top')
|
||||||
step = g => {
|
step = g => {
|
||||||
const k = grab ? grab * Math.sin(Math.PI * Math.min(1, Math.max(0, (g - g0) / (g1 - g0 || 1)))) : 0
|
const k = grab ? grab * Math.sin(Math.PI * Math.min(1, Math.max(0, (g - g0) / (g1 - g0 || 1)))) : 0
|
||||||
|
|||||||
Reference in New Issue
Block a user