H5項目開發分享——用Canvas合成文字


以前曾用Canvas合成、裁剪、圖片等《用H5中的Canvas等技術制作海報》。這次用Canvas來畫文字。

下圖中“老王考到駕照后”這幾個字是畫在Canvas上的,與在PS中打入的字非常接近,毫無違和感。

前面一段時間也在研讀JavaScript設計模式相關的知識,這次正好小小的實踐一下,但對設計模式的理解還不是很深。

 

一、項目總覽

  

總共就兩張頁面,第一張是選擇性別,輸入名字,第二張頁面是合成文字,並展示出來。

雖然頁面很簡單,但在做這個項目的時候,涉及到了很多方面,自定義字體、CSS3動畫、Canvas、CSS3選擇器、本地緩存、構建工具等。

下圖是工程文件總覽:

 

二、構建工具

目前開發采用的是自動化構建工具“gulp”,“config.js”和“gulpfile.js”都是配置文件。

關於這個工具,以前曾寫過介紹《前端自動化構建工具gulp記錄

有了構建工具后,就能方便的壓縮圖片、壓縮CSS、壓縮JS、編譯Sass文件、編譯Jade文件、搭建本地服務器等。

網上有個很時髦的工具“webpack”,在構建工具也引用了,目前就僅僅用來合並JS。

 

三、HTML

1)Jade

不同於以前編寫html,這里我使用了Jade,一個模版引擎。

通過使用Jade,可以將html中通用的抽象出來,還可以使用循環、條件、繼承等特性,減少代碼,代碼也更可讀。

Jade代碼如下,下面是一個模版layout中的代碼,其他頁面可以繼承他,這樣很多通用的代碼就不用再寫了。

 

2)flexible.js

這段腳本是用來解決H5頁面終端適配的。具體的使用方法可以參考這里

在腳本中會做兩個操作,

一個是放大,如果是IOS系統,那么會根據當前的設備像素比來做頁面的放大操作,如果是Android就還是默認的。

例如Iphone6中設備像素比是2,那么就設置為0.5,也就是1/2。

<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

另外一個就是計算rem的基准值,獲取到“document.documentElement”的寬度,再除以10,作為一個基准值。

var width = docEl.getBoundingClientRect().width;
var rem = width / 10;

具體可以參考《移動開發屏幕適配分析

 

三、CSS

1)Sass

目前開發CSS,會使用Sass預編譯工具,它允許你使用變量、嵌套規則、 mixins、導入等眾多功能,並且完全兼容 CSS 語法。

Sass 有助於保持大型樣式表結構良好,同時也讓你能夠快速開始小型項目。

通過Sass,可以將CSS模塊化、代碼更清晰、並且能將通用的代碼抽象出來復用。

下面的代碼是引用了自己寫的一個庫“PrimusUI”中的部分模塊:

移動端開發,由於屏幕尺寸很多,所以用彈性布局,會比較方便,專門封裝了一段操作彈性布局各個屬性的代碼“grid”。

傳統的浮動布局,很容易出現各種問題,尤其是字體間的對齊,非常頭疼,具體可以參考《CSS3伸縮盒Flexible Box

 

2)自定義字體圖標

上圖中的“icon”,封裝了自定義字體的CSS代碼。

自定義字體圖標相對於圖片,有可控制大小、顏色、對齊更簡單等優勢。

並且現在移動端都能支持,適當的使用自定義字體可以提升頁面性能。

國外有“Font Awesome”,國內有“iconfont”,iconfont中有豐富的圖標,基本能滿足你日常的開發需求,如果沒有還可以自己制作矢量圖,上傳到網上自動轉換。

我將用到的圖標放到了一個項目中,以便重復使用。

 

3)CSS3

CSS3擴展了很多屬性,下圖中的選中的勾就是通過偽類實現的。

input[type=radio]:checked {
      background: url(../img/checked.png) no-repeat 32px 5px;
      background-size: 40px 40px;
}

還經常會用到偽對象選擇符“::after”或“::before”,有了這兩個就相當於多了兩個標簽。

上圖中的長按保存這張圖片就設置在偽對象中。

&::after {
    position: absolute;
    content: "";
    background: url(../img/prompt.png) no-repeat;
    width: 350px;
    top: 40px;
    left: 50%;
    margin-left: -175px;
    height: 70px;
    background-size: 100% 100%;
}

還會做一些小動畫,脈沖,上下位移,漸變等,更多動畫屬性可以參考《CSS3中的動畫效果記錄

 

四、JavaScript

1)通用模塊

JS與CSS一樣,也整理了一些通用的模塊,在實際項目中,直接引用即可。

上面的模塊一個封裝了緩存,一個封裝了平時需要操作DOM的相關方法。

DOM中有個方法是用於圖片預加載的,主要是為了圖片阻塞頁面加載CSS、JS、HTML資源,提升頁面性能,關於預加載可以參考《圖片預加載與懶加載

/**
 * 圖片預加載
 */
$("img[data-src]").each(function() {
    var $this = $(this);
    var src = $this.data('src');
    dom.preImage(src, function() {
        $this.attr('src', src);
    });
});

 

2)命令模式封裝的Canvas

命令模式是將請求與實現解耦並封裝成獨立對象,根據不同參數,執行不同功能。

這里將canvas畫文本與合成圖片封裝了起來:

var CanvasCommand = (function() {
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    canvas.width = 520;
    canvas.height = 500;

    var $compose = $('#compose');

    var Action = {
        fillText: function(font) {
            var canvas2 = document.createElement('canvas');
            var sizes = [], width=0;
            $.each(font, function(key, value) {
                sizes.push(value['size']);
                width += value['size'] * value['txt'].length + 5;
            });
            canvas2.width = width - 5;//畫布寬度
            var max = Math.max.apply(this, sizes);

            canvas2.height = max * 1.5;//畫布高度
            var ctx2 = canvas2.getContext('2d');
            ctx2.fillStyle = "#ffed03";
            ctx2.fillRect(0, 0, canvas2.width, canvas2.height);
            var x = 0;
            $.each(font, function(key, value) {
                ctx2.font = (value['bold'] || '')+" "+value['size']+"px serif";
                ctx2.fillStyle = "black";
                ctx2.fillText(value['txt'], x, max);
                x += value['size'] * value['txt'].length + 5;
            });

            return canvas2;
        },
        fillImage: function(num, txts) {
            var qrcode = new Image();
            qrcode.src = 'img/qrcode.png';
            qrcode.onload = function() {
                var image = new Image();
                image.src = 'img/story/'+num+'.png';
                image.onload = function() {
                    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
                    ctx.drawImage(qrcode, 20, 400, 80, 80);
                    $.each(txts, function(key, value) {
                        ctx.drawImage(value, value.left, value.top, value.width, value.height);
                    });
                    var base64 = canvas.toDataURL("image/jpeg", 0.6);
                    $compose.attr('src', base64);
                };
            };
        }
    };
    return {
        /**
         * 命令格式 command,params
         * @param param
         */
        execute: function(param) {
            return Action[param.command].apply(Action, param.params);//執行命令
        }
    }
})();

1.這里使用了canvas中的fillText來渲染文本,在渲染的時候還通過font設置了字體,fillStyle設置了顏色,MDN上有篇canvas的基礎教程

2.canvas中的drawImage就是用來嵌入圖片的,設置好起始坐標和圖片大小后就能將圖片展示在一起。

3.上面的操作就是:在一張預先寫好文案的圖片上寫上動態輸入的名字,再配上自定義文案和二維碼圖片。

  

 

源碼地址:

https://github.com/pwstrick/road


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM