You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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类实现淡入淡出过渡

  1. 首先添加CSS过渡样式:
#board img {
    width: 118px;
    height: 118px;
    border: 1px solid #0c67ae;
    transition: opacity 0.5s ease; /* 添加入淡出过渡 */
}

.img-fade-out {
    opacity: 0;
}
  1. 修改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:叠加图片实现滑入切换动画

  1. 添加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;
}
  1. 修改初始化代码,将每个图片包裹在容器中:
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);
    }
  }  
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:55:18