| 13 | |
| 14 | // Export the InteractiveTilt class |
| 15 | export class InteractiveTilt { |
| 16 | // Object to hold references to DOM elements |
| 17 | DOM = { |
| 18 | el: null, // Main element (.content) |
| 19 | wrapEl: null // Wrap element (.content__img-wrap) |
| 20 | }; |
| 21 | |
| 22 | // Default options for the InteractiveTilt effect |
| 23 | defaults = { |
| 24 | perspective: 800, // CSS perspective value for the 3D effect |
| 25 | // Range of values for translation and rotation on x and y axes |
| 26 | valuesFromTo: { |
| 27 | x: [-35, 35], |
| 28 | y: [-35, 35], |
| 29 | rx: [-18, 18], // rotation on the X-axis |
| 30 | ry: [-10, 10], // rotation on the Y-axis |
| 31 | rz: [-4, 4] // rotation on the Z-axis |
| 32 | }, |
| 33 | // Amount to interpolate values for smooth animation (higher value, less smoothing) |
| 34 | amt: 0.1 |
| 35 | }; |
| 36 | |
| 37 | // Object to store the current transform values for the image element |
| 38 | imgTransforms = {x: 0, y: 0, rx: 0, ry: 0, rz: 0}; |
| 39 | |
| 40 | /** |
| 41 | * Constructor for the InteractiveTilt class. |
| 42 | * @param {Element} DOM_el - The .content element to be animated |
| 43 | * @param {Object} options - Custom options for the effect |
| 44 | */ |
| 45 | constructor(DOM_el, options) { |
| 46 | // Assign DOM elements to the DOM object |
| 47 | this.DOM.el = DOM_el; |
| 48 | this.DOM.wrapEl = this.DOM.el.querySelector('.content__img-wrap'); |
| 49 | // Merge the default options with any user-provided options |
| 50 | this.options = Object.assign(this.defaults, options); |
| 51 | |
| 52 | // If a perspective value is provided, apply it to the main element |
| 53 | if (this.options.perspective) { |
| 54 | this.DOM.el.style.perspective = `${this.options.perspective}px`; |
| 55 | } |
| 56 | |
| 57 | // Start the rendering loop for the animation |
| 58 | requestAnimationFrame(() => this.render()); |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * Animation loop that applies the tilt effect based on the cursor position. |
| 63 | */ |
| 64 | render() { |
| 65 | // Interpolate the current transform values towards the target values |
| 66 | // based on the cursor's position on the screen |
| 67 | this.imgTransforms.x = lerp(this.imgTransforms.x, map(cursor.x, 0, winsize.width, this.options.valuesFromTo.x[0], this.options.valuesFromTo.x[1]), this.options.amt); |
| 68 | this.imgTransforms.y = lerp(this.imgTransforms.y, map(cursor.y, 0, winsize.height, this.options.valuesFromTo.y[0], this.options.valuesFromTo.y[1]), this.options.amt); |
| 69 | this.imgTransforms.rz = lerp(this.imgTransforms.rz, map(cursor.x, 0, winsize.width, this.options.valuesFromTo.rz[0], this.options.valuesFromTo.rz[1]), this.options.amt); |
| 70 | |
| 71 | // Apply rotation on the X and Y-axis only if perspective is enabled |
| 72 | this.imgTransforms.rx = !this.options.perspective ? 0 : lerp(this.imgTransforms.rx, map(cursor.y, 0, winsize.height, this.options.valuesFromTo.rx[0], this.options.valuesFromTo.rx[1]), this.options.amt); |
nothing calls this directly
no outgoing calls
no test coverage detected