以前曾用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