如何用JavaScript替换图片src并实现平滑过渡效果
3x3拼图完成后中间行图片平滑替换方案
我正在通过实例学习JavaScript,基于网上的3x3滑块拼图脚本开发,已添加部分功能,但在完成拼图后的一个需求上遇阻:调用solvedIt()函数时,需要将中间行(ID分别为1-0、1-1、1-2)的3个拼图块替换为code1.jpg、code2.jpg、code3.jpg,并实现平滑过渡效果。直接替换图片src可以实现内容切换,但过渡效果始终无法实现。目前想到两种原生实现思路:修改CSS类、叠加图片配合CSS动画,希望得到可行的原生解决方案。
以下是当前代码片段:
HTML
<body> <div id="board"></div> </body>
CSS
body { font-family: Arial, Helvetica, sans-serif; text-align: center; color: #0c67ae; } #board { width: 360px; height: 360px; background-color: lightblue; border: 10px solid #0c67ae; margin: 0 auto; display: flex; flex-wrap: wrap; } #board img { width: 118px; height: 118px; border: 1px solid #0c67ae; }
JavaScript
var rows = 3; var columns = 3; var currTile; var otherTile; //blank tile // var imgOrder = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]; var imgOrder = ["4", "1", "3", "7", "2", "5", "8", "6", "9"]; window.onload = function() { for (let r=0; r < rows; r++) { for (let c=0; c < columns; c++) { //<img id="0-0" src="1.jpg"> let tile = document.createElement("img"); tile.id = r.toString() + "-" + c.toString(); tile.src = "./" + src_dir + "/" + imgOrder.shift() + ".jpg"; //DRAG FUNCTIONALITY tile.addEventListener("dragstart", dragStart); //click an image to drag tile.addEventListener("dragover", dragOver); //moving image around while clicked tile.addEventListener("dragenter", dragEnter); //dragging image onto another one tile.addEventListener("dragleave", dragLeave); //dragged image leaving another image tile.addEventListener("drop", dragDrop); //drag an image over another image, drop the image tile.addEventListener("dragend", dragEnd); //after drag drop, swap the two tiles // added mouse click handlers tile.addEventListener("click", mouseClick); document.getElementById("board").append(tile); } } } // end window.onload function solvedIt() { // replace 4.jpg, 5.jpg and 6.jpg with code1.jpg, code2.jpg and code3.jpg // 4.jpg has id of '1-0', 5.jpg id='1-1' and 6.jpg='1-2' let xTile = document.getElementById('1-0'); xTile.src="./"+src_dir+"/code1.jpg" ; let xTile = document.getElementById('1-1'); xTile.src="./"+src_dir+"/code2.jpg" ; let xTile = document.getElementById('1-2'); xTile.src="./"+src_dir+"/code3.jpg" ; }
解决方案1:通过CSS类实现淡入淡出过渡
- 首先添加CSS过渡样式:
#board img { width: 118px; height: 118px; border: 1px solid #0c67ae; transition: opacity 0.5s ease; /* 添加入淡出过渡 */ } .img-fade-out { opacity: 0; }
- 修改
solvedIt()函数,利用定时器配合类切换实现过渡:
function solvedIt() { const middleTiles = [ {id: '1-0', newSrc: `./${src_dir}/code1.jpg`}, {id: '1-1', newSrc: `./${src_dir}/code2.jpg`}, {id: '1-2', newSrc: `./${src_dir}/code3.jpg`} ]; middleTiles.forEach(tileData => { const tile = document.getElementById(tileData.id); // 触发淡出 tile.classList.add('img-fade-out'); // 等待淡出完成后替换图片并恢复透明度 setTimeout(() => { tile.src = tileData.newSrc; tile.classList.remove('img-fade-out'); }, 500); }); }
解决方案2:叠加图片实现滑入切换动画
- 添加CSS动画和容器样式:
@keyframes slide-up { from { transform: translateY(100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .tile-container { position: relative; width: 118px; height: 118px; border: 1px solid #0c67ae; } .tile-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; animation: slide-up 0.6s ease forwards; }
- 修改初始化代码,将每个图片包裹在容器中:
window.onload = function() { for (let r=0; r < rows; r++) { for (let c=0; c < columns; c++) { // 创建容器 let container = document.createElement("div"); container.className = "tile-container"; // 创建图片 let tile = document.createElement("img"); tile.id = r.toString() + "-" + c.toString(); tile.src = "./" + src_dir + "/" + imgOrder.shift() + ".jpg"; // 绑定原事件 tile.addEventListener("dragstart", dragStart); tile.addEventListener("dragover", dragOver); tile.addEventListener("dragenter", dragEnter); tile.addEventListener("dragleave", dragLeave); tile.addEventListener("drop", dragDrop); tile.addEventListener("dragend", dragEnd); tile.addEventListener("click", mouseClick); container.appendChild(tile); document.getElementById("board").append(container); } } }
- 修改
solvedIt()函数,添加叠加图片实现切换:
function solvedIt() { const middleTiles = [ {id: '1-0', newSrc: `./${src_dir}/code1.jpg`}, {id: '1-1', newSrc: `./${src_dir}/code2.jpg`}, {id: '1-2', newSrc: `./${src_dir}/code3.jpg`} ]; middleTiles.forEach(tileData => { const tile = document.getElementById(tileData.id); const container = tile.parentElement; // 创建叠加图片 const overlayImg = document.createElement("img"); overlayImg.className = "tile-overlay"; overlayImg.src = tileData.newSrc; container.appendChild(overlayImg); // 动画完成后替换原图片并移除叠加层 setTimeout(() => { tile.src = tileData.newSrc; container.removeChild(overlayImg); }, 600); }); }
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

