将图像分割成许多较小的图像并允许来自每个单独图像的超链接(如图像映射)

Split image into many smaller images and allow hyperlinks from each individual image (like an imagemap)

总结

我有一张图片 (1920px x 1080px),我想将其拆分为 40px x 40px 的小图片。我想在网页上显示图像,使其看起来像原始的完整 1920x1080 图像。它将是 48 个图像宽(列)乘以 27 行。

对于每张图片,我希望能够有不同的超链接和替代文本。

当屏幕尺寸被动改变时,我希望图像也能缩小,这样它们就不会环绕页面,或者滚动出页面。

框架

目前正在使用 Vue 和 Vuetify。

尝试过

  1. 我试过使用完整图像而不将其拆分并在其上放置图像映射。这在全屏显示时效果很好,但是,当页面被动调整以调整大小时,图像映射坐标会随着底层图像大小的变化而被破坏。我不知道如何获取图像的比例以相应地调整图像贴图。

            <template v-slot:activator="{ on, attrs }">
            <v-img ref="imageShow" usemap="" class="image" contain src="@/assets/sections/fullsize_image.jpg" v-resize="onResize">
                <!-- Loop over array of plots by row & col to generate this.
                    Eg. top: = rowId * 40... 
                        left: = colPos * 40
                -->
                <span v-for="(i, row) in listSections"
                    :key="row"
                    justify="center" align="center" class="d-flex flex-nowrap"
                >
                    <!-- i contains an object with URL, alt text etc in it -->
                    <span
                        v-for="col in Object.keys(i)"
                        :key="col"
                    >
                        <a v-bind="attrs" v-on="on" @click="info = i[col]" :style="`${ returnStyle(row,col) }`"></a>
                    </span>
                </span>
            </v-img>
            </template>
    

returnStyle 是计算函数,用于计算图片部分的图像映射。如果图像因反应性图像大小调整而调整,我不确定如何在计算函数中考虑到这一点:

    computed: {
    returnStyle: function() {
        return function(row, col) {
            return "position:absolute; top: " + (row * 40) + "px; left: " + (col * 40) + "px; height:40px; width: 40px;"
        }
      }
    }
  1. 我试过 Vuetify v-row 和 v-col 来包含 v-img...图像没有正确缩小,或者它们正在换行或只是滚出页面(class="d-flex flex-nowrap").

     <v-container pa-0 fluid ma-0>
         <v-row no-gutters style="maxWidth: 1920px; width: 100%;" class="d-flex flex-nowrap">
             <v-col>
                 <v-img :src="require(`../assets/section/section_0_0.jpg`)"></v-img>
             </v-col>
             <!-- ... 46 more v-col/v-img's  -->                                  
         </v-row>
         <v-row no-gutters style="maxWidth: 1920px; width: 100%;" class="d-flex flex-nowrap">
             <v-col>
                 <v-img :src="require(`../assets/section/section_2_0.jpg`)"></v-img>
             </v-col>
             <!-- ... 46 more v-col/v-img's  -->                          
         </v-row>       
         <v-row no-gutters style="maxWidth: 1920px; width: 100%;" class="d-flex flex-nowrap">
             <v-col>
                 <v-img :src="require(`../assets/section/section_2_0.jpg`)"></v-img>
             </v-col>
             <!-- ... 46 more v-col/v-img's  -->
         </v-row>             
     </v-container>
    

我曾建议为此查看 Flex 或 CSS Grid,但是,我有点担心我会结束对它们的试验并以相同的类型结束的问题。

非常感谢任何建议。谢谢

您可以将图像作为背景放置到具有视口宽度(或您需要的任何其他尺寸)的容器中,并据此计算出合适的高度并显示为网格。

这里是一个简单纯粹的JS/CSS例子:

const numCols = 1920 / 40;
const numRows = 1080 / 40;
const container = document.querySelector('.container');
for (col = 1; col <= numCols; col++) {
  for (row = 1; row <= numRows; row++) {
    let a = document.createElement('a');
    a.style.gridColumn = col + ' / ' + (col + 1);
    a.style.gridRow = row + ' / ' + (row + 1);
    a.style.opacity = 0;
    a.href = 'url for cell ' + row + ', ' + col;
    container.appendChild(a);
  }
}
* {
  padding: 0;
  margin: 0;
}

.container {
  display: grid;
  grid-template-columns: repeat(40, 1fr);
  grid-template-rows: repeat(27, 1fr);
  width: 100vw;
  height: calc(100vw * 1080 / 1920);
  gap: 0;
  background-image: url(https://picsum.photos/id/1016/1920/1080);
  background-size: contain;
  background-repeat: no-repeat;
}
<div class="container">
</div>

您可能希望在每个单元格中包含一个带有 src(透明 png)的实际 img,以便在其中也获得 alt。