起步软件技术论坛
搜索
 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3767|回复: 6

[分享] 图片涂鸦

  [复制链接]

79

主题

581

帖子

3464

积分

论坛元老

Rank: 8Rank: 8

积分
3464
QQ
发表于 2016-6-28 20:56:40 | 显示全部楼层 |阅读模式
案例很粗糙,需要优化的地方很多,只是把网上一个案例搬到了wex5里,提供一个思路。哪位有时间可以优化下,照片可以canvas画进去。

小尾巴~~世间万难,无非一拖二懒三不读书

79

主题

581

帖子

3464

积分

论坛元老

Rank: 8Rank: 8

积分
3464
QQ
 楼主| 发表于 2016-6-28 20:57:31 | 显示全部楼层
  1. * {
  2.         margin: 0;
  3.         padding: 0;
  4. }

  5. .fa {
  6.         width: 300px;
  7.         margin: 0 auto;
  8. }

  9. .top {
  10.         margin: 20px 0;
  11. }

  12. .top input {
  13.         width: 25px;
  14.         height: 25px;
  15.         border: 1px solid #fff;
  16.         border-radius: 4px;
  17.         background: #ddd;
  18. }

  19. .top .i1 {
  20.         background: #000000;
  21. }

  22. .top .i2 {
  23.         background: #FF0000;
  24. }

  25. .top .i3 {
  26.         background: #80FF00;
  27. }

  28. .top .i4 {
  29.         background: #00FFFF;
  30. }

  31. .top .i5 {
  32.         background: #808080;
  33. }

  34. .top .i6 {
  35.         background: #FF8000;
  36. }

  37. .top .i7 {
  38.         background: #408080;
  39. }

  40. .top .i8 {
  41.         background: #8000FF;
  42. }

  43. .top .i9 {
  44.         background: #CCCC00;
  45. }

  46. #canvas {
  47.         background: #eee;
  48.         cursor: default;
  49. }

  50. .font input {
  51.         font-size: 14px;
  52. }

  53. .top .grea {
  54.         background: #aaa;
  55. }
复制代码



小尾巴~~世间万难,无非一拖二懒三不读书
回复 支持 反对

使用道具 举报

79

主题

581

帖子

3464

积分

论坛元老

Rank: 8Rank: 8

