最近朋友圈被很多网易云音乐的年底歌单给刷屏了, 我也去看了我的年度歌单, 发现一个有意思的交互成果, 抉择卡通形象, 通过滑动抉择人物的不同头像,衣服,裤子 最终塑造成一个领有独立共性的卡通形象.
界面成果预览
交互成果预览
制作素材
把每个滑动的图片进行了全屏截图, 而后通过图片解决工具去除背景, 制作成对立大小的png图片.
图片的卡通元素都是通过截图获取, 每个元素被解决成对立大小, 局部会有锯齿, 仅供参考. 这里头部比拟非凡, 每个形象的头部大小不一, 这里取一个对立的截止线, 不便前面整合成整个形象. 其它相似,顶对齐即可.
剖析交互的特点
1. 轮播图2. 跨屏3. 滑动循环4. 局部衣服滑动会触发裤子的扭转5. 局部裤子滑动会触发衣服的扭转6. ...
轮播图代码
<div id="slide" class="bui-slide bui-slide-skin01"></div>
var uiSlide = bui.slide({ id: "#slide", height: 320, // autopage: true, // 主动分页 data: [{ image: "images/banner01.png", url: "pages/ui_controls/bui.slide_title.html", }, { image: "images/banner02.png", url: "pages/ui_controls/bui.slide_title.html", }, { image: "images/banner03.png", url: "pages/ui_controls/bui.slide_title.html", }], loop: true, // 循环 })
跨屏轮播图只需加上 cross:true
参数即可. 相熟BUI的敌人, 一眼就能找到相似的成果, 跨屏轮播图 第1-第3的特点就解决了.
有意思的是第4点第5点, 轮播图切换的时候局部须要互相关联.
实现的外围思路:
- 页面有一个动态全屏轮播图, 用于点击下一步,上一步的整屏切换. 动态轮播图的益处是构造能够自定义.
- 首屏初始化三个跨屏轮播图, 用于头部,衣服,裤子的失常抉择切换;
- 点击轮播图的时候, 切换激活状态, 非激活状态暗藏左右两个图片(暗藏通过css), 并禁止滑动 ;
- 当滑动选中当前,别离把头部,衣服,裤子的图片地址,索引 缓存在 bui.store (轮播图的to回调外面);
- 通过bui.store 创立衣服跟裤子的关联 conection 字段, 当检测到滑动的图片有配套裤子的时候,主动滑动下一个轮播图到指定地位;
- 点击下一步去到第2屏, 用于展现刚刚选中的数据;
// 衣服const cartoonBody = bui.slide({ id: "#cartoonBody", height: 320, stopPropagation: false, autopage: false, cross: true, loop: true, data: this.$data.cartoon.body}).on("to", function () { let index = this.index(); // bui.store 读取的时候须要应用 this.$data.xxx ,如果应用 this.xxx 读取会导致最终的值不能设置正确. let img = that.$data.cartoon.body[index].image; // 设置 that.profile.body.image = img; that.profile.body.index = index; // 检测衣服跟裤子的关系索引 let item = bui.array.get(that.$data.conection, img, "body"); let footindex = bui.array.index(that.$data.cartoon.foot, item.foot, "image"); if (footindex >= 0 && that.$data.active[1] == "active-block") { // 操作裤子的实例, 跳转的时候, 因为loop:true, 这里的索引须要在实在的索引下+1 that.$data.distances[2].to(footindex + 1, "none") }}).lock();// lock禁止滑动// 裤子const cartoonFoot = bui.slide({ id: "#cartoonFoot", height: 320, stopPropagation: false, autopage: false, cross: true, loop: true, data: this.$data.cartoon.foot}).on("to", function () { let index = this.index(); let img = that.$data.cartoon.foot[index].image; that.profile.foot.image = img; that.profile.foot.index = index; // 检测衣服跟裤子的关系索引 let item = bui.array.get(that.$data.conection, img, "foot"); let bodyindex = bui.array.index(that.$data.cartoon.body, item.body, "image"); if (bodyindex >= 0 && that.$data.active[2] == "active-block") { // 操作衣服的实例, 跳转的时候, 因为loop:true, 这里的索引须要在实在的索引下+1 that.$data.distances[1].to(bodyindex + 1, "none") }}).lock();// lock禁止滑动
最终成果
github地址: https://github.com/imouou/BUI...
codepen地址: https://codepen.io/imouou/ful...
BUI专一挪动开发, 灵便超出你的设想, 感谢您的浏览.
多页残缺代码
<!DOCTYPE HTML><html><head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>BUI</title> <meta name="format-detection" content="telephone=no" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/buijs@latest/lib/latest/bui.css" /> <style> .cartoon-page main, .step-item { background-color: #f2c9bc; padding-top: .2rem; } .step-item { width: 100%; height: 100%; } .cartoon-page h1, .cartoon-page p { text-align: center; color: #675553; } .cartoon-wrap .bui-slide { margin-bottom: .2rem; } .cartoon-wrap .bui-slide-img{ width: 4rem; height: 3.2rem; background-color: #e2b4a3; border-radius: .2rem; } .cartoon-wrap .active-block .bui-slide-img{ background-color: #fff; } .cartoon-wrap .active-block .bui-cross-prev, .cartoon-wrap .active-block .bui-cross-next{ visibility: visible; } .cartoon-wrap .bui-cross-prev, .cartoon-wrap .bui-cross-next{ visibility: hidden; } .cartoon-wrap .bui-cross-prev .bui-slide-img, .cartoon-wrap .bui-cross-next .bui-slide-img{ background-color: rgba(255,255,255,.3); } .bui-btn-step { width: 1.4rem; height: 1.4rem; line-height: 1.4rem; color: #fff; background-color: #f5433b; border: 3px solid rgba(255,255,255,0.8); padding: 0; margin-bottom: .2rem; } .bui-slide-cross .bui-cross-next .bui-slide-img, .bui-slide-cross .li-next .bui-slide-img{ margin-left: 0; } .bui-slide-cross .bui-cross-prev .bui-slide-img, .bui-slide-cross .li-prev .bui-slide-img{ margin-right: 0; } .bui-slide-fullscreen>.bui-slide-main>ul>li img.cartoonhead , .bui-slide-fullscreen>.bui-slide-main>ul>li img.cartoonbody, .bui-slide-fullscreen>.bui-slide-main>ul>li img.cartoonfoot { display: block; width:3.2rem ; height:3.2rem ; } .cartoonhead { position: relative; z-index: 3; } .cartoonbody { margin-top: -1.1rem; position: relative; z-index: 2; } .cartoonfoot { margin-top: -1.1rem; position: relative; z-index: 1; }</style></head><body><!-- HTML Begin--><!-- 这里还是一个规范的BUI页面 --><div class="bui-page bui-box-vertical cartoon-page"> <header></header> <main> <!-- 动态轮播图 --> <div id="uiSlide" class="bui-slide"> <div class="bui-slide-main"> <ul> <li> <!-- 垂直布局 --> <div class="step-item bui-box-center bui-box-vertical fullheight"> <div class="span1"> <h1>设置形象, 开启年度报告</h1> <p>左右切换抉择造型</p> <div class="bui-box bui-box-vertical cartoon-wrap"> <div class="span1" b-class="cartoons.active.0" b-click="cartoons.activeBlock(0)"> <div id="cartoonHead" class="bui-slide"></div> </div> <div class="span1" b-class="cartoons.active.1" b-click="cartoons.activeBlock(1)"> <div id="cartoonBody" class="bui-slide"></div> </div> <div class="span1" b-class="cartoons.active.2" b-click="cartoons.activeBlock(2)"> <div id="cartoonFoot" class="bui-slide"></div> </div> <!-- <div class="span1" b-class="cartoons.active.3" b-click="cartoons.activeBlock(3)"> <div id="cartoonDeco" class="bui-slide"></div> </div> --> </div> </div> <div class="container-y"> <div class="bui-btn-step ring" b-click="cartoons.next">下一步</div> </div> </div> </li> <li style="display:none;"> <!-- 垂直布局 --> <div class="step-item bui-box-center bui-box-vertical fullheight"> <!-- 最终形象 --> <div class="span1"> <div class="bui-box-center"> <div class="wrap-img">    </div> </div> </div> <div class="container-y"> <div class="bui-btn-step ring" b-click="cartoons.prev">上一步</div> </div> </div> </li> </ul> </div> </div> </main></div><!-- HTML End--> <!-- 依赖库 手机调试的js援用程序如下 --> <script src="https://cdn.jsdelivr.net/npm/buijs@latest/lib/zepto.js"></script> <script src="https://cdn.jsdelivr.net/npm/buijs@latest/lib/latest/bui.js"></script> <script> bui.ready(function () { // 这里写业务及控件初始化, 一个页面只能有一个bui.ready // 页面跳转的全屏轮播图 const uiSlideStep = bui.slide({ id: "#uiSlide", autopage: false, fullscreen: true, swipe: false, loop: false }) // 初始化数据行为存储 const bs = bui.store({ el: `.bui-page`, scope: "cartoons", data: { // 衣服裤子的关系, 局部衣服关联裤子, 裤子关联衣服 conection: [{ body: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body02.png", foot: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot01.png" }, { body: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body03.png", foot: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot05.png" }, { body: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body12.png", foot: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot08.png" }, { body: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body13.png", foot: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot07.png" }, { body: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body14.png", foot: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot06.png" }], distances: [], // 存储滑动的实例 active: { 0: "active-block", 1: "", 2: "", }, profile: { // 集体形象的存储 head: { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head01.png", index: 0, }, body: { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body01.png", index: 0, }, foot: { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot01.png", index: 0, }, deco: { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/deco/deco01.png", index: 0, } }, cartoon: { active: 0, // 激活的slide, 默认头部 head: [{ image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head01.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head02.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head03.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head04.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head05.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head06.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head07.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head08.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head09.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head10.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head11.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/head/head12.png", }], body: [{ image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body01.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body02.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body03.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body04.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body05.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body06.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body07.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body08.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body09.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body10.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body11.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body12.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body13.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/body/body14.png", }], foot: [{ image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot01.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot02.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot03.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot04.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot05.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot06.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot07.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot08.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/foot/foot09.png", }], deco: [{ image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/deco/deco01.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/deco/deco02.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/deco/deco03.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/deco/deco04.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/deco/deco05.png", }, { image: "https://gitee.com/imouou/bui-case-cartoon/raw/main/src/images/cartoon/deco/deco06.png", }], }, }, methods: { activeBlock(index) { for (let i = 0; i < Object.keys(this.$data.active).length; i++) { this.active[i] = ""; this.$data.distances[i].lock(); } // 给激活的滑动图加上款式,区别其它两个 this.active[index] = "active-block"; this.$data.distances[index].unlock(); }, next() { uiSlideStep.next(); }, prev() { uiSlideStep.prev(); } }, mounted: function () { // 焦点图 js 初始化: let that = this; const cartoonHead = bui.slide({ id: "#cartoonHead", height: 320, autopage: false, stopPropagation: false, cross: true, loop: true, data: this.$data.cartoon.head }).on("to", function () { let index = this.index(); // bui.store 读取的时候须要应用 this.$data.xxx ,如果应用 this.xxx 读取会导致最终的值不能设置正确. let img = that.$data.cartoon.head[index].image; // 设置 that.profile.head.index = index; that.profile.head.image = img; }) const cartoonBody = bui.slide({ id: "#cartoonBody", height: 320, stopPropagation: false, autopage: false, cross: true, loop: true, data: this.$data.cartoon.body }).on("to", function () { let index = this.index(); // bui.store 读取的时候须要应用 this.$data.xxx ,如果应用 this.xxx 读取会导致最终的值不能设置正确. let img = that.$data.cartoon.body[index].image; // 设置 that.profile.body.image = img; that.profile.body.index = index; // 检测衣服跟裤子的关系索引 let item = bui.array.get(that.$data.conection, img, "body"); let footindex = bui.array.index(that.$data.cartoon.foot, item.foot, "image"); if (footindex >= 0 && that.$data.active[1] == "active-block") { // 操作裤子的实例, 跳转的时候, 因为loop:true, 这里的索引须要在实在的索引下+1 that.$data.distances[2].to(footindex + 1, "none") } }).lock(); const cartoonFoot = bui.slide({ id: "#cartoonFoot", height: 320, stopPropagation: false, autopage: false, cross: true, loop: true, data: this.$data.cartoon.foot }).on("to", function () { let index = this.index(); let img = that.$data.cartoon.foot[index].image; that.profile.foot.image = img; that.profile.foot.index = index; // 检测衣服跟裤子的关系索引 let item = bui.array.get(that.$data.conection, img, "foot"); let bodyindex = bui.array.index(that.$data.cartoon.body, item.body, "image"); if (bodyindex >= 0 && that.$data.active[2] == "active-block") { // 操作衣服的实例, 跳转的时候, 因为loop:true, 这里的索引须要在实在的索引下+1 that.$data.distances[1].to(bodyindex + 1, "none") } }).lock(); // const cartoonDeco = bui.slide({ // id: "#cartoonDeco", // height: 320, // stopPropagation: false, // autopage: false, // cross: true, // loop: true, // data: this.$data.cartoon.deco // }).on("to", function () { // let index = this.index(); // that.profile.deco.image = that.$data.cartoon.deco[index].image // that.profile.deco.index = index; // }).to(0, "none").lock(); // 增加实例,跟cartoon.active 的数值对应. this.distances.push(cartoonHead, cartoonBody, cartoonFoot); } }) }) </script></body></html>