亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

國慶節(jié)到了,利用JS實現(xiàn)一個生成國慶風(fēng)頭像的小工具 詳解實現(xiàn)過程

 更新時間:2021年09月30日 16:32:28   作者:CUGGZ  
明天就是國慶節(jié)了,最近看到好多好友換了國慶風(fēng)的頭像,感覺這個挺有意思,就找到了類似的源碼研究了一番,并進行了改造(并非原創(chuàng),只是進行了改造,只要想分享一下實現(xiàn)思路)。下面就來看看如何實現(xiàn)一鍵生成國慶風(fēng)頭像小工具。​

這里用到的技術(shù):

  • HTML+ CSS+ JavaScript;
  • download.js庫;
  • fabric.js庫;

先上體驗鏈接:g.cuggz.com/ 。​

注:可以點擊上方的連接進行使用,不過我的域名被TX屏蔽了,還在申訴中,所以無法在QQ、微信中打開,需要復(fù)制鏈接到瀏覽器進行查看、使用。​

下面是這個小工具的截圖:

1. 頁面布局

這部分不多說,直接上代碼:

<div class="wrapper">
    <!-- 選擇框 -->
    <div class="main-box">
      <a class="prev" onClick='changeHat()'></a>
      <div class="main-img">
        <div id="content">
          <canvas id='cvs'></canvas>
        </div>
      </div>
      <a class="next" onClick='changeHat()'></a>
    </div>
    <!-- 導(dǎo)出圖 -->
    <img id='export-img' alt='國慶專屬頭像' src='' crossorigin="anonymous"/>
    <!-- 操作按鈕 -->
    <div class="operation-btns">
      <a class="upload-btn">
        <input id='upload' type='file' onchange='viewer()' style='opacity: 0;'/>
      </a>
      <a class="export-btn" onClick='exportFunc()'></a>
    </div>
  </div>
 <!-- 模板 -->
  <div style='display: none'>
    <img id='img' src='' alt='' />
    <img class='hide' id='hat0' src='img/1.png' />
    <img class='hide' id='hat1' src='img/2.png' />
    <img class='hide' id='hat2' src='img/3.png' />
    <img class='hide' id='hat3' src='img/4.png' />
    <img class='hide' id='hat4' src='img/5.png' />
    <img class='hide' id='hat5' src='img/6.png' />
    <img class='hide' id='hat6' src='img/7.png' />
  </div>

這個頁面比較簡單,外面就是一個大的背景圖,中間就是一個頭像的展示框以及模板的切換按鈕,下面就是一個上傳按鈕和一個下載按鈕。頁面布局完之后,就是寫樣式了,CSS代碼如下:

body,
html {
    min-height: 100%;
    width: 100%;
    user-select: none;
    font-size: 18px;
}

.wrapper {
    width: 100%;
    height: 100%;
    max-width: 620px;
    max-height: 800px ;
    margin: 0 auto;
    background-image: url('../img/bg.png');
    background-repeat: no-repeat;
    background-size: 100% 100%;
    padding-top: 13em;
}

#export-img {
    display:none;
    margin:0 auto;
    width:250px;
    height:250px;
}

.main-box {
    display: flex;
    align-items: center;
    justify-content: center;
}

.main-box .next,
.main-box .prev {
    background-image: url('../img/next.png');
    background-size: contain;
    border-radius: 50%;
    width: 2.275rem;
    height: 2.275rem
}

.main-box .prev {
    transform: rotate(180deg)
}

.main-box .main-img {
    margin: 0 .75rem;
    background: #fff;
    border: .25rem solid #fbe6b5;
    border-radius: .75rem;
    font-size: 0
}

#content {
    border-radius: .5rem;
    position: relative;
    width: 9.5rem;
    height: 9.5rem;
    margin-left: 50%;
    transform: translateX(-50%);
    overflow: hidden
}

.operation-btns {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    margin-top: .75rem
}

.operation-btns .upload-btn {
    width: 11.6rem;
    height: 3.6rem;
    background-size: 100% 100%;
    background-image: url('../img/upload.png')
}

.operation-btns .export-btn {
    display: none;
    width: 11.6rem;
    height: 3.75rem;
    background-size: 100% 100%;
    background-image: url('../img/export.png')
}

