九宮格圖片制作


1.原理及說明

九宮格圖片就是將一張圖片分成9份,再拼成一個完整的圖片,如圖:

原理:創建9個正方形容器,利用背景圖定位,每個容器只顯示其中的一部分,最終拼接成一張完整的圖片

實現思路:
(1)使用flex布局,讓9個子元素以 3*3 的形式擺放
(2)因為圖片有縱向和橫向兩種可能,所以要對圖片的寬高比進行判斷,以此來判斷圖片的方向,並根據圖片的方向決定背景圖定位信息。
(3)將圖片的url放入文本框中,通過按鈕點擊事件將url對應的圖片設置成容器的背景圖
(4)使用FileReader()讀取本地選中的圖片時,會花費1-2s的時間,在此時間內顯示一個蒙版遮罩,用來提示用戶“加載中...”
(5)為了美化按鈕,使用了bootstrap

2.HTML代碼

HTML代碼分為3個部分:
(1)操作區,包括文本輸入框和按鈕
(2)九宮格圖片區,用於顯示背景圖
(3)蒙版遮罩

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- 引入bootstrap -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"> 
    <link rel="stylesheet" href="index.css">
    <title>九宮格圖片</title>
</head>
<body>
    <!-- 操作區 -->
    <div id="imgInfo">
        <input type="text" id="imgUrl" placeholder="請輸入圖片url">
        <button id="fileBtn" class="btn btn-info">瀏覽本地圖庫</button>
        <br>
        <button id="updateUrl"class="btn btn-primary">更新九宮格圖片</button>
        <button id="clearInput"class="btn btn-default">清空輸入框</button>
        <br>
        <input type="file" name="image" id="file" style="display: none;" accept="image/*">
        <div id="paddingCtrBox">
            <input type="range" max="10" min="0" id="paddingCtr" title="滑動控制間隙的大小">
        </div>
    </div>
    <!-- 九宮格圖片 -->
    <div class="wrap">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
    </div>
    <!-- 蒙版 -->
    <div id="mask" class="hidden">
        <h3 class="text-center">加載中...</h3>
    </div>
</body>
<!-- 引入js文件 -->
<script src="index.js"></script>
</html>

3.css文件

(1)為了美化按鈕,引用了bootstrap中的類
(2)九宮格使用了flex布局
(3)蒙版使用了bootstrap中的類,用於顯示/隱藏蒙版

/* 按鈕容器 */
#imgInfo{
    margin: 20px;
    text-align: center;
}
#imgUrl{
    width: 700px;
    height: 30px;
    line-height: 30px;
    margin-bottom: 10px;
}
#imgUrl::placeholder{
    color:red;
    text-align: center;
}
#paddingCtrBox{
    width: 150px;
    margin: 10px auto;
}

/* 九宮格  */
.wrap{
    width: 456px;
    height: 456px;
    margin: 0 auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-content: space-between;
    /* border: 1px solid black; */
}
.wrap > .box{
    width: 150px;
    height: 150px;
    background-repeat: no-repeat;
    /* background-color: #eee; */
}
/* 縱向 */
.wrap > .vertical{
    background-size: auto 300%;
}
/* 橫向 */
.wrap > .transverse{
    background-size: 300% auto;
}

/* 蒙版 */
#mask{
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 99;
    background-color: rgba(210, 210, 210, 0.5);
    padding-top: 150px;
}

4.js文件

(1)先根據圖片的寬高比來判斷圖片的方向(縱向/橫向)
(2)監聽按鈕點擊,將文本框的url賦給容器的背景圖
(3)根據圖片的方向來設置背景圖的定位信息
(4)使用普通的按鈕來模擬文件域按鈕的點擊,並使用FileReader()存儲選中的圖片
(5)設置蒙版

//計算原圖的寬高比
function getImgProportion(url,cb){
    var img = new Image()
    img.src = url
    img.onload = function(){
        var Proportion = img.width/img.height
        cb(Proportion,url)
    }
}

