分类 前端技术 下的文章

最近写了个目录直读的相册程序,用于展示日常拍摄的照片,直接通过FTP上传,免去后台开发和维护的成本,使用起来也很方便。

大图展示采用lightbox灯箱插件,效果很不错。但是索引页的图片怎么布局好看呢,参考图虫网的实现方式,每行图片数目固定,行内图片左右对齐,行高固定,单张图片的宽度根据实际比例计算得出。做出来的效果确实不错,计算过程也不复杂。效果图如下。

相册效果图

程序是用PHP实现的,后端直接计算好尺寸输出HTML,但实际上这个布局实现过程由前端来实现更科学,于是用js改写了计算方法,代码如下。

const containerWidth = 1200;
const column = 4;
const imagesRow = [
    {width: 1200, height: 750, info: {}},
    {width: 801, height: 1200, info: {}},
    {width: 1200, height: 1200, info: {}},
    {width: 1200, height: 675, info: {}}
];

function fixImageSize(imagesRow, containerWidth, column) {
    let heights = imagesRow.map(image => image.height);
    let minHeight = Math.min.apply(null, heights);
    let minWidth = containerWidth / column;
    // 第一次循环,统一高度
    for (let i = 0; i < imagesRow.length; i++) {
        if (imagesRow[i].height === minHeight) {
            minWidth = imagesRow[i].width;
        } else if (imagesRow[i].height > minHeight) {
            imagesRow[i].width = imagesRow[i].width * minHeight / imagesRow[i].height;
            imagesRow[i].height = minHeight;
        }
    }
    containerWidth = containerWidth * imagesRow.length / column;
    let widths = imagesRow.map(image => image.width);
    let zoom = widths.reduce((prev, next) => prev + next) / containerWidth;
    let fixedHeight = minHeight / zoom;
    // 第二次循环,压缩宽度
    for (let i = 0; i < imagesRow.length; i++) {
        imagesRow[i].width = parseInt(imagesRow[i].width / zoom, 10);
        imagesRow[i].height = parseInt(fixedHeight, 10);
    }
    return imagesRow;
}

let ret = JSON.stringify(fixImageSize(imagesRow, containerWidth, column), null ,2);
/*[
    {
      "width": 380,
      "height": 237,
      "info": {}
    },
    {
      "width": 158,
      "height": 237,
      "info": {}
    },
    {
      "width": 237,
      "height": 237,
      "info": {}
    },
    {
      "width": 422,
      "height": 237,
      "info": {}
    }
  ]*/

相册写好后,先把大学期间上传到人人网的照片备份了一下,说不定哪天人人网又不行了,还能留个怀念,地址