ionic3实战教程之随机布局瀑布流的实现方法


Posted in Javascript onDecember 28, 2017

前言

最近一段时间由于项目需要接触到了ionic3,发现真是一个利器啊!ionic项目提供了一套丰富的图标库,在ionic3中也进行了升级。

公司的一个项目中由于要用到一个瀑布流的特效,找了半天竟然没有找到相关的资源,没有办法,只能迎着头皮上了~

话不多说,先上图

ionic3实战教程之随机布局瀑布流的实现方法

ionic3实战教程之随机布局瀑布流的实现方法

ionic3实战教程之随机布局瀑布流的实现方法

相信看过图片的同学都明白什么意思了吧。对,就是瀑布流!

但是今天我们的瀑布流可不是一般的瀑布流。让我们接着看:

自动排版

我们的要求是做那种随机凌乱的感觉,所以我们需要做一种机制,来将图片选择最优的一种排列方式来展示到页面上,也就是保证图片与相邻图片的比例是最合适的然后在实现排列.

angular4

相信这个效果如果在平常的jq插件中似乎也不难实现,确实,网上也能搜到一些jq的插件。但是我们的技术栈是angular4呀~

在ng中我们的DOM操作基本都是放在指令中的,相信用过angularjs1.x的同学并不陌生了吧~,在angular4中也是一样。

好了,让我们贴代码~

创建指令

我们假设你已经在你的ionic中建立好了相关的组件,并且已经拥有的图片数据,如果没有相关基础的同学建议大家先去看看ionic3 与 angular4的入门。

ionic3实战教程之随机布局瀑布流的实现方法

这是我的一个组件html的页面,也许眼尖的同学已经发现了我们的指令 [imagr-sort]="item",对的,我们的指令是需要你当前的图片的angular数据的。

创建一个指令ts

ionic g directive image-sort执行建立我们的指令。

ionic3实战教程之随机布局瀑布流的实现方法

创建完了我们的自定义指令就是这个样子,空空如也啊~

编写我们的逻辑

1.1接收并且注入一些东西:

看图!

ionic3实战教程之随机布局瀑布流的实现方法

既然我们在模板中有输入([[imagr-sort]="item"]);那么我们也当然应该在指令中接收到输入的数据;如截图中红色箭头所示,我将输入的数据保存了起来->sourceArr;

然后我们在angular4中如果要获取到dom宿主的一些属性了,元素了等等就要用到ElementRef,Renderer2是angular4中的一个类似渲染器的东西吧,这个具体的我还没有搞懂,大家可以多看看这块的资料,我主要是在这个指令中用于更改Dom的一些结构。

关于我们的imgLength ,我待会再说

1.2实际点!图片是从异步加载过来的!

我们首先思考这样一个问题:

我们的指令是在angular数据渲染的时候就开始执行的,这个是基本大家都懂。

but!我们的图片可都是异步加载的呢~,所以自然而然我们要有一个图片加载的过程:

ionic3实战教程之随机布局瀑布流的实现方法

嗯,相信各位早就想到了---->image.onload,不错,是它~

也是时候说下之前的imgLength了,这个变量来记录记载完成的图片的数量,用来辨别是否当前图片都已经加载完毕了,为我们后续的动作做依据。

image.onerror,这个相信大家也看明白了吧,这个是图片加载失败的一个函数,我在里面做的操作是将加载失败的图片从原始的DOM中,angular的数据剔除。

这里面就用到了我们angular的渲染器this.render2();

相关功能方法大家可以去源码里面看一下,基本上所有常用的Dom操作都有实现。

for循环呢是因为我们的图片数据是多条的,所以我们要等待每一张图片都顺利的加载完成。

ps:注意在onerror与onload的函数中使用this要在imgOnlod中使用变量引用let _self = this;

图片加载完成开始我们的改造工程

1.3将我们的适口按照网格划分

imageStartStort()!

上图

ionic3实战教程之随机布局瀑布流的实现方法

大家看1图红圈内,我是自己划分出五个横向网格标准,便于我们待会将图片比例做对比。

1.4将我们的图片定义网格占用

ionic3实战教程之随机布局瀑布流的实现方法

ionic3实战教程之随机布局瀑布流的实现方法

我们创建了一个数组allImageArr=[];用于保存当前处理过的所有图片的数据。

还记的我们之前获得的angular的数据吧,我们通过循环它来将图片划分网格占用。

我们的循环中都做了些什么?

      1.图片的宽高,并且求出每一张图片的比例。

      2.将获得的图片比列与我们自己定义的网格比例进行区间划分。

      3.按照我们划分的网格来计算出占有网格的图片的新的宽度,所占网格数储存并且记录保存到我们的自定义的allImageArr中,并且在原有的angular数据中添加gridding数字那个记录相应的网格数。

执行this.pictureColumnSort方法;

我们的图片已经划分完成了,接下来,我们来激情的一刻~

1.5图片排列,跟据网格派选最合适的邻居~

pictureColumnSort()!

上图

ionic3实战教程之随机布局瀑布流的实现方法

这一个过程其实也没啥好说的,主要就是循环,查看每个图片的网格数,将最合适的进行相邻排序(执行下一步:goExchange函数),最后匹配不上的单独做一个5分网格战术出来.

格式可以是多种:

3+2,1+4,1+1+3,1+3+1,2+3.。。。。。

怎么高兴怎么来~

没啥好说的就是循环筛选,大家看看图就好。

1.6无序变有序,除了交换应该没有更好的选择了吧

goExchange()! 上图

ionic3实战教程之随机布局瀑布流的实现方法

看看1.5中的代码,我们呢是在每次匹配到了合适的图片之后执行这个函数,因为我们需要把匹配到的图片换位置啊!
这个函数中接收到的repeatI与repeatA就是1.5中的双重循环的索引,这个索引决定了我们换图片的位置。