积分
3464
QQ
 楼主| 发表于 2016-6-28 20:58:23 | 显示全部楼层
  1. define(function(require) {
  2.         var $ = require("jquery");
  3.         var justep = require("$UI/system/lib/justep");

  4.         var Model = function() {
  5.                 this.callParent();
  6.         };

  7.         Model.prototype.modelLoad = function(event) {
  8.                 this.x = [];// 记录鼠标移动是的X坐标
  9.                 this.y = [];// 记录鼠标移动是的Y坐标
  10.                 this.clickDrag = [];
  11.                 this.lock = false;// 鼠标移动前,判断鼠标是否按下
  12.                 this.isEraser = false;
  13.                 this.storageColor = "#000000";
  14.                 this.eraserRadius = 15;// 擦除半径值
  15.                 this.color = [ "#000000", "#FF0000", "#80FF00", "#00FFFF", "#808080", "#FF8000", "#408080", "#8000FF", "#CCCC00" ];// 画笔颜色值
  16.                 this.fontWeight = [ 2, 5, 8 ];

  17.                 this.$ = function(id) {
  18.                         return typeof id == "string" ? document.getElementById(id) : id;
  19.                 };
  20.                 this.canvas = this.$("canvas");
  21.                 if (this.canvas.getContext) {
  22.                 } else {
  23.                         alert("您的浏览器不支持 canvas 标签");
  24.                         return;
  25.                 }
  26.                 this.cxt = this.canvas.getContext('2d');
  27.                 this.cxt.lineJoin = "round";// context.lineJoin - 指定两条线段的连接方式
  28.                 this.cxt.lineWidth = 5;// 线条的宽度
  29.                 this.iptClear = this.$("clear");
  30.                 this.revocation = this.$("revocation");
  31.                 this.imgurl = this.$("imgurl");// 图片路径按钮
  32.                 this.w = this.canvas.width;// 取画布的宽
  33.                 this.h = this.canvas.height;// 取画布的高
  34.                 this.touch = ("createTouch" in document);// 判定是否为手持设备
  35.                 this.StartEvent = this.touch ? "touchstart" : "mousedown";// 支持触摸式使用相应的事件替代
  36.                 this.MoveEvent = this.touch ? "touchmove" : "mousemove";
  37.                 this.EndEvent = this.touch ? "touchend" : "mouseup";
  38.                 this.bind();
  39.         };

  40.         Model.prototype.bind = function() {
  41.                 var t = this;
  42.                 /* 清除画布 */
  43.                 this.iptClear.onclick = function() {
  44.                         t.clear();
  45.                 };
  46.                 /* 鼠标按下事件,记录鼠标位置,并绘制,解锁lock,打开mousemove事件 */
  47.                 this.canvas['on' + t.StartEvent] = function(e) {
  48.                         var touch = t.touch ? e.touches[0] : e;
  49.                         var _x = touch.clientX - touch.target.offsetLeft;// 鼠标在画布上的x坐标,以画布左上角为起点
  50.                         var _y = touch.clientY - touch.target.offsetTop;// 鼠标在画布上的y坐标,以画布左上角为起点
  51.                         this._x = _x;
  52.                         this._y = _y;
  53.                         if (t.isEraser) {

  54.                                 t.resetEraser(_x, _y, touch);
  55.                         } else {
  56.                                 t.movePoint(_x, _y);// 记录鼠标位置
  57.                                 t.drawPoint();// 绘制路线
  58.                         }
  59.                         t.lock = true;
  60.                 };
  61.                 /* 鼠标移动事件 */
  62.                 this.canvas['on' + t.MoveEvent] = function(e) {
  63.                         var touch = t.touch ? e.touches[0] : e;
  64.                         if (t.lock)// t.lock为true则执行
  65.                         {
  66.                                 var _x = touch.clientX - touch.target.offsetLeft;// 鼠标在画布上的x坐标,以画布左上角为起点
  67.                                 var _y = touch.clientY - touch.target.offsetTop;// 鼠标在画布上的y坐标,以画布左上角为起点
  68.                                 if (t.isEraser) {
  69.                                         // if(t.Timer)clearInterval(t.Timer);
  70.                                         // t.Timer=setInterval(function(){
  71.                                         t.resetEraser(_x, _y, touch);
  72.                                         // },10);
  73.                                 } else {
  74.                                         t.movePoint(_x, _y, true);// 记录鼠标位置
  75.                                         t.drawPoint();// 绘制路线
  76.                                 }
  77.                         }
  78.                 };
  79.                 this.canvas['on' + t.EndEvent] = function(e) {
  80.                         /* 重置数据 */
  81.                         t.lock = false;
  82.                         t.x = [];
  83.                         t.y = [];
  84.                         t.clickDrag = [];
  85.                         clearInterval(t.Timer);
  86.                         t.Timer = null;
  87.                 };
  88.                 this.revocation.onclick = function() {
  89.                         t.redraw();
  90.                 };
  91.                 this.changeColor();
  92.                 this.imgurl.onclick = function() {
  93.                         t.getUrl();
  94.                 };
  95.                 /* 橡皮擦 */
  96.                 this.$("eraser").onclick = function(e) {
  97.                         t.isEraser = true;
  98.                         t.$("error").style.color = "red";
  99.                         t.$("error").innerHTML = "您已使用橡皮擦!";
  100.                 };
  101.         };

  102.         Model.prototype.movePoint = function(x, y, dragging) {
  103.                 /* 将鼠标坐标添加到各自对应的数组里 */
  104.                 this.x.push(x);
  105.                 this.y.push(y);
  106.                 this.clickDrag.push(y);
  107.         };

  108.         Model.prototype.drawPoint = function(x, y, radius) {
  109.                 for (var i = 0; i < this.x.length; i++)// 循环数组
  110.                 {
  111.                         this.cxt.beginPath();// context.beginPath() , 准备绘制一条路径
  112.                         if (this.clickDrag[i] && i) {// 当是拖动而且i!=0时,从上一个点开始画线。
  113.                                 this.cxt.moveTo(this.x[i - 1], this.y[i - 1]);// context.moveTo(x,
  114.                                 // y) ,
  115.                                 // 新开一个路径,并指定路径的起点
  116.                         } else {
  117.                                 this.cxt.moveTo(this.x[i] - 1, this.y[i]);
  118.                         }
  119.                         this.cxt.lineTo(this.x[i], this.y[i]);// context.lineTo(x, y)
  120.                         // ,
  121.                         // 将当前点与指定的点用一条笔直的路径连接起来
  122.                         this.cxt.closePath();// context.closePath() , 如果当前路径是打开的则关闭它
  123.                         this.cxt.stroke();// context.stroke() , 绘制当前路径
  124.                 }
  125.         };

  126.         Model.prototype.clear = function() {
  127.                 this.cxt.clearRect(0, 0, this.w, this.h);// 清除画布,左上角为起点
  128.         };

  129.         Model.prototype.redraw = function() {
  130.                 /* 撤销 */
  131.                 this.cxt.restore();
  132.         };

  133.         Model.prototype.preventDefault = function() {
  134.                 /* 阻止默认 */
  135.                 var touch = this.touch ? e.touches[0] : e;
  136.                 if (this.touch)
  137.                         touch.preventDefault();
  138.                 else
  139.                         window.event.returnValue = false;
  140.         };

  141.         Model.prototype.changeColor = function() {
  142.                 /* 为按钮添加事件 */
  143.                 var t = this, iptNum = this.$("color").getElementsByTagName("input"), fontIptNum = this.$("font").getElementsByTagName("input");
  144.                 for (var i = 0, l = iptNum.length; i < l; i++) {
  145.                         iptNum[i].index = i;
  146.                         iptNum[i].onclick = function() {
  147.                                 t.cxt.save();
  148.                                 t.cxt.strokeStyle = t.color[this.index];
  149.                                 t.storageColor = t.color[this.index];
  150.                                 t.$("error").style.color = "#000";
  151.                                 t.$("error").innerHTML = "如果有错误,请使用橡皮擦:";
  152.                                 t.cxt.strokeStyle = t.storageColor;
  153.                                 t.isEraser = false;
  154.                         }
  155.                 }
  156.                 for (var i = 0, l = fontIptNum.length; i < l; i++) {
  157.                         t.cxt.save();
  158.                         fontIptNum[i].index = i;
  159.                         fontIptNum[i].onclick = function() {
  160.                                 t.changeBackground(this.index);
  161.                                 t.cxt.lineWidth = t.fontWeight[this.index];
  162.                                 t.$("error").style.color = "#000";
  163.                                 t.$("error").innerHTML = "如果有错误,请使用橡皮擦:";
  164.                                 t.isEraser = false;
  165.                                 t.cxt.strokeStyle = t.storageColor;
  166.                         }
  167.                 }
  168.         };

  169.         Model.prototype.changeBackground = function(num) {
  170.                 /* 添加画笔粗细的提示背景颜色切换,灰色为当前 */
  171.                 var fontIptNum = this.$("font").getElementsByTagName("input");
  172.                 for (var j = 0, m = fontIptNum.length; j < m; j++) {
  173.                         fontIptNum[j].className = "";
  174.                         if (j == num)
  175.                                 fontIptNum[j].className = "grea";
  176.                 }
  177.         };

  178.         Model.prototype.getUrl = function() {
  179.                 this.$("html").innerHTML = this.canvas.toDataURL();
  180.         };

  181.         Model.prototype.resetEraser = function(_x, _y, touch) {
  182.                 /*使用橡皮擦-提醒*/
  183.                 var t = this;
  184.                 //this.cxt.lineWidth = 30;
  185.                 /*source-over 默认,相交部分由后绘制图形的填充(颜色,渐变,纹理)覆盖,全部浏览器通过*/
  186.                 t.cxt.globalCompositeOperation = "destination-out";
  187.                 t.cxt.beginPath();
  188.                 t.cxt.arc(_x, _y, t.eraserRadius, 0, Math.PI * 2);
  189.                 t.cxt.strokeStyle = "rgba(250,250,250,0)";
  190.                 t.cxt.fill();
  191.                 t.cxt.globalCompositeOperation = "source-over"
  192.         };

  193.         return Model;
  194. });
