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

之前曾用Canvas合成、裁剪、圖片等《用H5中的Canvas等技術製做海報》。此次用Canvas來畫文字。css

下圖中「老王考到駕照後」這幾個字是畫在Canvas上的,與在PS中打入的字很是接近,毫無違和感。html

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

 

1、項目總覽

  

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

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

下圖是工程文件總覽:git

 

2、構建工具

目前開發採用的是自動化構建工具「gulp」,「config.js」和「gulpfile.js」都是配置文件。github

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

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

網上有個很時髦的工具「webpack」,在構建工具也引用了,目前就僅僅用來合併JS。gulp

 

3、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;

具體能夠參考《移動開發屏幕適配分析

 

3、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中的動畫效果記錄

 

4、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

相關文章
相關標籤/搜索