代码所示的原理就是将匹配到的图片换到我们当前图片的后面,将原来后面的图片补到换过来图片的位置,有点绕可能是我的比哦打能力不好,哈哈。

没啥好说的这个函数,就是换位置。

1.7取长补短,完工!

setHeight()!上图

ionic3实战教程之随机布局瀑布流的实现方法

再次循环(代码应该还有不少改进的地步,循环用的不少~);

这个地步已经我们呢的布局页面完成了,但是我们的图片的尺寸实际上是不规则的,不忍直视,
所以我们在这个函数中将差异抹平,取长补短。

实际上我们的图片肯定会有一点拉伸,所以我们也是取了平衡的一个中间点,来进行适当的拉伸。

这个函数肯定其实还可以做一些适当的限制来精细化图片的尺寸调整。至此我们也算是写完了整个指令逻辑。

完工! ioinc serve

ionic3实战教程之随机布局瀑布流的实现方法

至于中间的调用的过程有一点我要说明:

setTimeout(() => {
  _self.setHeight(angularImageList, ele);
  });

整个调用我也是晚班无奈的情况下才使用的,如果不加整个调用在setHeight函数中设置的angular,数据会莫名其妙的出现图片位置更换错误,至今误解,如果大佬们能看到整个有好的解决方法也分享一下。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Javascript模板技术
Apr 27 Javascript
JS编程小常识很有用
Nov 26 Javascript
Bootstrap Modal对话框如何在关闭时触发事件
Dec 02 Javascript
Vue数据驱动模拟实现1
Jan 11 Javascript
vue.js指令和组件详细介绍及实例
Apr 06 Javascript
深入理解Vue transition源码分析
Jul 30 Javascript
Angular.js中数组操作的方法教程
Jul 31 Javascript
JS返回顶部实例代码
Aug 09 Javascript
vue-cli启动本地服务局域网不能访问的原因分析
Jan 22 Javascript
微信小程序tab切换可滑动切换导航栏跟随滚动实现代码
Sep 04 Javascript
ES6中let、const的区别及变量的解构赋值操作方法实例分析
Oct 15 Javascript
JS中==、===你分清楚了吗
Mar 04 Javascript
JS实现带动画的回到顶部效果
Dec 28 #Javascript
JavaScript实现元素滚动条到达一定位置循环追加内容
Dec 28 #Javascript
在nginx上部署vue项目(history模式)的方法
Dec 28 #Javascript
js实现把时间戳转换为yyyy-MM-dd hh:mm 格式(es6语法)
Dec 28 #Javascript
vue获取dom元素注意事项
Dec 28 #Javascript
vue实现文章内容过长点击阅读全文功能的实例
Dec 28 #Javascript
webpack搭建vue 项目的步骤
Dec 27 #Javascript
You might like
phpcms模块开发之swfupload的使用介绍
2013/04/28 PHP
PHP操作MySQL中BLOB字段的方法示例【存储文本与图片】
2017/09/15 PHP
ThinkPHP框架实现的微信支付接口开发完整示例
2019/04/10 PHP
laravel框架使用极光推送消息操作示例
2020/02/15 PHP
javascript编程起步(第二课)
2007/02/27 Javascript
js选取多个或单个元素的实现代码(用class)
2012/08/22 Javascript
解决checkbox的attr(checked)一直为undefined问题
2014/06/16 Javascript
Javascript闭包用法实例分析
2015/01/23 Javascript
jquery调取json数据实现省市级联的方法
2015/01/29 Javascript
详解JavaScript对W3C DOM模版的支持情况
2015/06/16 Javascript
JavaScript每天定时更换皮肤样式的方法
2015/07/01 Javascript
浅谈Javascript数组的使用
2015/07/29 Javascript
js仿支付宝填写支付密码效果实现多方框输入密码
2016/03/09 Javascript
JS获取子窗口中返回的数据实现方法
2016/05/28 Javascript
使用bootstrap实现多窗口和拖动效果
2016/09/22 Javascript
jQuery视差滚动效果网页实现方法经验总结
2016/09/29 Javascript
Bootstrap CSS组件之输入框组
2016/12/17 Javascript
微信小程序scroll-view实现横向滚动和上拉加载示例
2017/03/06 Javascript
微信小程序视图template模板引用的实例详解
2017/09/20 Javascript
AngularJS实现的锚点楼层跳转功能示例
2018/01/02 Javascript
nodejs基础之多进程实例详解
2018/12/27 NodeJs
Vue Router 实现动态路由和常见问题及解决方法
2020/03/06 Javascript
JS如何实现封装列表右滑动删除收藏按钮
2020/07/23 Javascript
带你使用webpack快速构建web项目的方法
2020/11/12 Javascript
[02:04]2014DOTA2国际邀请赛 DK一个时代的落幕
2014/07/21 DOTA
[06:11]2014DOTA2国际邀请赛 专访团结一心的VG战队
2014/07/21 DOTA
[53:44]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第一场 1月31日
2021/03/11 DOTA
删除目录下相同文件的python代码(逐级优化)
2012/05/25 Python
python使用Matplotlib绘制分段函数
2018/09/25 Python
Python设计模式之装饰模式实例详解
2019/01/21 Python
利用Python产生加密表和解密表的实现方法
2019/10/15 Python
TensorFlow实现打印每一层的输出
2020/01/21 Python
采购部岗位职责
2013/11/24 职场文书
网络营销计划书
2015/01/17 职场文书
MySQL查询学习之基础查询操作
2021/05/08 MySQL
Oracle11g R2 安装教程完整版
2021/06/04 Oracle