這里只是簡單的實現(xiàn),僅供參考。還有很多可以優(yōu)化的地方,這里不在修改,有興趣的可以自己進行個性化定制。

2. 圖片上傳和展示

接下來就是邏輯部分的實現(xiàn)了。首先,有幾個全局變量需要先定義,后面會用到:

let canvasFabric;   // 畫布實例
let hat = "hat0";  // 當(dāng)前的模板class
let hatInstance;  // 模板圖層實例
const screenWidth = document.getElementById("content").scrollHeight;  // 內(nèi)容框的高度

之后就需要處理上傳的圖片并將他展示在頁面上:

function viewer() {
  // 獲取上傳的圖片文件
  const file = document.getElementById("upload").files[0];
  // 獲取需要展示圖片的標(biāo)簽
  const img = document.getElementById("img");
  // 創(chuàng)建文件讀取文件對象
  const reader = new FileReader();
  if (file) {
    // 將文件轉(zhuǎn)化為Base64
    reader.readAsDataURL(file);
    // 當(dāng)文件讀取成功之后觸發(fā)
    reader.onload = () => {
      // 將base64的url賦值給要展示圖片的標(biāo)簽
      img.src = reader.result;
      // 圖片加載完成觸發(fā)
      img.onload = () => img2Cvs(img);
    }
  } else {
    img.src = ""
  }
}

這里使用到了HTML5FileReader對象,它提供了讀取文件的方法和包含讀取結(jié)果的事件模型。可以使用new來初始化對象,FileReader對象包含四個方法,其中 3 個用以讀取文件,另一個用來中斷讀取。需要注意的是 ,無論讀取成功或失敗,方法并不會返回讀取結(jié)果,這一結(jié)果存儲在 result 屬性中。這里用到了readAsDataURL方法,MDN對該方法的介紹如下:

readAsDataURL 方法會讀取指定的 Blob 或 File 對象。讀取操作完成的時候,readyState 會變成已完成DONE,并觸發(fā) loadend (en-US) 事件,同時 result 屬性將包含一個data:URL格式的字符串(base64編碼)以表示所讀取文件的內(nèi)容。

也就是說將上傳的圖片轉(zhuǎn)化為了一個Base64格式的URL,并賦值給了展示圖片的標(biāo)簽,這樣這個標(biāo)簽就顯示出現(xiàn)這個頭像了,效果如下:

這樣就完成了圖片的上傳和展示,接下來就該初始化一個畫布了。

3. 初始化畫布

在上面的代碼的最后執(zhí)行了 img.load,這里的 onload 事件會在圖片加載完成后立即執(zhí)行。在圖片展示完成之后會執(zhí)行img2Cvs方法,這個方法主要用來初始化一塊畫布,順便展示和隱藏頁面的部分元素。

img2Cvs方法中使用到了 fabric庫,F(xiàn)abric.js是一個可以簡化Canvas程序編寫的庫。 Fabric.jsCanvas提供所缺少的對象模型, svg parser, 交互和一整套其他不可或缺的工具。Canvas提供一個好的畫布能力, 但是Api不夠友好。Fabric.js就是為此而開發(fā),它主要就是用對象的方式去編寫代碼。Fabric.js能做的事情如下:

  • Canvas上創(chuàng)建、填充圖形(包括圖片、文字、規(guī)則圖形和復(fù)雜路徑組成圖形)。
  • 給圖形填充漸變顏色。
  • 組合圖形(包括組合圖形、圖形文字、圖片等)。
  • 設(shè)置圖形動畫集用戶交互。
  • 生成JSON, SVG數(shù)據(jù)等。
  • 生成Canvas對象自帶拖拉拽功能。

可以通過npm命令來安裝fabric.js庫:

npm install fabric --save

也可以通過cdn來引用:

<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>

下面就來看看img2Cvs方法是如何實現(xiàn)的:

function img2Cvs(img) {
   // 獲取并展示canvas畫布,并將畫布的大小設(shè)置為圖片的大小
    const cvs = document.getElementById("cvs");
    cvs.width = img.width;
    cvs.height = img.height;
    cvs.style.display = "block";
   
   // 創(chuàng)建一個畫布,并設(shè)置其位置和背景圖
    canvasFabric = new fabric.Canvas("cvs", {
      width: screenWidth,
      height: screenWidth,
      backgroundImage: new fabric.Image(img, {
        scaleX: screenWidth / img.width,
        scaleY: screenWidth / img.height
      })
    });
   // 切換模板
    changeHat();
  // 隱藏上傳圖片按鈕,展示下載圖片按鈕
    document.getElementsByClassName("upload-btn")[0].style.display = "none";
    document.getElementsByClassName("export-btn")[0].style.display = "block";
  }

