微信小程序實踐_3點擊版面圖片獲取新聞連接

前言

上回講到將人民日報的首版圖片顯示出來,本次將實現點擊新聞對應區域,閱讀該新聞html

熱區

熱區就是在網頁上進行了連接的一個區域算法

人民日報電子版的版面圖片上,點擊想要看的新聞,右側就會出現該新聞的詳細報道,咱們點擊的地方就是「熱區」,在網頁中可經過<map></map>標籤實現此項功能,可是小程序中未提供相似功能的組件,要腫麼辦?小程序

俗話說:只要思想不滑坡,辦法總比困難多this

雖然沒有相似組件,但是咱們只要知道區域的範圍就好啦,點擊版面圖片的某塊區域時,判斷觸點是否在該區域內就好了。那麼如何判斷?url

代碼實現

如上所述,版面圖片的熱區信息包含在map標籤內,正則匹配走起~
修改paper.js的onLoad方法爲:code

onLoad: function (options) {
    var self = this;
    //獲取系統寬高,並計算寬高比
    ..........
    wx.request({
      url: url,
      success: function (res) {
        var html = res.data;
        //正則式-匹配版面圖片
        var pagePicImgReg = /<img[^>]+src=(.*)\s+border=0\s+usemap=#pagepicmap[^>]*>/i;
        //正則式-匹配熱區信息
        var pagePicMapReg = /<map[^>]+name=pagepicmap[^>]*>.*<\/map>/i;
        //版面圖片匹配結果
        var pagePicImgMatch = html.match(pagePicImgReg);
        //熱區信息匹配結果
        var pagePicMapMatch = html.match(pagePicMapReg);
        //中間變量,存放map標籤內容
        var mapHtml = "";
        //中間變量,存放img的src內容
        var imgSrc = "";
        pagePicMapMatch && (mapHtml = pagePicMapMatch[0]);
        pagePicImgMatch && (imgSrc = pagePicImgMatch[1].replace('../../..', imgUrl));
        //正則式-匹配map標籤裏area信息,coords是區域定點信息,href是該區域所連接到的文章
        var areaReg = /<area\s+coords="(.*?)"[^>]+href="(.*?)"[^>]*>/ig;
        var area;
        //存放該版面圖片的area內容
        var areaArray = []
        while ((area = areaReg.exec(mapHtml)) != null) {
          areaArray.push({ "coords": area[1].split(",").map(self.computeCoords), "href": area[2] });//href爲當前版面每條文章的連接
        }
        //console.log("areaArray ", areaArray);
        self.setData({
          paperInfo: [{ "imgSrc": imgSrc, "areaArray": areaArray}]
        });
      }
    })
  },

paper.js添加computeCoords方法: 因爲響應的coords座標信息對應的版面圖片默認爲400*571px的,因此不一樣設備的coords要做等比例縮放xml

//計算適合該設備的coords大小
  computeCoords: function (coord, index) {
    var self = this;
    var tmpCoord = parseInt(coord);
    if (index % 2 == 1) {//表明x座標
      tmpCoord = Math.ceil(tmpCoord * (400 / self.data.windowWidth));
    }
    if (index % 2 == 0) {//表明y座標
      tmpCoord = Math.ceil(tmpCoord * (571 / self.data.windowHeight));
    }
    return tmpCoord;
  },

知道了版面圖片的熱區狀況,如何判斷用戶點擊的是哪篇文章呢?
ray-crossing算法
1.簡單來講,該算法能夠判斷一點是否在給定的某個不規則封閉區域內。(幸運的是版面圖片上畫的熱區是簡單的封閉圖形,且大可能是矩形)
該算法的大體思路是:過被判斷的點(觸點)做一條向右的射線,若射線與區域的邊的交點爲奇數,則認爲該點在此區域內,若爲偶數,則未在該區域內
對於邊界點(區域頂點和邊上的點),對於本應用來講,用戶點到邊界的機率很小,是能夠忽略的
2.實現:在paper.js中添加如下方法htm

//point爲用戶觸點的座標,coords爲某個熱區頂點狀況
  pointInRegin: function (point, coords) {
    //coords中每兩個是一對座標
    var count = 0;//統計目標點向右畫射線與多邊形相交次數
    var x = point[0];//用戶觸點x位置
    var y = point[1];//用戶觸點y位置
    var i = 0, j = 0;//j表明i的下一個座標點

    //coords中肯定一條直線的兩點的座標
    var xi = 0;
    var yi = 0;
    var xj = 0;
    var yj = 0;
    for (i = 0, j = coords.length - 2; i < coords.length - 1; j = i, i = +2) {
      xi = coords[i];
      yi = coords[i + 1];
      xj = coords[j];
      yj = coords[j + 1];
      if (yi == yj) { continue; }//若是兩點水平,則跳過
      if (y < Math.min(yi, yj)||y > Math.max(yi, yj)) { continue; }//若是觸點低於該線段或高於該線段,則跳過
      if (x >= Math.max(xi, xj)) { continue; }//若是觸點在該線段的右邊,則跳過
      //該觸點與coords所肯定的區域有交叉,求該交叉點的x座標的值
      var intersection_x = (xj - xi) * (y - yi) / (yj - yi) + xi;
      if (x < intersection_x) { count++; }//若是交叉點在觸點的右邊,相交次數加1
    }
    if (count % 2 == 0) { return false; }//在多邊形外面或邊上
    if (count % 2 == 1) { return true; }//在多邊形裏面

  },

paper.js添加肯定觸點點擊的新聞連接方法:事件

/**
  * 肯定觸點的文章
  * 返回文章的href
  * pagenum表明版面號(從1開始編號)
  */
  getArticleHref: function (fingerx, fingery, pagenum) {
    var self = this;

    var currentPageAreas = self.data.paperInfo[pagenum - 1].areaArray;
    var aresLength = currentPageAreas.length;
    var i;
    var points = [];
    for (i = 0; i < aresLength; i++) {
      points = currentPageAreas[i].coords;
      if (self.pointInRegin([fingerx, fingery], points)) {
        console.log("找到href",currentPageAreas[i].href);
        return currentPageAreas[i].href;
      }else{console.log("未在當前coords內");}
    }
  },
  /**
  * 點擊跳轉到相關文章
  *記得在paper.wxml文件的img組件上綁定toArticle事件
  */
  toArticle: function (e) {
    var self = this;
    var fingerx = e.detail.x;//x,y表明距離其父文檔左上角的距離
    var fingery = e.detail.y; 
  
    //獲取觸點所在的文章href,目前只有初版因此pagenum爲1
    var href = self.getArticleHref(fingerx, fingery, pagenum);
    if (href) {
      console.log("獲取的文章連接爲 ",href);
    }else{
      console.log("未找到文章連接");
    }
  },

編譯運行

按照上篇文章的方法,編譯運行程序,點擊版面圖片上的任意一條新聞,查看控制檯是否輸出該文章的href圖片

相關文章
相關標籤/搜索