Merge pull request #10 from PoongalOO/gradients/ticket4

Rendre les gradients de pli plus prévisibles et testables
This commit is contained in:
PoongalOO 2026-06-08 22:50:54 +02:00 committed by GitHub
commit 9551bb5191
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 109 additions and 10 deletions

View File

@ -154,6 +154,85 @@ describe('turn.js jQuery plugin', () => {
}
});
it('builds normalized linear gradients without legacy syntax or white highlights', () => {
fixture.window.close();
fixture = createFixture(4, {
__TURNJS_TEST_HOOKS__: {}
});
const buildLinearGradient = fixture.window.__TURNJS_TEST_HOOKS__.buildLinearGradient;
const gradient = buildLinearGradient(
{ x: 0, y: 0 },
{ x: -10, y: 0 },
[
[-1, 'rgba(0,0,0,0)'],
[0.5, 'rgba(0,0,0,0.12)'],
[2, 'rgba(0,0,0,0)']
],
3
);
expect(gradient).toMatch(/^linear-gradient\(180deg,/);
expect(gradient).not.toContain('-webkit-gradient');
expect(gradient).not.toContain('255, 255, 255');
expect([...gradient.matchAll(/([0-9.]+)%/g)].map(match => Number(match[1]))).toEqual([
0,
50,
100
]);
});
it('normalizes fold gradient opacity for tiny and large folds', () => {
fixture.window.close();
fixture = createFixture(4, {
__TURNJS_TEST_HOOKS__: {}
});
const calculateFoldGeometry = fixture.window.__TURNJS_TEST_HOOKS__.calculateFoldGeometry;
const base = {
point: { corner: 'tl', x: 90, y: 120 },
origin: { x: 0, y: 0 },
width: 300,
height: 400,
wrapperHeight: 500,
frontGradient: true,
backGradient: true
};
const tinyFold = calculateFoldGeometry({
...base,
endingPoint: { x: 90, y: 120 }
});
const largeFold = calculateFoldGeometry({
...base,
endingPoint: { x: 600, y: 0 }
});
expect(tinyFold.gradient.opacity).toBe(0);
expect(largeFold.gradient.opacity).toBe(1);
});
it('does not create gradient shadow layers when gradients are disabled', () => {
const { $ } = fixture;
const $book = $('#book');
$book.turn({
width: 600,
height: 400,
display: 'double',
gradients: false,
acceleration: false
});
const pageState = $book.data('pages')[1].data('f');
expect(pageState.opts.frontGradient).toBe(false);
expect(pageState.opts.backGradient).toBe(false);
expect(pageState.ashadow).toBeUndefined();
expect(pageState.bshadow).toBeUndefined();
expect($book.find('[style*="linear-gradient"]').length).toBe(0);
});
it('initializes a book and exposes page, view, pages and size state', () => {
const { $ } = fixture;
const $book = $('#book');

38
turn.js
View File

@ -191,6 +191,18 @@ var has3d,
return Object.prototype.hasOwnProperty.call(object, property);
},
clamp = function(value, min, max) {
value = parseFloat(value);
return Math.max(min, Math.min(max, isNaN(value) ? min : value));
},
normalizeDegrees = function(degrees) {
degrees = degrees%360;
if (degrees<0)
degrees += 360;
return degrees===0 ? 0 : degrees;
},
// Internal book state stored on the root element with $.data().
// This helper keeps direct $.data() reads easy to identify.
@ -293,7 +305,7 @@ var has3d,
gradientSize = side*Math.sin(alpha);
var far = Math.sqrt(Math.pow(opts.endingPoint.x-point.x, 2)+Math.pow(opts.endingPoint.y-point.y, 2));
gradientOpacity = (far<width) ? far/width : 1;
gradientOpacity = clamp((far<width) ? far/width : 1, 0, 1);
if (opts.frontGradient) {
@ -339,23 +351,29 @@ var has3d,
};
},
// Adds gradients
// Builds a modern linear-gradient string from points and normalized stops
buildLinearGradient = function(p0, p1, colors, numColors) {
gradient = function(obj, p0, p1, colors, numColors) {
var j, cols = [],
dx = p1.x-p0.x,
dy = p1.y-p0.y,
angle = Math.atan2(dy, dx),
angle = normalizeDegrees(-deg(Math.atan2(dy, dx))),
stop;
for (j = 0; j<numColors; j++) {
stop = Math.max(0, Math.min(1, colors[j][0])) * 100;
stop = clamp(colors[j][0], 0, 1) * 100;
cols.push(' '+colors[j][1]+' '+stop+'%');
}
var backgroundImage = 'linear-gradient(' + (-deg(angle)) + 'deg,' + cols.join(',') + ')';
obj.css({'background-image': backgroundImage});
return 'linear-gradient(' + angle + 'deg,' + cols.join(',') + ')';
},
// Adds gradients
gradient = function(obj, p0, p1, colors, numColors) {
obj.css({'background-image': buildLinearGradient(p0, p1, colors, numColors)});
},
turnMethods = {
@ -2163,8 +2181,10 @@ $.extend($.fn, {
});
if (window.__TURNJS_TEST_HOOKS__)
if (window.__TURNJS_TEST_HOOKS__) {
window.__TURNJS_TEST_HOOKS__.calculateFoldGeometry = calculateFoldGeometry;
window.__TURNJS_TEST_HOOKS__.buildLinearGradient = buildLinearGradient;
}
$.isTouch = isTouch;

2
turn.min.js vendored

File diff suppressed because one or more lines are too long