复制代码



小尾巴~~世间万难,无非一拖二懒三不读书
回复 支持 反对

使用道具 举报

79

主题

581

帖子

3464

积分

论坛元老

Rank: 8Rank: 8

积分
3464
QQ
 楼主| 发表于 2016-6-28 20:58:39 | 显示全部楼层
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <div xmlns="http://www.w3.org/1999/xhtml" component="$UI/system/components/justep/window/window" design="device:m;"
  3.   xid="window" class="window">  
  4.   <div component="$UI/system/components/justep/model/model" xid="model" style="left:18px;top:83px;height:244px;"
  5.     onLoad="modelLoad"/>  
  6.   <div component="$UI/system/components/justep/panel/panel" class="x-panel x-full"
  7.     xid="panel1">
  8.     <div class="x-panel-content" xid="content1">
  9.       <div xid="div2" class="fa">
  10.         <div xid="div3" class="top">
  11.           <div xid="div4" id="color">请选择画笔颜色:
  12.             <input type="button" value="" xid="input1" class="i1"/>  
  13.             <input type="button" value="" xid="input2" class="i2"/>  
  14.             <input type="button" value="" xid="input3" class="i3"/>  
  15.             <input type="button" value="" xid="input4" class="i4"/>  
  16.             <input type="button" value="" xid="input5" class="i5"/>  
  17.             <input type="button" value="" xid="input6" class="i6"/>  
  18.             <input type="button" value="" xid="input7" class="i7"/>  
  19.             <input type="button" value="" xid="input8" class="i8"/>  
  20.             <input type="button" value="" xid="input9" class="i9"/>
  21.           </div>  
  22.           <div xid="div5" class="font" id="font">请选择画笔宽度:
  23.             <input type="button" value="细" xid="input10"/>  
  24.             <input type="button" value="中" xid="input11" class="grea"/>  
  25.             <input type="button" value="粗" xid="input12"/>
  26.           </div>
  27.         <div xid="div6"><span xid="span1" id="error"><![CDATA[如果有错误,请使用橡皮擦:]]></span>
  28.   <input type="button" value="橡皮擦" xid="input13" style="width:60px;font-size:14px;" id="eraser"></input></div>
  29.   <input type="button" value="清除画布" xid="input14" style="width:74px;" id="clear"></input>
  30.   <input type="button" value="撤销" xid="input15" style="width:38px;" id="revocation"></input>
  31.   <input type="button" value="导出图片路径" xid="input16" style="width:99px;" id="imgurl"></input></div>
  32.       </div>  
  33.       <div xid="main" style="text-align:center;">
  34.         <canvas id="canvas" width="300" height="420"/>
  35.       </div>
  36.     <div xid="div7" id="html"></div>
  37.   <div xid="div1" style="clear:both"></div></div>
  38.   </div>
  39. </div>
复制代码



小尾巴~~世间万难,无非一拖二懒三不读书
回复 支持 反对

使用道具 举报

2

主题

4

帖子

80

积分

初级会员

Rank: 2

积分
80
QQ
发表于 2016-6-28 21:38:58 | 显示全部楼层
在APP模式下不能使用
回复 支持 反对

使用道具 举报

79

主题

581

帖子

3464

积分

论坛元老

Rank: 8Rank: 8

积分
3464
QQ
 楼主| 发表于 2016-6-29 09:03:20 | 显示全部楼层
lezaiyingyong 发表于 2016-6-28 21:38
在APP模式下不能使用

真机测试

小尾巴~~世间万难,无非一拖二懒三不读书
回复 支持 反对

使用道具 举报

150

主题

511

帖子

2350

积分

金牌会员

Rank: 6Rank: 6

积分
2350
QQ
发表于 2017-2-12 16:46:27 | 显示全部楼层
不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|X3技术论坛|Justep Inc.    

GMT+8, 2024-5-4 23:54 , Processed in 0.058862 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表