這里面的fabric.Canvas()方法有兩個參數(shù),第一個參數(shù)是canvas畫布的id,第二個參數(shù)是初始化畫布時的配置項,這里我們設(shè)置了初始的畫布的大小以及背景圖,使用我們上傳的頭像作為背景圖。這里的背景圖是實例化的fabric.Image對象,該對象初始化時的第一個參數(shù)是圖片對象,第二個參數(shù)是圖片的樣式設(shè)置配置對象。​

當(dāng)創(chuàng)建好畫布之后,就需要切換出第一個模板,并將上傳圖片按鈕隱藏,以及將下載頭像按鈕顯示出來。這樣就完成了第一步的工作。下面就在來看看如何切換已有的模板。

4. 切換模板

接下來就來看看切換模板是如何實現(xiàn)的:

function changeHat() {
   // 隱藏當(dāng)前的模板
    document.getElementById(hat).style.display = "none";
   // 獲取所有的模板
    const hats = document.getElementsByClassName("hide");
    hat = "hat" + (+hat.replace("hat", "") + 1) % hats.length;
   // 獲取當(dāng)前的模板并展示出來
    const hatImage = document.getElementById(hat);
    hatImage.style.display = "block";
   // 如果當(dāng)前存在圖層,就將其移除
    if (hatInstance) {
      canvasFabric.remove(hatInstance)
    }
   // 將當(dāng)前的模板添加為圖層對象
    hatInstance = new fabric.Image(hatImage, {
      top: 0,
      left: 0,
      scaleX: screenWidth / hatImage.width,
      scaleY: screenWidth / hatImage.height,
      cornerColor: "#0b3a42",
      cornerStrokeColor: "#fff",
      cornerStyle: "circle",
      transparentCorners: false,
      rotatingPointOffset: 30
    });
   // 將圖層對象設(shè)置為不可拉伸
    hatInstance.setControlVisible({
       mt: false, 
       mb: false, 
       ml: false, 
       mr: false, 
       bl: false, 
       br: false, 
       tl: false, 
       tr: false, 
       mtr: false, 
    })
   // 將圖層添加到畫布中
    canvasFabric.add(hatInstance);
  }

在默認(rèn)情況下,fabric.js元素帶有八個點來縮放任何對象,這里我們是不希望用戶在水平或垂直方向?qū)?code>fabric對象進行拉伸的,可以通過setControlsVisibility()方法來設(shè)置其不可拉伸,該方法需要傳入一個配置對象,該對象包含八個縮放點,都設(shè)置為false即可。​

最后我們將使用模板生成的圖層添加到了畫布中,這里使用到了add方法,這是fabric提供的事件,以下為fabric.js官方提供的常用事件:

  • object:added 添加圖層
  • object:modified 編輯圖層
  • object:removed 移除圖層
  • selection:created 初次選中圖層
  • selection:updated 圖層選擇變化
  • selection:cleared 清空圖層選中

5. 輸出圖片

經(jīng)過上面的步驟,我們就初始化了一個畫布,畫布的背景是我們上傳的圖片,畫布上還有一個圖層,這個圖層是我們自己選擇的模板。最后一步就是輸出合成之后的圖片了。下面來看看點擊下載圖片按鈕之后會執(zhí)行哪些操作:

function exportFunc() {
  // 隱藏選擇框、上傳下載按鈕、canvas畫布
  document.getElementsByClassName("main-box")[0].style.display = "none";
  document.getElementsByClassName("operation-btns")[0].style.display = "none";
  document.getElementById("cvs").style.display = "none";

  // 將畫布生成URL,并賦值給對應(yīng)標(biāo)簽進行展示
  const exportImage = document.getElementById("export-img");
  exportImage.style.display = "block";
  exportImage.src = canvasFabric.toDataURL({
    width: screenWidth,
    height: screenWidth
  });
  // 下載生成的圖片
  window.confirm("是否下載頭像") ? download(exportImage.src, "國慶風(fēng)頭像", 'image/png') : void 0
}

