博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
html5仿小红书的图片标签功能
阅读量:6636 次
发布时间:2019-06-25

本文共 5097 字,大约阅读时间需要 16 分钟。

  最近做了这样的一个功能,在wap网页上实现类似小红书app里的图片标签功能,很是蛋疼。

  上传页示例如下图:

  可以看到最上面的①是展示区域,也是编辑标签的操作区域;中间②是可滑动的缩略图,在此选择要编辑的图片;最下面③是“添加图片”和“添加标签”两个按钮。

  废话不多说,下面介绍具体实现思路。

  首先就是要有“选择图片”的按钮。

1 
 

  其中的 multiple 属性是一次多选多张图片,但并不是所有浏览器都支持,比如UC,如果不支持就只能多选几次了。

  fileSelectHandler()的作用是处理你所选择的图片文件,首先要将图片显示在②的区域,这里的滑动效果是用swiper.js实现的,有兴趣的同学可以百度一下,有中文官网。但是手机拍照动不动就几兆的图片,不利于上传,而且手机浏览器处理时会有明显卡顿,所以需要压缩后再使用。

1 function fileSelectHandler() { 2     //... 3     //获取文件 4     var oFile = $('#image_file')[0].files; 5     for (var j = 0; j < oFile.length; j++) { 6         var oReader = new FileReader(); 7         oReader.readAsDataURL(oFile[j]); 8         oReader.onloadend = function (e) { 9             var img = new Image();10             img.src = this.result;11             img.onload = function () {12                 ctx.clearRect(0, 0, ww.width, ww.height);13                 //兼容苹果手机14                 var mpImg = new MegaPixImage(img);15                 mpImg.render(canvas, { maxWidth: 1000, maxHeight: 1000, quality: 0.1 });16                17                 var newImageData = canvas.toDataURL("image/jpeg", 0.3);18                 var result_image_obj = new Image();19                 result_image_obj.src = newImageData;20                 imgkey++;21                 var imgdata = dataURItoBlob(newImageData);//转码22                 fd.append("file" + imgkey, imgdata);//压入FormData等待提交23                 swiper.appendSlide("
");24 }25 }26 }27 }

  这里有一个坑,就是苹果手机对canvas的限制,包括图片大小以及canvas尺寸的限制,如果这里使用drawImage()来画canvas的话,一旦图片超出限制,是画不出来的,所以这里使用了megapix-image.js来绘制图片,有兴趣的同学看这里: 

  这样②区域就已经显示刚刚选取的图片了,我们需要点击其中一个,使其展现在①区域来进行下一步操作,而①区域就是一个canvas。

1  function clickImg(e) {2       //全局变量,记录当前操作的图片src3       currentimgsrc = e.src;     4       //全局变量,记录当前操作的图片顺序标识5       flag = e.attributes.key.nodeValue;6       //核心方法,将所选图片及其所有标签绘到①区7       drawMyCanvas();8  }

  在实现drawMyCanvas()方法前需要先解决图片及图片标签的存储问题,我们可以有多张图片,而每一张图片又可以有多个标签,因此,我的思路是由一个Dictionary来存储。

1 //键值对Dictionary 2 function Dictionary() { 3      this.data = new Array(); 4      this.put = function (key, value) { 5             this.data[key] = value; 6      }; 7      this.get = function (key) { 8             return this.data[key]; 9      };10 }11 var images = new Dictionary();

  Dictionary的key就是图片的顺序标识,即<img>元素的key属性值,而value则是一个Array,存储的就是标签集合,如下:

1 //图片标签2 function myLabel(x, y, radius, color,text) {3         this.x = x;//坐标X4         this.y = y;//坐标Y5         this.radius = radius;//半径6         this.color = color;//颜色7         this.isSelected = false;//是否是当前选中,拖动标签时用8         this.text = text;//标签文字9 }

  解决了存储,现在来为一个图片添加一个标签吧。

1 //在某个范围内生成随机数 2 function randomFromTo(from, to) { 3         return Math.floor(Math.random() * (to - from + 1) + from); 4 } 5 //添加标签 6 function addMyLabel(e) { 7         // 为圆圈设定一个大小和随机位置 8         var radius = 10; 9         //sidelength是canvas的边长(canvas是个正方形)10         var x = randomFromTo(0, sidelength-30);11         var y = randomFromTo(0, sidelength-30);12 13         var text = $("#labeltxt").val();//标签文字14         // 创建一个新标签15         var lab= new myLabel(x, y, radius, "white",text);16 17         // 把它保存在数组中18         if (images.get(flag) == undefined) { //还记得前面的flag变量吧19             var a=new Array();20             a.push(lab);21             images.put(flag,a);22         } else {23             images.get(flag).push(lab);24         }25         // 重新绘制画布26         drawMyCanvas();27 }

  好了,现在我们来看drawMyCanvas()方法吧。

function drawMyCanvas() {          var img = new Image();          img.src = imgsrc;//这也是前面的全局变量          img.onload = function () {              context.clearRect(0, 0, canvas.width, canvas.height);              context.drawImage(img, 0, 0, canvas.width, canvas.height);              //遍历当前图片的所有标签              for (var i = 0; i < images.get(flag).length; i++) {                  var onelabel= images.get(flag)[i];                   // 绘制标签的圆点                  context.globalAlpha = 0.85;                  context.beginPath();                  context.arc(onelabel.x, onelabel.y, onelabel.radius, 0, Math.PI * 2);                  context.fillStyle = onelabel.color;                  context.strokeStyle = "white";                  //选中的标签变粗,以便区分(标签拖动)                  if (onelabel.isSelected) {                      context.lineWidth = 2;                  }                  else {                      context.lineWidth = 1;                  }                  //绘制圆点与文字之间的折线                  context.moveTo(onelabel.x, onelabel.y);                  context.lineTo(onelabel.x + 15, onelabel.y - 20);                  context.moveTo(onelabel.x + 15, onelabel.y - 20);                  context.lineTo(onelabel.x + 30, onelabel.y - 20);                  context.fill();                  context.stroke();                  //绘制标签文字                  context.font = "bold 20px 宋体";                  context.fillText(onelabel.text, onelabel.x + 33, onelabel.y - 15);               }          }      }

   最后就是标签移动的功能了,大致的想法就是随着拖动事件即时更新标签的坐标,并调用drawMyCanvas()方法不断重绘画布,具体实现大家可以参考这篇文章:

    

  这篇文章给了我很大帮助,感谢。

转载于:https://www.cnblogs.com/Qingxin1990/p/6142773.html

你可能感兴趣的文章
salt更改yum源
查看>>
【转载】GITHUB之GIT BASH使用教程
查看>>
C/C++回调函数
查看>>
phalcon队列使用Queueing
查看>>
java synchronized详解(二)
查看>>
优秀的 Java 程序员所应该知道的 Java 知识
查看>>
KVM部署搭建
查看>>
MySQL5.7.18 for Linux7.2(二进制安装)
查看>>
设置/修改linux上的swap交换分区的方法
查看>>
vim使用小结
查看>>
Linux新建虚拟机
查看>>
我的友情链接
查看>>
JAVA设计模式:简单工厂、工厂方法、抽象工厂之小结与区别 .
查看>>
.NET概念:消息机制
查看>>
面试官提问最常见的问题与影片在回答分享-70问
查看>>
Java annotation源码解读
查看>>
前端功能资料
查看>>
《数据结构与算法分析--c语言描述》之第一章:引论
查看>>
DAHDI 卡安装配置
查看>>
IE 8下的pdf打不开
查看>>