<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      artwlfeedback.js——仿google搜索結果頁的“發送反饋”功能

      緣起

        不知道大家有沒有用過google搜索結果頁的“發送反饋”功能(還沒有用過的,快去體驗一下吧),個人用過后覺得非常酷,特別適合反饋界面視覺問題,于是就有了本文介紹的小作品。

        給不能FQ的截張圖吧:

      效果

        不知道大家有沒有注意到本頁最下面有個“發送反饋”的固定鏈接,可以點擊看看效果。下面是chrome下的效果:

        注:需要瀏覽器支持HTML5

      原理

        通過查看google搜索結果頁反饋時的代碼可以看到,是把頁面生成了一個canvas,然后在canvas上畫矩形來實現的:

        所以在不支持canvas的瀏覽器下,是沒有這個效果的。

        我的方案是利用html2canvas庫把頁面內容渲染成一個canvas,然后利用canvas的畫圖功能來做標記,然后把canvas轉換為base64格式的圖片用于發送反饋。

      代碼

        代碼比較簡單,就是先用調用html2canvas庫把頁面轉換成一個canvas,然后把這個canvas添加到頁面上,然后再創建一個空白的canvas用于畫標記(矩形),添加一個空白的canvas的作用是如果標記有誤方便清除。其他的就是canvas的畫圖的代碼,最后當用戶點擊保存時合并前面創建的兩個canvas,并利用canvas的toDataUrl方法把canvas轉換為base64格式的png圖片輸出,后續的操作開發者就可以自己定義了。

        JS代碼如下(canvas畫圖的代碼有參考 Javascript實現canvas畫圖功能 一文):

      var artwlfeedback = (function(){
          var load =function(callback){
              html2canvas(document.body, {
                  onrendered: function(canvas) {
                      canvas.id = "artwlfeedback_pagecanvas";
                      var cv = document.createElement("canvas");
                      cv.width = canvas.width;
                      cv.height = canvas.height;
                      cv.style.background = "#666";
                      cv.id = "artwlfeedback_canvas";
                      document.body.appendChild(cv);
                      document.body.appendChild(canvas);
                      init(callback);
                  }
              });
          }
      
          var init = function(callback){
              var paint={
                  init:function(){
                      this.addDrawTool();
                      this.load();
                      this.bind();
                  },
                  addDrawTool: function(){
                      var NewLine = '\n';
                      var drawToolHtml = '';
                      drawToolHtml+='    <div id="artwlfeedback_operate">'+NewLine;
                      drawToolHtml+='        <input id="artwlfeedback_clear" type="button" value=" " title="clear"/>'+NewLine;
                      drawToolHtml+='        <input id="artwlfeedback_cancel" type="button" value=" " title="cancel"/>'+NewLine;
                      drawToolHtml+='        <input id="artwlfeedback_save" type="button" value=" " title="save as image" />'+NewLine;
                      drawToolHtml+='    </div>'+NewLine;
                      var drawToolNode = document.createElement("div");
                      drawToolNode.id = "artwlfeedback_draw_tool";
                      drawToolNode.className = "artwlfeedback";
                      drawToolNode.innerHTML = drawToolHtml;
                      document.body.appendChild(drawToolNode);
                  },
                  load:function(){
                      this.x=[];//記錄鼠標移動是的X坐標
                      this.y=[];//記錄鼠標移動是的Y坐標
                      this.clickDrag=[];
                      this.Rectangles = [];
                      this.lock=false;//鼠標移動前,判斷鼠標是否按下
                      this.storageColor="#000000";
                      this.$=function(id){return typeof id=="string"?document.getElementById(id):id;};
                      this.canvas=this.$("artwlfeedback_canvas");
                      this.pageCanvas = this.$("artwlfeedback_pagecanvas");
                      this.cxt=this.canvas.getContext('2d');
                      this.cxt.lineJoin = "round";//context.lineJoin - 指定兩條線段的連接方式
                      this.cxt.lineWidth = 2;//線條的寬度
                      this.iptClear=this.$("artwlfeedback_clear");
                      this.cancel= this.$("artwlfeedback_cancel");
                      this.saveAs = this.$("artwlfeedback_save");
                      this.w=this.pageCanvas.width;//取畫布的寬
                      this.h=this.pageCanvas.height;//取畫布的高
                      this.touch =("createTouch" in document);//判定是否為手持設備
                      this.StartEvent = this.touch ? "touchstart" : "mousedown";//支持觸摸式使用相應的事件替代
                      this.MoveEvent = this.touch ? "touchmove" : "mousemove";
                      this.EndEvent = this.touch ? "touchend" : "mouseup";
                      this.drawTool = this.$("artwlfeedback_draw_tool");
                      this.callback = callback;
                  },
                  bind:function(){
                      var t=this;
                      /*清除畫布*/
                      this.iptClear.onclick=function(){
                          t.clear();
                          t.Rectangles.length = [];
                      };
                      this.cancel.onclick = function(){
                          t.removeNode(t.pageCanvas);
                          t.removeNode(t.canvas);
                          t.removeNode(t.drawTool);
                      };
                      /*保存*/
                      this.saveAs.onclick = function(){
                          //創建新canvas用于合并pageCanvas和canvas
                          var saveCanvas = document.createElement('canvas');
                          saveCanvas.width = t.w;
                          saveCanvas.height = t.h;
      
                          var saveCxt = saveCanvas.getContext('2d');
                          saveCxt.fillStyle = "#666";
                          saveCxt.fillRect(0, 0, t.w, t.h);
                          saveCxt.globalAlpha=1;
                          saveCxt.drawImage(t.canvas, 0, 0);
                          saveCxt.globalAlpha=0.5;
                          saveCxt.drawImage(t.pageCanvas, 0, 0);
      
                          t.removeNode(t.pageCanvas);
                          t.removeNode(t.canvas);
                          t.removeNode(t.drawTool);
      
                          //輸出圖片
                          var imgData = saveCanvas.toDataURL("image/png");
                          if(t.callback){
                              callback(imgData);
                          } else {
                              var w=window.open('about:blank','image from canvas');
                              w.document.write("<img src='"+imgData+"' alt='from canvas'/>");
                          }
                      };
                      /*鼠標按下事件,記錄鼠標位置,并繪制,解鎖lock,打開mousemove事件*/
                      this.canvas['on'+t.StartEvent]=function(e){
                          var touch=t.touch ? e.touches[0] : e;
                          var scrollTop = window.pageYOffset|| document.documentElement.scrollTop || document.body.scrollTop;
                          t.movePoint(touch.clientX - touch.target.offsetLeft,touch.clientY - touch.target.offsetTop + scrollTop);//記錄鼠標位置
                          t.lock=true;
                          t.drawTool.style.display = "none";
                      };
                      /*鼠標移動事件*/
                      this.canvas['on'+t.MoveEvent]=function(e){
                          var touch=t.touch ? e.touches[0] : e;
                          if(t.lock)//t.lock為true則執行
                          {
                              var _x=touch.clientX - touch.target.offsetLeft;//鼠標在畫布上的x坐標,以畫布左上角為起點
                              var scrollTop = window.pageYOffset|| document.documentElement.scrollTop || document.body.scrollTop;
                              var _y=touch.clientY - touch.target.offsetTop + scrollTop;//鼠標在畫布上的y坐標,以畫布左上角為起點
                              t.movePoint(_x,_y,true);//記錄鼠標位置
                              t.drawRectangle();
                          }
                      };
                      this.canvas['on'+t.EndEvent]=function(e)
                      {
                          /*重置數據*/
                          t.lock=false;
                          t.Rectangles.push([t.x[0], t.y[0], t.x[t.x.length -1] - t.x[0], t.y[t.y.length -1] - t.y[0]]);
                          t.x=[];
                          t.y=[];
                          t.clickDrag=[];
                          t.drawTool.style.display = "block";
                      };
                  },
                  movePoint:function(x,y,dragging){
                      /*將鼠標坐標添加到各自對應的數組里*/
                      this.x.push(x);
                      this.y.push(y);
                      this.clickDrag.push(y);
                  },
                  drawRectangle: function(){
                      var width = this.x[this.x.length-1] - this.x[0],
                          height = this.y[this.y.length-1] - this.y[0];
                      this.clear();
                      var i = this.Rectangles.length;
                      if(i){
                          for (i=i-1; i >= 0; i--) {
                              var rectangle = this.Rectangles[i],
                                  r_x = rectangle[0],
                                  r_y = rectangle[1],
                                  r_width = rectangle[2],
                                  r_height = rectangle[3];
                              this.cxt.strokeRect(r_x, r_y, r_width, r_height); // 只勾畫出矩形的外框
                              this.cxt.fillStyle = "#FFFFFF";
                              this.cxt.fillRect(r_x, r_y, r_width, r_height); // 畫出矩形并使用顏色填充矩形區域
                          };
                      }
                      this.cxt.strokeRect(this.x[0], this.y[0], width, height); // 只勾畫出矩形的外框
                      this.cxt.fillStyle = "#FFFFFF";
                      this.cxt.fillRect(this.x[0], this.y[0], width, height); // 畫出矩形并使用顏色填充矩形區域
                  },
                  clear:function(){
                      this.cxt.clearRect(0, 0, this.w, this.h);//清除畫布,左上角為起點
                  },
                  removeNode: function(node){
                      node.parentNode.removeChild(node);
                  }
              };
              paint.init();
          }
      
          return {
              load: load
          }
      })();

      調用

        關于如何調用可參考這里:http://afeedback.duapp.com/

      局限

        由于html2canvas有跨域限制,所以如果頁面用了不同域下的圖片(如本文)就不能正常顯示。

        另外,由于html2canvas是根據HTML代碼重新渲染成canvas,而有些css無法識別,會造成頁面跟canvas上的不完全一致。

      改進空間和后續計劃

        目前在不支持canvas的瀏覽器下沒有任何效果,這個可改進為傳統方式。

        html2canvas的庫比較大,后續會改進為當用戶點擊反饋鏈接時進行異步加載。

        當然,大家在體驗的過程中如果有什么意見和建議非常歡迎提出,一起完善。

      posted @ 2013-05-09 19:22  artwl  閱讀(2665)  評論(4)    收藏  舉報

      個人簡介

      var ME = {
      	"name": "土豆/Artwl",
      	"job": "coding",
      	"languages": [
      		"JS", "HTML",
                      "CSS", "jQuery"
      		"MVC",".NET",
      		"設計模式"
      	],
      	"hobby": [
      		"閱讀", "旅游",
      		"音樂", "電影"
      	]
      }
      
      TOP
      主站蜘蛛池模板: 久久亚洲人成网站| 欧美午夜成人片在线观看| 人妻少妇精品系列一区二区| 成人3D动漫一区二区三区| 无码无需播放器av网站| 自拍日韩亚洲一区在线| 久久久av男人的天堂| 国产对白老熟女正在播放| 精品国产成人一区二区| 国产蜜臀一区二区在线播放| 国产精品免费中文字幕| 老熟妇乱子交视频一区| 亚洲av二区国产精品| 免费av网站| 精品国产成人国产在线视| 日韩乱码视频一区二区三区| 国产精品无码成人午夜电影 | 亚洲午夜香蕉久久精品| 亚洲av成人一区二区| 日本视频精品一区二区| 国产微拍一区二区三区四区| 欧美大胆老熟妇乱子伦视频| 亚洲欧美综合精品成| 伊人久久精品一区二区三区| 夜夜添狠狠添高潮出水| 亚洲午夜精品国产电影在线观看| 亚洲精品国产美女久久久| 67194熟妇人妻欧美日韩| 日韩av在线一卡二卡三卡 | 日韩精品卡1卡2日韩在线| 国产色无码精品视频免费| 高清破外女出血AV毛片| 久久夜色精品国产噜噜亚洲sv| 国产香蕉九九久久精品免费| 国产一级小视频| 久久av无码精品人妻系列试探| 翘臀少妇被扒开屁股日出水爆乳| 国产精品视频全国免费观看| 欧美日韩性高爱潮视频| 精品亚洲精品日韩精品| 欧美巨大巨粗黑人性aaaaaa|