从零打造在线版H5页面生成器
想必你一定使用過易企秀或其它微場景生成工具制作過炫酷的h5頁面,除了感嘆其神奇之處有沒有想過其實現方式呢?
從設計者的角度來看待問題,會有不一樣的收獲,本文將從零開始,使用node技術來設計實現一款精簡版的易企秀
Github: 傳送門
演示地址:傳送門
目錄
一、實例實現
自動化/可視化工具的實現,無不是大量重復實例的一種模板化,微場景生成工具也不例外,所以首先需要探討具體的一個微場景是怎么實現的
來看下面這個實例:
要實現這樣的場景,我們首先得把任務分解下:
1) 布局:整個場景可以分為很多屏(頁),每一屏上有動畫元素(文字/圖片)
<!-- --------------html---------- --><div class="page-box" id="page1"><div class="item page1-item1">...</div><div class="item page1-item2">...</div><div class="pre-item">...</div></div><div class="page-box" id="page2"><div class="item page2-item1" data-cls="bounceIn1000" data-ts="0">...</div><div class="item page2-item2" data-cls="bounceIn1000" data-ts="1000">...</div><div class="pre-item">...</div></div><!-- --------------css---------- -->// 每一屏(page-box)都是absolute布局,便于為每屏增加入場出場動畫(減少重繪重排)// 每一屏寬高皆為100%,默認隱藏,入場增加入場動畫,并設置為可見.page-box {position: absolute;top: 0;z-index: 1;width: 100%;height: 100%;visibility: hidden;background: no-repeat center center #FFFFFF;background-size: 100% 100%;}.page-box.show {visibility: visible;}// 屏內動畫項目,也都采用abasolute布局,just因為,是動畫元素.item {position: absolute;background-repeat: no-repeat;opacity: 0;text-align: center;}2) 屏間切換:事件觸發,過渡動畫
/*** 下滑手勢,頁面上翻* 上一屏(prev)增加入場動畫slideZoom_tInt,本屏增加離場動畫slideZoom_tOut*/pre: function() {var $el = $(".page-box.show");var $prev = $el.prev(".page-box")[0] ? $el.prev() : $(".page-box").last();$prev.addClass("show").show().css({"-webkit-animation":"slideZoom_tInt 0.5s linear","animation":"slideZoom_tInt 0.5s linear" });$el.css({"-webkit-animation":"slideZoom_tOut 0.5s linear","animation":"slideZoom_tOut 0.5s linear"});setTimeout(function(){$el.removeClass("show");...},500);}/*** 滑動事件監聽*///控制滑動//不禁止默認事件 他丫的不能滑document.addEventListener('touchmove', function(event) {event.preventDefault();}, false);$(document).on('swipeUp', function() {slider.next();}).on('swipeDown', function() {//手勢下滑,向上翻頁slider.pre();});3) 屏內項目控制(文字和圖片):引入動畫庫animate.css來設置屏內項目的動畫效果(所以說是精簡版易企秀)
/*** 動畫效果控制,動畫效果播放、時間間隔*///動畫一個個播放,遞歸調用var i = 0;function startShow(callback) {if(i === itemLength){callback && callback();return ;}var item = items.eq(i);var cls = item.attr('data-cls');//動畫類var ts = item.attr('data-ts');//下一個動畫開始間隔時間item.addClass(cls);i ;setTimeout(function() {startShow(callback);},ts);};//播放某一屏的動畫function showItem(id, callback) {var self = this;i = 0;items = $('#' id " .item");itemLength = items.length;if(!callback) {callback = function() {self.showPreItem(id);}}startShow(callback);},4) 頁面加載進度控制:阻塞頁面加載進度的無非圖片,枚舉頁面使用到的所有圖片(可以使用程序遍歷目錄),判斷Image對象的complete狀態或者監聽onload事件來判斷圖片是否加載完成,篇幅原因,代碼就不貼出來了
二、實例模板化與渲染
所謂模板化,無非是在重復實例中提取共性的東西定義數據模型,并且使用模板標簽來描述,渲染的過程中用數據填充模板占位符
在此選用了nunjucks作為模板引擎
我們先來分析下,微場景頁面的組成部分:
于是數據模型可以定義為:
//頁面數據pages: [{burl: String, //背景圖片inAnimate: String,outAnimate: String,bgColor: String,items: [ //頁面項目{px: String, //位置x 必選py: String, //位置y 必選width: String, //寬度 必選height: String, //高度 必選transparent: String,//透明度 可選animateClass: String,//動畫 可選animateDuration: String, //動畫持續時間,默認2000nextAnimateTime: String, //下一個item動畫開始的時間間隔zIndex: String, //可選imgUrl: String,// 圖片路徑 //可選text: String, //文本textStyle: {'color': String,'font-size': String}}...]},{...}...]根據數據模型來編寫模板
<!-- ---------html模板片段--------- -->//遍歷pages生成每一屏的div//遍歷page的items生成動畫項目div{% set i = 0 %}{% for page in pages %}{% set i = i 1 %}{% set j = 0 %}<div class="page-box" id="page{{i}}">{% for item in page.items %}{% set j = j 1 %}<div class="item page{{i}}-item{{j}}" data-cls="{{ item.animateClass }}{{item.animateDuration}}" {% if item.nextAnimateTime %} data-ts="{{ item.nextAnimateTime }}" {% else %} data-ts="500" {% endif %} >{% if item.text %}{{ item.text }}{% endif %}{% if item.imgUrl %}{% endif %}</div>{% endfor %}<div class="pre-item"><div class="pre-wrap"><div class="pre-box1"><div class="pre1"></div></div><div class="pre-box2"><div class="pre2"></div></div></div></div></div> {% endfor %}<!-- ---------css模板片段--------- -->/************* item style ***********************/{% set i = 0 %}{% for page in pages %}{% set i = i 1 %}{% set j = 0 %}#page{{i}} {{% if page.burl %}background-image: url({{page.burl}});{% endif %}background-color: {{page.bgColor}};}{% for item in page.items %}{% set j = j 1 %}.page{{i}}-item{{j}} {width: rem({{item.width}});height: rem({{item.height}});left: rem({{item.px}});top: rem({{item.py}});{% for key, value in item.textStyle %}{{key}}: {{value}};{% endfor %}}{% endfor %}{% endfor %}//這里要重點說明的,數據模型中的所有item對應的,動畫類和持續時長作為key值//去重之后,構造animateClasses對象,遍歷該對象,生成相應的動畫類//例如動畫類bounceIn1000:就表示動畫庫中的bounceIn,并且持續時長1000毫秒/**************** animate class **************************/{% for cname, cvalue in animateClasses %}.{{cname}} {-webkit-animation: {{cvalue.ac}} {{cvalue.ad}}s ease 1 both;-webkit-animation-play-state: initial; animation: {{cvalue.ac}} {{cvalue.ad}}s ease 1 both;animation-play-state: initial;opacity: {% if cvalue.isOut %}0 {% else %} 1 {% endif %};}{% endfor %}渲染過程:
1) 復制用到的圖片
2) rem預處理
3) 根據數據渲染模板
三、前端可視化操作
在上一步模板化之后,我們已經可以根據數據和模板生成場景實例,那么前端可視化操作要做什么就比較清晰了,前端可視化操作的目的在于根據數據模型構造數據實例,前端的可視化操作應該包括設置每一屏的背景色/背景圖片,并且可以增加或刪除一頁,在每一屏中可以增加文本或者圖片項目,并且設置對應的屬性
編輯屏 編輯動畫項目在此采用了以上兩圖的設計風格:
同樣的,我們要將任務分解:
這些個步驟每一步要寫的話,篇幅都可以長到獨立成文,例如,另一篇文章:div拖拽縮放jquery插件編寫——帶8個控制點已經詳細說過,本文就不再拓展,如果有需要,可以私信我,有必要再整理
通過前端可視化的操作,構造數據模型實例,傳入后臺,后臺再通過上一步的模板進行渲染,那么整一個核心功能就走通了~~~
其它的入庫保存,展示,預覽功能,則是需要慢慢豐富的過程
先把核心骨架搭建完畢,再去豐富皮肉,是一個軟件從無到有的重要心法
四、總結
本文重在說明設計步驟和實現思路,省去了很多實現細節,并非面面俱到,并且也不方便公布所有源代碼,更細致的討論,可以私信我,定盡力解答。
本文方法論:
1)任務分解
2)實例模板化
3)核心骨架搭建、再豐富皮肉功能
更多專業前端知識,請上 【猿2048】www.mk2048.com
總結
以上是生活随笔為你收集整理的从零打造在线版H5页面生成器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端通过spark-md5.js计算本地
- 下一篇: 你不懂js系列学习笔记-异步与性能- 0