//根據格子的大小設置背景圖的大小
function setBgc(Proportion,url){
    //Proportion<1 縱向
    //Proportion>1 橫向

    //獲取所有格子
    var box = document.getElementsByClassName('box')
    //為每個容器設置背景圖的url
    for(var i=0;i<box.length;i++){
        box[i].style.backgroundImage = `url(${url})`
    }


    //判斷圖片的方向
    if(Proportion<1){
        //計算寬高差距
        var disparity = box[0].offsetWidth*3 * (1-Proportion)
        //添加縱向的類
        for(var i=0;i<box.length;i++){
            box[i].className = 'box vertical'
        }
        //左右兩側背景圖片進行橫向偏移
        box[0].style.backgroundPosition = `${disparity/2}px 0`
        box[1].style.backgroundPosition = '50% 0'
        box[2].style.backgroundPosition = `${disparity/2 - box[0].offsetWidth*2}px 0`
        box[3].style.backgroundPosition = `${disparity/2}px 50%`
        box[4].style.backgroundPosition = '50% 50%'
        box[5].style.backgroundPosition = `${disparity/2 - box[0].offsetWidth*2}px 50%`
        box[6].style.backgroundPosition = `${disparity/2}px ${-box[0].offsetWidth*2}px`
        box[7].style.backgroundPosition = `50% ${-box[0].offsetWidth*2}px`
        box[8].style.backgroundPosition = `${disparity/2 - box[0].offsetWidth*2}px ${-box[0].offsetWidth*2}px`
    }else{
        //計算寬高差距
        var disparity = box[0].offsetHeight*3*(1-1/Proportion)
        //添加橫向的類
        for(var i=0;i<box.length;i++){
            box[i].className = 'box transverse'
        }
        //上下兩側背景圖片進行縱向偏移
        box[0].style.backgroundPosition = `0 ${disparity/2}px`
        box[1].style.backgroundPosition = `50% ${disparity/2}px`
        box[2].style.backgroundPosition = `${-box[0].offsetWidth*2}px ${disparity/2}px`
        box[3].style.backgroundPosition = `0 50%`
        box[4].style.backgroundPosition = '50% 50%'
        box[5].style.backgroundPosition = `${-box[0].offsetWidth*2}px 50%`
        box[6].style.backgroundPosition = `0 ${disparity/2 - box[0].offsetWidth*2}px`
        box[7].style.backgroundPosition = `50% ${disparity/2 - box[0].offsetWidth*2}px`
        box[8].style.backgroundPosition = `${-box[0].offsetWidth*2}px ${disparity/2 - box[0].offsetWidth*2}px`
    }
}

//九宮格的函數
function jiuGongGe(){
    var imgUrl = document.querySelector('#imgUrl').value
    //設置背景圖
    getImgProportion(imgUrl,setBgc)
}

window.onload = function(){
    //獲取元素
    var updateBtn = document.querySelector('#updateUrl')
    var clearBtn = document.querySelector('#clearInput')
    var fileBtn = document.querySelector('#fileBtn')
    var fileInput = document.querySelector('#file')
    var maskBox = document.querySelector("#mask")
    var paddingCtr = document.querySelector("#paddingCtr")
    //監聽 更新 按鈕的點擊
    updateBtn.onclick = function(){
        jiuGongGe()
    }
    //監聽 清空 按鈕的點擊
    clearBtn.onclick = function(){
        document.querySelector('#imgUrl').value = ''
    }
    //監聽 瀏覽本地圖庫 按鈕的點擊
    fileBtn.onclick = function(){
        //觸發fileInput的點擊事件
        fileInput.click()
    }
    //監聽fileInput的change事件
    fileInput.onchange = function(){
        //顯示遮罩(去除hidden類)
        maskBox.classList.remove('hidden')
        var reader = new FileReader()
        reader.readAsDataURL(document.querySelector('#file').files[0])
        reader.onload = function() {
            //文件已讀取完畢 將結果賦值給文本框
            document.querySelector('#imgUrl').value = reader.result
            //去除遮罩(添加hidden類)
            maskBox.classList.add('hidden')
        }
    }
    //監聽滑塊change事件
    paddingCtr.onchange = function(){
        //獲取大容器
        var wrap = document.querySelector("#wrap")
        //設置最小值
        var min = 450
        //獲取當前滑塊對應的值
        var value = Number(paddingCtr.value) * 2
        //設置大容器的寬高
        wrap.style.width = (min+value) + 'px'
        wrap.style.height = (min+value) + 'px'
    }
}

5.效果圖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM