{"id":977,"date":"2025-09-16T09:37:47","date_gmt":"2025-09-16T09:37:47","guid":{"rendered":"https:\/\/laywow.com\/animation\/image-trail-effect\/"},"modified":"2025-09-17T15:09:30","modified_gmt":"2025-09-17T15:09:30","slug":"image-trail-effect","status":"publish","type":"post","link":"https:\/\/laywow.com\/en\/animations\/image-trail-effect\/","title":{"rendered":"Image Trail Effect"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This effect is widely used in modern web design: when the user moves their mouse, a succession of images appears and disappears with a smooth animation.<\/p>\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n<h2 class=\"wp-block-heading\">Add the HTML Structure in Elementor<\/h2>\n\n<ol class=\"wp-block-list\">\n<li>In Elementor, add an <strong>HTML Widget<\/strong> to your page.<\/li>\n\n\n\n<li>Paste this code:<\/li>\n<\/ol>\n\n<pre class=\"wp-block-code\"><code>&lt;div class=\"items\">&lt;\/div>\n\n&lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/gsap\/3.12.5\/gsap.min.js\">&lt;\/script>\n\n&lt;script>\n   const imagePaths = &#91;\n      \"https:\/\/images.pexels.com\/photos\/18131871\/pexels-photo-18131871.jpeg?w=300&amp;auto=compress&amp;cs=tinysrgb\",\n      \"https:\/\/images.pexels.com\/photos\/18398708\/pexels-photo-18398708.jpeg?w=300&amp;auto=compress&amp;cs=tinysrgb\",\n      \"https:\/\/images.pexels.com\/photos\/18131896\/pexels-photo-18131896.jpeg?w=300&amp;auto=compress&amp;cs=tinysrgb\",\n      \"https:\/\/images.pexels.com\/photos\/18398385\/pexels-photo-18398385.jpeg?w=300&amp;auto=compress&amp;cs=tinysrgb\",\n      \"https:\/\/images.pexels.com\/photos\/18398430\/pexels-photo-18398430.jpeg?w=300&amp;auto=compress&amp;cs=tinysrgb\"\n      \/\/ ajoute ou enl\u00e8ve des images ici\n   ];\n\n   document.addEventListener(\"DOMContentLoaded\", function () {\n      const container = document.querySelector(\".items\");\n      let imageIndex = 0;\n\n      let lastX = null;\n      let lastY = null;\n      const minDistance = 100; \/\/ Distance minimale avant apparition d\u2019une nouvelle image\n\n      function getDistance(x1, y1, x2, y2) {\n         const dx = x2 - x1;\n         const dy = y2 - y1;\n         return Math.sqrt(dx * dx + dy * dy);\n      }\n\n      function addNewItem(x, y, dx, dy) {\n         const newItem = document.createElement(\"div\");\n         newItem.className = \"item\";\n         newItem.style.position = \"absolute\";\n         newItem.style.left = `${x - 150}px`;\n         newItem.style.top = `${y - 150}px`;\n         newItem.style.width = \"300px\";\n         newItem.style.height = \"300px\"; \/\/ d\u00e9finit la taille de l'image\n         newItem.style.pointerEvents = \"none\";\n\n         const img = document.createElement(\"img\");\n         img.src = imagePaths&#91;imageIndex];\n         img.style.width = \"100%\";\n         img.style.height = \"100%\";\n         img.style.objectFit = \"contain\";\n         newItem.appendChild(img);\n\n         container.appendChild(newItem);\n\n         imageIndex = (imageIndex + 1) % imagePaths.length;\n\n         const randomRotation = gsap.utils.random(0, 0);\n\n         \/\/ Normalisation direction\n         const length = Math.sqrt(dx * dx + dy * dy) || 1;\n         const dirX = (dx \/ length) * 80; \/\/ Direction et amplitude de l\u2019entr\u00e9e\n         const dirY = (dy \/ length) * 80; \/\/ Direction et amplitude de l\u2019entr\u00e9e\n\n         \/\/ Animation GSAP\n         gsap.timeline()\n            .fromTo(newItem,\n               { scale: 1, opacity: 1, rotation: randomRotation, x: -dirX, y: -dirY },\n               { scale: 1, opacity: 1, x: 0, y: 0, duration: 0.4, ease: \"power2.out\" } \n            )\n            .to(newItem,\n               { \n                 scale: 0.3, opacity: 0, duration: 1, ease: \"power2.out\", delay: 0.05, \n                 onComplete: () => newItem.remove() \n               } \n            );\n      }\n\n      container.addEventListener(\"mousemove\", function (event) {\n         if (lastX === null || lastY === null) {\n            lastX = event.pageX;\n            lastY = event.pageY;\n            return;\n         }\n\n         const dx = event.pageX - lastX;\n         const dy = event.pageY - lastY;\n         const distance = getDistance(lastX, lastY, event.pageX, event.pageY);\n\n         if (distance > minDistance) {\n            addNewItem(event.pageX, event.pageY, dx, dy);\n            lastX = event.pageX;\n            lastY = event.pageY;\n         }\n      });\n   });\n&lt;\/script><\/code><\/pre>\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n<h2 class=\"wp-block-heading\">Add the CSS in Elementor<\/h2>\n\n<p class=\"wp-block-paragraph\">Still in the <strong>HTML<\/strong> widget, go to Advanced and then Custom CSS, add:<\/p>\n\n<pre class=\"wp-block-code\"><code>.items { \n  position: fixed; \n  top: 0; \n  left: 0; \n  width: 100vw; \n  height: 100vh; \n  will-change: transform, opacity; \n  z-index: 999; \/* passe au-dessus du contenu *\/\n} \n\n.item { \n  position: absolute; \n  width: 450px; \n  height: 600px; \n  overflow: hidden; \n} \n\n.item img { \n  width: 150%; \n  height: 250%; \n  object-fit: cover; \n}<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n<h2 class=\"wp-block-heading\">Customize the Animation<\/h2>\n\n<p class=\"wp-block-paragraph\">You can adapt the effect by modifying these <strong>key lines<\/strong> of the script:<\/p>\n\n<p class=\"wp-block-paragraph\"><strong>Minimum distance before a new image appears<\/strong> <code>const minDistance = 100;<\/code> \u2192 Lower = more images, higher = fewer images.<\/p>\n\n<p class=\"wp-block-paragraph\"><strong>Direction and amplitude of entry<\/strong> <code>const dirX = (dx \/ length) * 80; const dirY = (dy \/ length) * 80;<\/code> \u2192 Change <code>80<\/code> to increase\/decrease the &#8220;trajectory&#8221; effect.<\/p>\n\n<p class=\"wp-block-paragraph\"><strong>Appearance duration<\/strong> <code>duration: 0.4<\/code> \u2192 Lower = faster, higher = slower.<\/p>\n\n<p class=\"wp-block-paragraph\"><strong>Disappearance animation<\/strong><br\/>Currently: <code>scale: 0.3, opacity: 0, duration: 1, ease: \"power2.out\"<\/code> <br\/>Suggested variant for a downward fall effect:  <\/p>\n\n<pre class=\"wp-block-code\"><code><code>y: window.innerHeight + 300, opacity: 0, scale: 0.3, duration: 1.2, ease: \"power2.in\", onComplete: () => item.remove()<\/code><\/code><\/pre>\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n<h2 class=\"wp-block-heading\">Practical Tips<\/h2>\n\n<ul class=\"wp-block-list\">\n<li><strong>Image compression<\/strong>: optimize images with <a href=\"https:\/\/tinypng.com\/\" target=\"_blank\" rel=\"noopener\">TinyPNG <\/a>or <a href=\"https:\/\/squoosh.app\/\" target=\"_blank\" rel=\"noopener\">Squoosh<\/a>.<\/li>\n\n\n\n<li><strong>Image size<\/strong>: avoid overly heavy originals (200\u2013400px max for this effect).<\/li>\n\n\n\n<li><strong>Mobile performance<\/strong>: disable this effect on mobile if smoothness is not optimal.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This effect is widely used in modern web design: when the user moves their mouse, a succession of images appears and disappears with a smooth animation. Add the HTML Structure in Elementor Add the CSS in Elementor Still in the HTML widget, go to Advanced and then Custom CSS, add: Customize the Animation You can [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":973,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[25],"tags":[27,26],"class_list":["post-977","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-animations","tag-hover","tag-interactions"],"acf":[],"_links":{"self":[{"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/posts\/977","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/comments?post=977"}],"version-history":[{"count":1,"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/posts\/977\/revisions"}],"predecessor-version":[{"id":978,"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/posts\/977\/revisions\/978"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/media\/973"}],"wp:attachment":[{"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/media?parent=977"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/categories?post=977"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/laywow.com\/en\/wp-json\/wp\/v2\/tags?post=977"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}