(1/2)Canvas的交互&存爲圖片-基本篇

前言

公司的產品同窗看到朋友圈瘋傳的這張圖後。一拍腦殼,決定作個H5版本的來推廣一波。css

clipboard.png

需求以下:html

  1. 文字變成能夠點擊的,並且還要可以變色(閃瞎有木有)canvas

  2. 中間的姓名換成用戶的微信頭像api

  3. 點擊button後,將canvas的操做結果保存成圖片,來現微信長按保存到本地的功能。微信

難點總結:ide

  1. 頁面元素canvas基本的api畫到畫布上(要解決顯示自適應的問題);函數

  2. 如何實現點擊canvas,識別點擊文字的對應位置;spa

  3. 圖片保存的api;設計

canvas的基本繪製和自適應

代碼部分請忽略css樣式調試

canvas初始化

html

<canvas id="test"></canvas>
var canvas = document.getElementById('test'),
        ctx = canvas.getContext('2d');

js | canvas自適應方案

  1. 等比公式:設計圖元素尺寸/設計圖寬度 = 顯示圖元素尺寸/移動設備像素寬度;

  2. 推導: 顯示圖元素尺寸 = 設計圖元素尺寸*(移動設備像素寬度/設計圖寬度);

  3. 定義: rate= 移動設備像素寬度/設計圖寬度;

var width = document.documentElement.clientWidth,
    //自適應比率計算
    rate = (document.documentElement.clientWidth/ 960).toFixed(2),
    height = rate*1540,

js | canvas面向對象的元素繪製方法

  1. 經由高人指點,將canvas內部的元素記錄成一個個記錄了顏色大小座標、等屬性的對象。

  2. 這樣能夠將元素分爲幾類:簡單幾何圖形(圓,矩形等)、文字、圖片這幾類;

  3. 同類元素能夠用相同的方法繪製(請務必get此技能

canvas繪製文字

baseColor = '#000';

//canvas文字對象
 var textArr = [
 {num:0, has_click: 0, worth:750000, x : 60, y : 50+60, fontSize : 25, text : '英雄聯盟', color: baseColor,isEn : true },
 {num:1, has_click: 0, worth:750000, x : 310/3, y : 50+650/3, fontSize : 20, text : '守望先鋒', color: baseColor }
 ];

//轉爲自適應文字對象
var getTextScope = function(textArr){
  var arr = [];
  textArr.forEach(function(item){
    item.x = item.x * rate;
    item.y = item.y * rate;
    item.fontSize = item.fontSize * rate;
    //計算文字對象在canvas中的觸摸範圍
    item.r = item.x + (item.isEn ? item.text.length / 2 : item.text.length) * item.fontSize;
    item.b = item.y + item.fontSize;
    arr.push(item);
  });
return arr;
};

var newArr = getTextScope(textArr);


//繪製文字方法
var fillTextArr = function(el, textArr){
  textArr.forEach(function(item){
    el.font = item.fontSize + 'px Microsoft Yahei Helvetica Neue  Helvetica, STHeiTi, Arial, sans-serif ';
    el.textAlign= 'left';
    el.textBaseline = 'top';
    el.fillStyle = item.color;
    el.fillText(item.text, item.x, item.y);
    //繪製文字的觸摸識別範圍(調試用)
    el.beginPath();
    el.rect(item.x, item.y, item.r - item.x, item.b - item.y);
    el.stroke();
  });
};

fillTextArr(canvas,newArr)

canvas繪製圖片

html
頁面隱藏元素加載canvas所須要用到的img元素,也能夠新建img對象來處理。

<footer class="footer">
  <div class="img-source hide">
    <img src="/images/avater.jpg" alt="" id="avater"/>
    <img src="/images/avater-bg_05.png" alt="" id="avaterBg"/>
    <img src="/images/3.jpg" alt="" id="img3"/>
    <img src="/images/21060715code_img.jpg" alt="" id="code"/>
    <img src="/images/canvas_tag.png" alt="" id="scan"/>
  </div>
</footer>

js

繪製圖片的函數

var drawImages = function(el, arr){
  arr.forEach(function(item){
   el.drawImage(document.getElementById(item.id), item.x * rate, item.y * rate, item.w * rate, item.h * rate);
  });
};

var avatar = [
        {id : 'avater', x : 106, y : 50+95, w : 340/3, h : 340/3},
        {id : 'avater', x : 106, y : 50+95, w : 340/3, h : 340/3},
        {id : 'avaterBg', x : 100, y : 50+90, w : 375/3, h : 366/3}
    ];

drawImages(ctx, avatar);

canvas元素點擊交互

js
item.r、item.b、item.x、item.y在上文var newArr = getTextScope(textArr);中已經獲取;

//判斷點擊的點是否在範圍內

var isInText = function(item, p){
        if(p.x > item.x && p.x < item.r && p.y > item.y && p.y < item.b) {
            return true;
        }else {
            return false;
        }
    };
//獲取元素所在區域範圍的函數

var getEventPosition =  function(ev){
        var x, y;
        if (ev.layerX || ev.layerX == 0) {
            x = ev.layerX;
            y = ev.layerY;
        } else if (ev.offsetX || ev.offsetX == 0) { // Opera
            x = ev.offsetX;
            y = ev.offsetY;
        }
        return {x: x, y: y};
    };

交互事件實例

canvas.addEventListener('click', function(e){
    //獲取點擊座標
    var p = getEventPosition(e);
    
    //遍歷歐判斷是否點擊到某元素
    newArr.forEach(function(item, i){
            //判斷是否點擊到元素進行分別操做
            if(isInText(item, p)){
                //點擊到某元素的操做
            }
        });
}, false);

如今介紹了canvas繪製的基礎操做,下一節就會寫到項目的實踐部分。

相關文章
相關標籤/搜索