以前曾用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.上面的操作就是:在一張預先寫好文案的圖片上寫上動態輸入的名字,再配上自定義文案和二維碼圖片。
源碼地址: