html5仿小红书的图片标签功能

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

  上传页示例如下图:

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

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

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

1 <input type="file" name="fileToUpload" accept="image/*" multiple onchange="fileSelectHandler()" id="image_file" />

  其中的 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("<div class=\"swiper-slide\"><a href=\"javascript:;\"><img key=\"" + imgkey + "\" onclick=\"clickImg(this)\" src=\"" + result_image_obj.src + "\" /></a></div>");
24             }
25         }
26     }
27 }

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

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

1  function clickImg(e) {
2       //全局变量,记录当前操作的图片src
3       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;//坐标X
4         this.y = y;//坐标Y
5         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()方法不断重绘画布,具体实现大家可以参考这篇文章:

  ----->HTML5 - Canvas的使用样例14(图形增加鼠标点击、拖动交互)  

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

时间: 2024-10-26 00:26:59

html5仿小红书的图片标签功能的相关文章

Android 仿小红书自定义展开 收起的TextView

详解 故事是这么开始的,有个产品需求需求,要做一个小红书文本折叠的功能,于是就有了后面一系列的东西.不过实现了之后,自己对 TextView 截取文本也了解了不少,具体效果如下: 先总结一下实现的时候需要注意的几个点: 显示 "-展开" 时,是截取的一定行数之后,在最后一行的末尾直接显示 "收起" 显示在全部文本的下一行,并且是右对齐 展开和收起的动画效果 如果归纳的不完善,还请指出,不想看过程了可以直接跳到文末查看ExpandableTextView代码 文本的截

仿半塘图片加入标签功能

模仿半塘app的图片加入标签功能,刚開始反编译了半塘的代码,结果代码太多了,用一些三方的东西.觉的比較麻烦,这里自己写了一下实现.感觉和半塘的没啥差别(自我感觉良好,嘿嘿) 一.半塘功能实现步骤 二.半塘实现分析 功能分析 - 本地相冊选择 - 加入图片 - 加入标签 - 标签移动 - 标签动画切换 - 图片生成 实现说明 (1) 标签类型有两种 第一种是单个标签 另外一种是两个标签 (2) 第一种标签的包括:原点和文字 (3) 第二步标签包括:原点.文字和横线 (4) 原点的位置是点击的位置

类似小红书标签效果(补间动画)

昨天老大给布置个任务,为我们的app做下调研,app中有标签的存在,类似小红书和nice的添加标签模式,于是我就试着做出那个一闪一闪的标注点~   仔细看了看小红书的闪闪的标签,得出一个结论: 它是个动画   好吧,这简直是废话. 其实一开始我的思路是拿来主义,去网上找了找类似的“小红书标签效果”等等,然后我发现他们用自定义控件完成了一个这样的动画..就这样,我华丽丽的跑偏了呃呃呃..   自定义控件我不熟啊!! 学. 花了半个下午研究自定义控件,好不容易写出了动画效果. 这个效果的原理是这个样

Android 仿微信朋友圈发动态功能(相册图片多选)

代码分享 代码名称: 仿微信朋友圈发动态功能(相册图片多选) 代码描述: 仿微信朋友圈发动态功能(相册图片多选) 代码托管地址: http://www.apkbus.com/android-152760-1-1.html 代码作者: 楼主 代码效果图: 本帖最后由 ^.^ 于 2014-7-8 16:23 编辑 <ignore_js_op> <ignore_js_op> <ignore_js_op> DEMO一共13个类 大约2000行代码,童鞋们耐心点看基本思路是:1

AnimatedPathView实现自定义图片标签

老早用过小红书app,对于他们客户端笔记这块的设计非常喜欢,恰好去年在小红书的竞争对手公司,公司基于产品的考虑和产品的发展,也需要将app社交化,于是在社区分享这块多多少少参照了小红书的设计,这里面就有一个比较有意思的贴纸,标签等设计,这里用到了GpuImage的库,这个demo我也将代码开源了,有需要的去fork我的github的代码,今天要说的是详情页面的AnimatedPathView实现可以动起来的标签.(之前我们项目中由于时间问题,将这种效果用h5实现了,不过现在回React Nati

HTML5实现类似刮刮卡的功能

HTML5实现类似刮刮卡的功能 有这样一个功能,当我们使用微信公众号,发送图片时......此处省略300字! 注意要点设置: 1.设置用户缩放:user-scalable=no|yes <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /> 2.禁止拖动: docu

2月第3周业务风控关注|上海网信办复测23个被约谈APP 涉及1号店、小红书等

易盾业务风控周报每周呈报值得关注的安全技术和事件,包括但不限于内容安全.移动安全.业务安全和网络安全,帮助企业提高警惕,规避这些似小实大.影响业务健康发展的安全风险. 1.上海网信办复测23个被约谈APP 涉及1号店.小红书等 近日,上海市网信办对此前被约谈的23个APP开展"回头看"复测工作,要求各企业按照整改报告切实做好整改工作.2018年10月,上海市网信办对本地最常用的23个App获取用户个人信息等权限申请情况开展安全抽查,并就抽查中发现的申请权限不合理.过度索取用户个人信息等

【微信公众平台开发】借用微信内置图片浏览功能

开发微信公众平台时,碰到文章中有很多图片,需要可以点开图片浏览:那么点击图片直接调用微信客户端自带的图片播放组件会省很多事.否则你得去摆弄折腾各种图片浏览插件,比如photoswipe. 个人封装功能成一个js文件.把该文件放到你需要的网页里面即可,这样文章当你点击图片时,就会调用图片浏览功能! <script> function addLoadEvent(func){ //将函数作为参数,此函数就是 onload 触发时需要执行的某个函数 var oldonload=window.onloa

html5开发手机打电话发短信功能,html5的高级开发,html5开发大全,html手机电话短信功能详解

在很多的手机网站上,有打电话和发短信的功能,对于这些功能是如何实现的呢.其实不难,今天我们就用html5来实现他们.简单的让你大开眼界. HTML5 很容易写,但创建网页时,您经常需要重复做同样的任务,如创建表单.在这...有 HTML5 启动模板.空白图片.打电话和发短信.自动完成等等,帮助你提高开发效率的同时,还带来了更炫的功能.好了,我们今天就来做一做看看效果吧!! 看代码: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitio