From: Vincent Vanwaelscappel Date: Mon, 30 Sep 2024 16:14:58 +0000 (+0200) Subject: wait #7092 @1.5 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=e40d0b176aea33a34e4ad8d2045c3d5976da5466;p=fluidbook-html5.git wait #7092 @1.5 --- diff --git a/js/libs/fluidbook/fluidbook.js b/js/libs/fluidbook/fluidbook.js index e43d3736..fd900e2f 100644 --- a/js/libs/fluidbook/fluidbook.js +++ b/js/libs/fluidbook/fluidbook.js @@ -177,6 +177,12 @@ Fluidbook.prototype = { this.help = new FluidbookHelp(this); this.articles = new FluidbookArticles(this); + try { + $('head').append(''); + } catch (e) { + + } + $(this).trigger('fluidbook.lib.ready'); @@ -698,6 +704,7 @@ Fluidbook.prototype = { } } + var s = $("#shadow,#edges"); var s_in = []; diff --git a/js/libs/fluidbook/fluidbook.pagetransitions.js b/js/libs/fluidbook/fluidbook.pagetransitions.js index cff6290a..2c541509 100644 --- a/js/libs/fluidbook/fluidbook.pagetransitions.js +++ b/js/libs/fluidbook/fluidbook.pagetransitions.js @@ -306,7 +306,8 @@ FluidbookPageTransition.prototype = { centerBook: function (center, animationDuration) { var animate = animationDuration !== undefined && animationDuration > 0; - var move = $("#center-fluidbook,#center-shadow,#l_tabs .tabs"); + var moveTransform = $("#center-fluidbook,#l_tabs .tabs"); + var move = $("#center-shadow"); var currentLeft = $("#center-fluidbook").data('left'); var left = 0; if (center === undefined) { @@ -324,14 +325,17 @@ FluidbookPageTransition.prototype = { if (animate) { $(move).addClass('animate'); + $(moveTransform).addClass('animate'); } else { $(move).removeClass('animate'); + $(moveTransform).removeClass('animate'); } var $this = this; var delay = this.fluidbook.support.android ? this.fluidbook.settings.mobileTransitionDuration * 1000 : 10; setTimeout(function () { - move.transform({translateX: left + 'px'}); + moveTransform.transform({translateX: left + 'px'}); + move.css('left', left); $this.fluidbook.resize.updateFluidbookRect(); }, delay); }, diff --git a/js/libs/fluidbook/fluidbook.utils.js b/js/libs/fluidbook/fluidbook.utils.js index c3c832c8..8ccf07ed 100644 --- a/js/libs/fluidbook/fluidbook.utils.js +++ b/js/libs/fluidbook/fluidbook.utils.js @@ -181,3 +181,252 @@ function relayIframeScrollToView(iframe) { } + +class Color { + constructor(r, g, b) { + this.set(r, g, b); + } + + toString() { + return `rgb(${Math.round(this.r)}, ${Math.round(this.g)}, ${Math.round(this.b)})`; + } + + set(r, g, b) { + this.r = this.clamp(r); + this.g = this.clamp(g); + this.b = this.clamp(b); + } + + hueRotate(angle = 0) { + angle = angle / 180 * Math.PI; + let sin = Math.sin(angle); + let cos = Math.cos(angle); + + this.multiply([ + 0.213 + cos * 0.787 - sin * 0.213, 0.715 - cos * 0.715 - sin * 0.715, 0.072 - cos * 0.072 + sin * 0.928, + 0.213 - cos * 0.213 + sin * 0.143, 0.715 + cos * 0.285 + sin * 0.140, 0.072 - cos * 0.072 - sin * 0.283, + 0.213 - cos * 0.213 - sin * 0.787, 0.715 - cos * 0.715 + sin * 0.715, 0.072 + cos * 0.928 + sin * 0.072 + ]); + } + + grayscale(value = 1) { + this.multiply([ + 0.2126 + 0.7874 * (1 - value), 0.7152 - 0.7152 * (1 - value), 0.0722 - 0.0722 * (1 - value), + 0.2126 - 0.2126 * (1 - value), 0.7152 + 0.2848 * (1 - value), 0.0722 - 0.0722 * (1 - value), + 0.2126 - 0.2126 * (1 - value), 0.7152 - 0.7152 * (1 - value), 0.0722 + 0.9278 * (1 - value) + ]); + } + + sepia(value = 1) { + this.multiply([ + 0.393 + 0.607 * (1 - value), 0.769 - 0.769 * (1 - value), 0.189 - 0.189 * (1 - value), + 0.349 - 0.349 * (1 - value), 0.686 + 0.314 * (1 - value), 0.168 - 0.168 * (1 - value), + 0.272 - 0.272 * (1 - value), 0.534 - 0.534 * (1 - value), 0.131 + 0.869 * (1 - value) + ]); + } + + saturate(value = 1) { + this.multiply([ + 0.213 + 0.787 * value, 0.715 - 0.715 * value, 0.072 - 0.072 * value, + 0.213 - 0.213 * value, 0.715 + 0.285 * value, 0.072 - 0.072 * value, + 0.213 - 0.213 * value, 0.715 - 0.715 * value, 0.072 + 0.928 * value + ]); + } + + multiply(matrix) { + let newR = this.clamp(this.r * matrix[0] + this.g * matrix[1] + this.b * matrix[2]); + let newG = this.clamp(this.r * matrix[3] + this.g * matrix[4] + this.b * matrix[5]); + let newB = this.clamp(this.r * matrix[6] + this.g * matrix[7] + this.b * matrix[8]); + this.r = newR; + this.g = newG; + this.b = newB; + } + + brightness(value = 1) { + this.linear(value); + } + + contrast(value = 1) { + this.linear(value, -(0.5 * value) + 0.5); + } + + linear(slope = 1, intercept = 0) { + this.r = this.clamp(this.r * slope + intercept * 255); + this.g = this.clamp(this.g * slope + intercept * 255); + this.b = this.clamp(this.b * slope + intercept * 255); + } + + invert(value = 1) { + this.r = this.clamp((value + (this.r / 255) * (1 - 2 * value)) * 255); + this.g = this.clamp((value + (this.g / 255) * (1 - 2 * value)) * 255); + this.b = this.clamp((value + (this.b / 255) * (1 - 2 * value)) * 255); + } + + hsl() { // Code taken from https://stackoverflow.com/a/9493060/2688027, licensed under CC BY-SA. + let r = this.r / 255; + let g = this.g / 255; + let b = this.b / 255; + let max = Math.max(r, g, b); + let min = Math.min(r, g, b); + let h, s, l = (max + min) / 2; + + if (max === min) { + h = s = 0; + } else { + let d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return { + h: h * 100, + s: s * 100, + l: l * 100 + }; + } + + clamp(value) { + if (value > 255) { + value = 255; + } else if (value < 0) { + value = 0; + } + return value; + } +} + +class Solver { + constructor(target) { + this.target = target; + this.targetHSL = target.hsl(); + this.reusedColor = new Color(0, 0, 0); // Object pool + } + + solve() { + let result = this.solveNarrow(this.solveWide()); + return { + values: result.values, + loss: result.loss, + filter: this.css(result.values) + }; + } + + solveWide() { + const A = 5; + const c = 15; + const a = [60, 180, 18000, 600, 1.2, 1.2]; + + let best = {loss: Infinity}; + for (let i = 0; best.loss > 25 && i < 3; i++) { + let initial = [50, 20, 3750, 50, 100, 100]; + let result = this.spsa(A, a, c, initial, 1000); + if (result.loss < best.loss) { + best = result; + } + } + return best; + } + + solveNarrow(wide) { + const A = wide.loss; + const c = 2; + const A1 = A + 1; + const a = [0.25 * A1, 0.25 * A1, A1, 0.25 * A1, 0.2 * A1, 0.2 * A1]; + return this.spsa(A, a, c, wide.values, 500); + } + + spsa(A, a, c, values, iters) { + const alpha = 1; + const gamma = 0.16666666666666666; + + let best = null; + let bestLoss = Infinity; + let deltas = new Array(6); + let highArgs = new Array(6); + let lowArgs = new Array(6); + + for (let k = 0; k < iters; k++) { + let ck = c / Math.pow(k + 1, gamma); + for (let i = 0; i < 6; i++) { + deltas[i] = Math.random() > 0.5 ? 1 : -1; + highArgs[i] = values[i] + ck * deltas[i]; + lowArgs[i] = values[i] - ck * deltas[i]; + } + + let lossDiff = this.loss(highArgs) - this.loss(lowArgs); + for (let i = 0; i < 6; i++) { + let g = lossDiff / (2 * ck) * deltas[i]; + let ak = a[i] / Math.pow(A + k + 1, alpha); + values[i] = fix(values[i] - ak * g, i); + } + + let loss = this.loss(values); + if (loss < bestLoss) { + best = values.slice(0); + bestLoss = loss; + } + } + return {values: best, loss: bestLoss}; + + function fix(value, idx) { + let max = 100; + if (idx === 2 /* saturate */) { + max = 7500; + } else if (idx === 4 /* brightness */ || idx === 5 /* contrast */) { + max = 200; + } + + if (idx === 3 /* hue-rotate */) { + if (value > max) { + value = value % max; + } else if (value < 0) { + value = max + value % max; + } + } else if (value < 0) { + value = 0; + } else if (value > max) { + value = max; + } + return value; + } + } + + loss(filters) { // Argument is array of percentages. + let color = this.reusedColor; + color.set(0, 0, 0); + + color.invert(filters[0] / 100); + color.sepia(filters[1] / 100); + color.saturate(filters[2] / 100); + color.hueRotate(filters[3] * 3.6); + color.brightness(filters[4] / 100); + color.contrast(filters[5] / 100); + + let colorHSL = color.hsl(); + return Math.abs(color.r - this.target.r) + + Math.abs(color.g - this.target.g) + + Math.abs(color.b - this.target.b) + + Math.abs(colorHSL.h - this.targetHSL.h) + + Math.abs(colorHSL.s - this.targetHSL.s) + + Math.abs(colorHSL.l - this.targetHSL.l); + } + + css(filters) { + function fmt(idx, multiplier = 1) { + return Math.round(filters[idx] * multiplier); + } + + return `filter: invert(${fmt(0)}%) sepia(${fmt(1)}%) saturate(${fmt(2)}%) hue-rotate(${fmt(3, 3.6)}deg) brightness(${fmt(4)}%) contrast(${fmt(5)}%);`; + } +} diff --git a/style/fluidbook.less b/style/fluidbook.less index 8edb6306..f62b6ad9 100644 --- a/style/fluidbook.less +++ b/style/fluidbook.less @@ -709,7 +709,7 @@ body, html { width: unit(@book-page-width*2, px); height: unit(@book-page-height, px); pointer-events: none; - mix-blend-mode: multiply; + mix-blend-mode: @shadow-blend-mode; transition-property: none !important; transition-duration: 0ms !important;