<style type="text/css"> .tileContainer{ // border:10px solid black; display:inline-block; position:relative; width:450px; height:543px; overflow:hidden; box-sizing:border-box; } .tile{ position:relative; vertical-align:top; display:inline-block; border-right:1px solid rgba(0, 0, 0, 0.5); border-bottom:1px solid rgba(0, 0, 0, 0.5); box-sizing:border-box; } .tile:after{ content:""; background-color:#cc1c32; width:6px; height:6px; position:absolute; top:100%; right:0px; transform:translate(50%, -50%); z-index:2; line-height:1; } /*-- no grid --*/ .noGrid .tile{ border-right:0px solid rgba(0, 0, 0, 0.5); border-bottom:0px solid rgba(0, 0, 0, 0.5); } .noGrid .tile:after{ content:none; } </style> <table cellpadding="10" cellspacing="10" width="100%"> <tr> <td align="center"> <table cellpadding="5" cellspacing="20" class="colorborder" style="background-image:url(/Icon/foninfo.png)" width="500"> <tr class="colorborder"> <td align="center"> <table cellpadding="3" cellspacing="3" class="colorborder" style="background-image:url(/Icon/foninfo.png)" width="480"> <tr class="colorborder"> <td align="center"> <table width="450"> <tbody><tr style="background-image:url(https://sklees.narod.ru/Scr/desine/GMfonopacity.png)"><td> <div class="tileContainer"></div> </td></tr></tbody> </table> </td></tr> </table> </td></tr> </table> </td></tr> </table> <script src="https://sklees.narod.ru/webGL/TweenMax.min.js"></script> <script> // options var options = { imgSrc : "https://sklees.narod.ru/sity/poster/pinnoccio.png", containerName : "tileContainer", grid : false, tileWidth : 80, tileHeight : 80, mouseTrail:true } // ---------------------------------------------------------- var tileWidth, tileHeight, numTiles, tileHolder, tileContainer; var directionX, directionY; var imgOriginalWidth, imgOriginalHeight; var imgCoverWidth, imgCoverHeight; var imageLoaded = false; numTiles=0; tileWidth = options.tileWidth; tileHeight = options.tileHeight; tileContainer = document.getElementsByClassName(options.containerName)[0]; function init(){ if(options.grid == false)tileContainer.className += " noGrid"; //preload image and get original image size, then create tiles var image = new Image(); image.src = options.imgSrc; image.onload = function(e){ imageLoaded = true; imgOriginalWidth = e.currentTarget.width; imgOriginalHeight = e.currentTarget.height; createTileHolder(); checkTileNumber(); positionImage(); addListeners(); }; } function resizeHandler() { if(imageLoaded == false)return; //not working yet checkTileNumber(); positionImage(); } function createTileHolder(){ tileHolder = document.createElement('div'); tileHolder.className = "tileHolder"; tileHolder.style.position = "absolute"; tileHolder.style.top = "50%"; tileHolder.style.left = "50%"; tileHolder.style.transform = "translate(-50%, -50%)"; tileContainer.appendChild(tileHolder); } function checkTileNumber() { tileHolder.style.width = Math.ceil(tileContainer.offsetWidth / tileWidth) * tileWidth + "px"; tileHolder.style.height = Math.ceil(tileContainer.offsetHeight / tileHeight) * tileHeight + "px"; var tilesFitInWindow = Math.ceil(tileContainer.offsetWidth / tileWidth) * Math.ceil(tileContainer.offsetHeight / tileHeight); if(numTiles < tilesFitInWindow){ for (var i=0, l=tilesFitInWindow-numTiles; i < l; i++){ addTiles(); } }else if(numTiles > tilesFitInWindow){ for (var i=0, l=numTiles-tilesFitInWindow; i < l; i++){ removeTiles(); } } } function addTiles() { var tile = document.createElement('div'); tile.className = "tile"; //maintain aspect ratio imgCoverWidth = tileContainer.offsetWidth; imgCoverHeight = tileContainer.offsetHeight; if(imgOriginalWidth > imgOriginalHeight){ imgCoverHeight = imgOriginalHeight / imgOriginalWidth * imgCoverWidth; }else{ imgCoverWidth = imgOriginalWidth / imgOriginalHeight * imgCoverHeight; } tile.style.background = 'url("'+options.imgSrc+'") no-repeat'; tile.style.backgroundSize = imgCoverWidth + "px " + imgCoverHeight + "px"; tile.style.width = tileWidth + "px"; tile.style.height = tileHeight + "px"; document.querySelectorAll(".tileHolder")[0].appendChild(tile); tile.addEventListener("mouseover", moveImage); numTiles++; } function removeTiles() { var tileToRemove = document.querySelectorAll(".tile")[0]; tileToRemove.removeEventListener("mouseover", moveImage); TweenMax.killTweensOf(tileToRemove); tileToRemove.parentNode.removeChild(tileToRemove); numTiles--; } function addListeners(){ if(options.mouseTrail){ document.addEventListener('mousemove', function (event) { directionX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; directionY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; }); } } function positionImage(){ for(var t=0, l=numTiles; t < l; t++) { var nowTile = document.querySelectorAll(".tile")[t]; var left = (-nowTile.offsetLeft - (tileHolder.offsetLeft - (tileHolder.offsetWidth/2))); var top = (-nowTile.offsetTop - (tileHolder.offsetTop - (tileHolder.offsetHeight/2))); nowTile.style.backgroundPosition = left + "px " + top + "px"; } } function resetImage(nowTile){ var left = (-nowTile.offsetLeft - (tileHolder.offsetLeft - (tileHolder.offsetWidth/2))); var top = (-nowTile.offsetTop - (tileHolder.offsetTop - (tileHolder.offsetHeight/2))); TweenMax.to(nowTile, 1, {backgroundPosition:left + "px " + top + "px", ease:Power1.easeInOut}); } function moveImage(e){ var nowTile = e.currentTarget var minWidth = -tileContainer.offsetWidth+nowTile.offsetWidth; var minHeight = -tileContainer.offsetHeight+nowTile.offsetHeight; var nowLeftPos = (-nowTile.offsetLeft - (tileHolder.offsetLeft - (tileHolder.offsetWidth/2))); var nowTopPos = (-nowTile.offsetTop - (tileHolder.offsetTop - (tileHolder.offsetHeight/2))) var offset = 60; var left = nowLeftPos; var top = nowTopPos; if(options.mouseTrail){ //direction-aware movement if(directionX > 0){ left = nowLeftPos + offset; }else if(directionX < 0){ left = nowLeftPos - offset; } if(directionY > 0){ top = nowTopPos + offset; }else if(directionY < 0){ top = nowTopPos - offset; } }else{ //random movement left = getRandomInt(nowLeftPos - offset , nowLeftPos + offset); top = getRandomInt(nowTopPos - offset, nowTopPos + offset); } // bounds if(left < minWidth)left=minWidth; if(left > 0)left=0; if(top < minHeight)top=minHeight; if(top > 0)top=0; //tween TweenMax.to(nowTile, 1.5, {backgroundPosition:left + "px " + top + "px", ease:Power1.easeOut, onComplete:resetImage, onCompleteParams:[nowTile]}); } /////////////////////////////////////////////////////////////////// init(); // handle event window.addEventListener("optimizedResize", resizeHandler); ////////////////////////UTILS////////////////////////////////////// ////////////////////////////////////////////////////////////////// function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } (function() { var throttle = function(type, name, obj) { obj = obj || window; var running = false; var func = function() { if (running) { return; } running = true; requestAnimationFrame(function() { obj.dispatchEvent(new CustomEvent(name)); running = false; }); }; obj.addEventListener(type, func); }; /* init - you can init any event */ throttle("resize", "optimizedResize"); })(); </script>