前言
最近一段時間由于項目需要接觸到了ionic3,發現真是一個利器啊!ionic項目提供了一套豐富的圖標庫,在ionic3中也進行了升級。
公司的一個項目中由于要用到一個瀑布流的特效,找了半天竟然沒有找到相關的資源,沒有辦法,只能迎著頭皮上了~
話不多說,先上圖
相信看過圖片的同學都明白什么意思了吧。對,就是瀑布流!
但是今天我們的瀑布流可不是一般的瀑布流。讓我們接著看:
自動排版
我們的要求是做那種隨機凌亂的感覺,所以我們需要做一種機制,來將圖片選擇最優的一種排列方式來展示到頁面上,也就是保證圖片與相鄰圖片的比例是最合適的然后在實現排列.
angular4
相信這個效果如果在平常的jq插件中似乎也不難實現,確實,網上也能搜到一些jq的插件。但是我們的技術棧是angular4呀~
在ng中我們的DOM操作基本都是放在指令中的,相信用過angularjs1.x的同學并不陌生了吧~,在angular4中也是一樣。
好了,讓我們貼代碼~
創建指令
我們假設你已經在你的ionic中建立好了相關的組件,并且已經擁有的圖片數據,如果沒有相關基礎的同學建議大家先去看看ionic3 與 angular4的入門。
這是我的一個組件html的頁面,也許眼尖的同學已經發現了我們的指令 [imagr-sort]="item",對的,我們的指令是需要你當前的圖片的angular數據的。
創建一個指令ts
ionic g directive image-sort
執行建立我們的指令。
創建完了我們的自定義指令就是這個樣子,空空如也啊~
編寫我們的邏輯
1.1接收并且注入一些東西:
看圖!
既然我們在模板中有輸入([[imagr-sort]="item"]);
那么我們也當然應該在指令中接收到輸入的數據;如截圖中紅色箭頭所示,我將輸入的數據保存了起來->sourceArr;
然后我們在angular4中如果要獲取到dom宿主的一些屬性了,元素了等等就要用到ElementRef,Renderer2是angular4中的一個類似渲染器的東西吧,這個具體的我還沒有搞懂,大家可以多看看這塊的資料,我主要是在這個指令中用于更改Dom的一些結構。
關于我們的imgLength ,我待會再說
1.2實際點!圖片是從異步加載過來的!
我們首先思考這樣一個問題:
我們的指令是在angular數據渲染的時候就開始執行的,這個是基本大家都懂。
but!我們的圖片可都是異步加載的呢~,所以自然而然我們要有一個圖片加載的過程:
嗯,相信各位早就想到了---->image.onload
,不錯,是它~
也是時候說下之前的imgLength了,這個變量來記錄記載完成的圖片的數量,用來辨別是否當前圖片都已經加載完畢了,為我們后續的動作做依據。
image.onerror
,這個相信大家也看明白了吧,這個是圖片加載失敗的一個函數,我在里面做的操作是將加載失敗的圖片從原始的DOM中,angular的數據剔除。
這里面就用到了我們angular的渲染器this.render2();
相關功能方法大家可以去源碼里面看一下,基本上所有常用的Dom操作都有實現。
for循環呢是因為我們的圖片數據是多條的,所以我們要等待每一張圖片都順利的加載完成。
ps:注意在onerror與onload的函數中使用this要在imgOnlod中使用變量引用let _self = this;
圖片加載完成開始我們的改造工程
1.3將我們的適口按照網格劃分
imageStartStort()!
上圖
大家看1圖紅圈內,我是自己劃分出五個橫向網格標準,便于我們待會將圖片比例做對比。
1.4將我們的圖片定義網格占用
我們創建了一個數組allImageArr=[];用于保存當前處理過的所有圖片的數據。
還記的我們之前獲得的angular的數據吧,我們通過循環它來將圖片劃分網格占用。
我們的循環中都做了些什么?
1.圖片的寬高,并且求出每一張圖片的比例。
2.將獲得的圖片比列與我們自己定義的網格比例進行區間劃分。
3.按照我們劃分的網格來計算出占有網格的圖片的新的寬度,所占網格數儲存并且記錄保存到我們的自定義的allImageArr中,并且在原有的angular數據中添加gridding數字那個記錄相應的網格數。
執行this.pictureColumnSort
方法;
我們的圖片已經劃分完成了,接下來,我們來激情的一刻~
1.5圖片排列,跟據網格派選最合適的鄰居~
pictureColumnSort()!
上圖
這一個過程其實也沒啥好說的,主要就是循環,查看每個圖片的網格數,將最合適的進行相鄰排序(執行下一步:goExchange函數),最后匹配不上的單獨做一個5分網格戰術出來.
格式可以是多種:
3+2,1+4,1+1+3,1+3+1,2+3.。。。
怎么高興怎么來~
沒啥好說的就是循環篩選,大家看看圖就好。
1.6無序變有序,除了交換應該沒有更好的選擇了吧
goExchange()! 上圖
看看1.5中的代碼,我們呢是在每次匹配到了合適的圖片之后執行這個函數,因為我們需要把匹配到的圖片換位置?。?br/>這個函數中接收到的repeatI與repeatA就是1.5中的雙重循環的索引,這個索引決定了我們換圖片的位置。
代碼所示的原理就是將匹配到的圖片換到我們當前圖片的后面,將原來后面的圖片補到換過來圖片的位置,有點繞可能是我的比哦打能力不好,哈哈。
沒啥好說的這個函數,就是換位置。
1.7取長補短,完工!
setHeight()!上圖
再次循環(代碼應該還有不少改進的地步,循環用的不少~);
這個地步已經我們呢的布局頁面完成了,但是我們的圖片的尺寸實際上是不規則的,不忍直視,
所以我們在這個函數中將差異抹平,取長補短。
實際上我們的圖片肯定會有一點拉伸,所以我們也是取了平衡的一個中間點,來進行適當的拉伸。
這個函數肯定其實還可以做一些適當的限制來精細化圖片的尺寸調整。至此我們也算是寫完了整個指令邏輯。
完工! ioinc serve
至于中間的調用的過程有一點我要說明:
setTimeout(() => { _self.setHeight(angularImageList, ele); });
整個調用我也是晚班無奈的情況下才使用的,如果不加整個調用在setHeight函數中設置的angular,數據會莫名其妙的出現圖片位置更換錯誤,至今誤解,如果大佬們能看到整個有好的解決方法也分享一下。
上面是我整理給大家的,希望今后會對大家有幫助。
相關文章:
vue中如何實現methods方法之間調用
vux如何實現上拉刷新功能
jQuery如何實現圖片輪播
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com