您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery | 小程序 |

国庆节到了,利用JS实现一个生成国庆风头像的小工具 详解实现过程

51自学网 2022-02-21 13:40:29
  javascript

这里用到的技术:

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

先上体验链接:g.cuggz.com/ 。​

注:可以点击上方的连接进行使用,不过我的域名被TX屏蔽了,还在申诉中,所以无法在QQ、微信中打开,需要复制链接到浏览器进行查看、使用。​

下面是这个小工具的截图:

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>    <!-- 导出图 -->    <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')}

这里只是简单的实现,仅供参考。还有很多可以优化的地方,这里不在修改,有兴趣的可以自己进行个性化定制。

2. 图片上传和展示

接下来就是逻辑部分的实现了。首先,有几个全局变量需要先定义,后面会用到:

let canvasFabric;   // 画布实例let hat = "hat0";  // 当前的模板classlet hatInstance;  // 模板图层实例const screenWidth = document.getElementById("content").scrollHeight;  // 内容框的高度

之后就需要处理上传的图片并将他展示在页面上:

function viewer() {  // 获取上传的图片文件  const file = document.getElementById("upload").files[0];  // 获取需要展示图片的标签  const img = document.getElementById("img");  // 创建文件读取文件对象  const reader = new FileReader();  if (file) {    // 将文件转化为Base64    reader.readAsDataURL(file);    // 当文件读取成功之后触发    reader.onload = () => {      // 将base64的url赋值给要展示图片的标签      img.src = reader.result;      // 图片加载完成触发      img.onload = () => img2Cvs(img);    }  } else {    img.src = ""  }}

这里使用到了HTML5FileReader对象,它提供了读取文件的方法和包含读取结果的事件模型。可以使用new来初始化对象,FileReader对象包含四个方法,其中 3 个用以读取文件,另一个用来中断读取。需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result 属性中。这里用到了readAsDataURL方法,MDN对该方法的介绍如下:

readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。

也就是说将上传的图片转化为了一个Base64格式的URL,并赋值给了展示图片的标签,这样这个标签就显示出现这个头像了,效果如下:

这样就完成了图片的上传和展示,接下来就该初始化一个画布了。

3. 初始化画布

在上面的代码的最后执行了 img.load,这里的 onload 事件会在图片加载完成后立即执行。在图片展示完成之后会执行img2Cvs方法,这个方法主要用来初始化一块画布,顺便展示和隐藏页面的部分元素。

img2Cvs方法中使用到了 fabric库,Fabric.js是一个可以简化Canvas程序编写的库。 Fabric.jsCanvas提供所缺少的对象模型, svg parser, 交互和一整套其他不可或缺的工具。Canvas提供一个好的画布能力, 但是Api不够友好。Fabric.js就是为此而开发,它主要就是用对象的方式去编写代码。Fabric.js能做的事情如下:

  • Canvas上创建、填充图形(包括图片、文字、规则图形和复杂路径组成图形)。
  • 给图形填充渐变颜色。
  • 组合图形(包括组合图形、图形文字、图片等)。
  • 设置图形动画集用户交互。
  • 生成JSON, SVG数据等。
  • 生成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方法是如何实现的:

function img2Cvs(img) {   // 获取并展示canvas画布,并将画布的大小设置为图片的大小    const cvs = document.getElementById("cvs");    cvs.width = img.width;    cvs.height = img.height;    cvs.style.display = "block";      // 创建一个画布,并设置其位置和背景图    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()方法有两个参数,第一个参数是canvas画布的id,第二个参数是初始化画布时的配置项,这里我们设置了初始的画布的大小以及背景图,使用我们上传的头像作为背景图。这里的背景图是实例化的fabric.Image对象,该对象初始化时的第一个参数是图片对象,第二个参数是图片的样式设置配置对象。​

当创建好画布之后,就需要切换出第一个模板,并将上传图片按钮隐藏,以及将下载头像按钮显示出来。这样就完成了第一步的工作。下面就在来看看如何切换已有的模板。

4. 切换模板

接下来就来看看切换模板是如何实现的:

function changeHat() {   // 隐藏当前的模板    document.getElementById(hat).style.display = "none";   // 获取所有的模板    const hats = document.getElementsByClassName("hide");    hat = "hat" + (+hat.replace("hat", "") + 1) % hats.length;   // 获取当前的模板并展示出来    const hatImage = document.getElementById(hat);    hatImage.style.display = "block";   // 如果当前存在图层,就将其移除    if (hatInstance) {      canvasFabric.remove(hatInstance)    }   // 将当前的模板添加为图层对象    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    });   // 将图层对象设置为不可拉伸    hatInstance.setControlVisible({       mt: false,        mb: false,        ml: false,        mr: false,        bl: false,        br: false,        tl: false,        tr: false,        mtr: false,     })   // 将图层添加到画布中    canvasFabric.add(hatInstance);  }

在默认情况下,fabric.js元素带有八个点来缩放任何对象,这里我们是不希望用户在水平或垂直方向对fabric对象进行拉伸的,可以通过setControlsVisibility()方法来设置其不可拉伸,该方法需要传入一个配置对象,该对象包含八个缩放点,都设置为false即可。​

最后我们将使用模板生成的图层添加到了画布中,这里使用到了add方法,这是fabric提供的事件,以下为fabric.js官方提供的常用事件:

  • object:added 添加图层
  • object:modified 编辑图层
  • object:removed 移除图层
  • selection:created 初次选中图层
  • selection:updated 图层选择变化
  • selection:cleared 清空图层选中

5. 输出图片

经过上面的步骤,我们就初始化了一个画布,画布的背景是我们上传的图片,画布上还有一个图层,这个图层是我们自己选择的模板。最后一步就是输出合成之后的图片了。下面来看看点击下载图片按钮之后会执行哪些操作:

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,并赋值给对应标签进行展示  const exportImage = document.getElementById("export-img");  exportImage.style.display = "block";  exportImage.src = canvasFabric.toDataURL({    width: screenWidth,    height: screenWidth  });  // 下载生成的图片  window.confirm("是否下载头像") ? download(exportImage.src, "国庆风头像", 'image/png') : void 0}

这里我们使用toDataURL方法来将画布实例对象生成图片,这是fabric对象的方法,可以将画布导出为图片,导出的一个Base64格式的URL。这样img标签获取到这个URL之后就能显示出来最终的图片了。​

最后,还添加了一个可有可无的功能,就是下载生成的头像,这里使用到了download.js库,该方法的第一个参数是图片的URL,第二个参数是下载图片的名称,第三个参数是图片的格式。​

这就是这个小应用的所有功能了,只是一个简单的实现,还存在一个BUG,主要提供一个实现的思路。我之前是没有接触过canvas以及画布的概念的,这次涨知识了。以后有时间多学习了一下相关的使用,interesting!​

到此这篇关于国庆节到了,利用JS实现一个生成国庆风头像的小工具 详解实现过程的文章就介绍到这了,更多相关利用JS实现一个生成国庆风头像内容请搜索51zixue.net以前的文章或继续浏览下面的相关文章希望大家以后多多支持51zixue.net!


下载地址:
vue2 vue3中使用Echarts详细
JavaScript实现密码框输入验证
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。