Estante 3D: mueble, lomos, logos y vista previa de tomos
This commit is contained in:
@@ -115,9 +115,9 @@ export function fitCamera(points, aspect, marginX, marginY) {
|
||||
// Colores de la portada para la contraportada y sus botones.
|
||||
const luma = c => { const f = v => (v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4); return 0.2126 * f(c[0]) + 0.7152 * f(c[1]) + 0.0722 * f(c[2]) }
|
||||
const contrast = (a, b) => { const x = luma(a), y = luma(b); return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05) }
|
||||
const inkOn = c => (contrast(c, [1, 1, 1]) >= contrast(c, [0.07, 0.06, 0.05]) ? [1, 1, 1] : [0.07, 0.06, 0.05])
|
||||
export const inkOn = c => (contrast(c, [1, 1, 1]) >= contrast(c, [0.07, 0.06, 0.05]) ? [1, 1, 1] : [0.07, 0.06, 0.05])
|
||||
const mixColor = (a, b, t) => a.map((n, k) => n + (b[k] - n) * t)
|
||||
const css = c => `rgb(${c.map(n => Math.round(n * 255)).join(' ')})`
|
||||
export const css = c => `rgb(${c.map(n => Math.round(n * 255)).join(' ')})`
|
||||
// Color dominante y color de acento: el acento es el que más destaca sobre el dominante, sin ser una mota de la imagen.
|
||||
export function coverPalette(data) {
|
||||
const boxes = new Map()
|
||||
@@ -143,7 +143,7 @@ export function coverPalette(data) {
|
||||
}
|
||||
|
||||
// Madera generada: se repite sin que se note el corte.
|
||||
function woodCanvas() {
|
||||
export function woodCanvas() {
|
||||
const S = 1024, PLANKS = 5, canvas = Object.assign(document.createElement('canvas'), { width: S, height: S }), g = canvas.getContext('2d')
|
||||
let seed = 7
|
||||
const rnd = () => (seed = (seed * 16807) % 2147483647) / 2147483647
|
||||
@@ -243,7 +243,7 @@ void main() {
|
||||
}`
|
||||
|
||||
// Junta rejillas en una malla: pos(3) normal(3) uv(2).
|
||||
class Shape {
|
||||
export class Shape {
|
||||
constructor() { this.v = []; this.i = [] }
|
||||
grid(cols, rows, at) {
|
||||
const base = this.v.length / 8
|
||||
@@ -305,8 +305,9 @@ function rimShape(pts, y0, y1, thick) {
|
||||
|
||||
// El sensor: los ejes de la pantalla a partir de la orientación del dispositivo. La inclinación se desvanece con el tiempo.
|
||||
// MAX_DEG: lo que hay que girar el dispositivo para llegar al tope. ORBIT_*: cuánto rodea entonces la cámara al libro, en grados.
|
||||
const MAX_DEG = 15, FADE_S = 2.5, QUIET = 0.6, ORBIT_TILT = 7, ORBIT_YAW = 10, ORBIT_BACK = 0.06
|
||||
function createTilt(onChange) {
|
||||
export const MAX_DEG = 15
|
||||
const FADE_S = 2.5, QUIET = 0.6, ORBIT_TILT = 7, ORBIT_YAW = 10, ORBIT_BACK = 0.06
|
||||
export function createTilt(onChange) {
|
||||
const target = { x: 0, y: 0 }
|
||||
let listening = false, gotOrientation = false, lastT = 0, lastOri = null, lastFade = 0, askOnTouch = null
|
||||
const clamp = v => Math.max(-MAX_DEG, Math.min(MAX_DEG, v))
|
||||
|
||||
Reference in New Issue
Block a user