這里我們使用toDataURL方法來將畫布實例對象生成圖片,這是fabric對象的方法,可以將畫布導(dǎo)出為圖片,導(dǎo)出的一個Base64格式的URL。這樣img標(biāo)簽獲取到這個URL之后就能顯示出來最終的圖片了。​

最后,還添加了一個可有可無的功能,就是下載生成的頭像,這里使用到了download.js庫,該方法的第一個參數(shù)是圖片的URL,第二個參數(shù)是下載圖片的名稱,第三個參數(shù)是圖片的格式。​

這就是這個小應(yīng)用的所有功能了,只是一個簡單的實現(xiàn),還存在一個BUG,主要提供一個實現(xiàn)的思路。我之前是沒有接觸過canvas以及畫布的概念的,這次漲知識了。以后有時間多學(xué)習(xí)了一下相關(guān)的使用,interesting!​

到此這篇關(guān)于國慶節(jié)到了,利用JS實現(xiàn)一個生成國慶風(fēng)頭像的小工具 詳解實現(xiàn)過程的文章就介紹到這了,更多相關(guān)利用JS實現(xiàn)一個生成國慶風(fēng)頭像內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 微信小程序 網(wǎng)絡(luò)API發(fā)起請求詳解

    微信小程序 網(wǎng)絡(luò)API發(fā)起請求詳解

    這篇文章主要介紹了微信小程序 網(wǎng)絡(luò)API發(fā)起請求詳解的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • 一款功能強大的markdown編輯器tui.editor使用示例詳解

    一款功能強大的markdown編輯器tui.editor使用示例詳解

    這篇文章主要為大家介紹了一款功能強大的markdown編輯器tui.editor使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • TypeScript對象解構(gòu)操作符在Spartacus實際項目開發(fā)中的應(yīng)用解析

    TypeScript對象解構(gòu)操作符在Spartacus實際項目開發(fā)中的應(yīng)用解析

    這篇文章主要為大家介紹了TypeScript對象解構(gòu)操作符在Spartacus實際項目開發(fā)中的應(yīng)用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • 使用PreloadJS加載圖片資源的基礎(chǔ)方法詳解

    使用PreloadJS加載圖片資源的基礎(chǔ)方法詳解

    PreloadJS是一個用來管理和協(xié)調(diào)相關(guān)資源加載的類庫,它可以方便的幫助你預(yù)先加載相關(guān)資源簡單點兒說就是一個加載插件,它可以做成頁面異步加載且頂部會有進度條動畫
    2020-02-02
  • Dom-api MutationObserver使用方法詳解

    Dom-api MutationObserver使用方法詳解

    這篇文章主要為大家介紹了Dom-api MutationObserver使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • JavaScript的單線程和異步詳細(xì)

    JavaScript的單線程和異步詳細(xì)

    這篇文章要給大家分享的是JavaScript的單線程和異步,其實單線程和異步確實不能同時成為一個語言的特性,js選擇了成為單線程的語言,所以它本身不可能是異步的,但js宿主環(huán)境是多線程,宿主環(huán)境通過某種方式使js具備了異步屬性,下面就來具體介紹,需要的朋友可以參考一下
    2021-10-10
  • js前端圖片加載異常兜底方案

    js前端圖片加載異常兜底方案

    這篇文章主要為大家介紹了js前端圖片加載異常兜底方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 分享5個JS?高階函數(shù)

    分享5個JS?高階函數(shù)

    這篇文章主要給大家分享了5個JS高階函數(shù),在JavaScript中,函數(shù)實際上也是一個數(shù)據(jù),也就是說函數(shù)也可以賦值給一個變量。本篇文章就來介紹一些JavaScript中的高階函數(shù)的用法,具有一定的參考價值,需要的朋友可以參考一下
    2021-12-12
  • 如果文字過長,則將過長的部分變成省略號顯示

    如果文字過長,則將過長的部分變成省略號顯示

    如果文字過長,則將過長的部分變成省略號顯示...
    2006-06-06
  • Evil.js項目源碼解讀

    Evil.js項目源碼解讀

    這篇文章主要為大家介紹了最近火爆全網(wǎng)的?Evil.js?源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08

最新評論