【JS】网易云音乐年度歌单的卡通形象联动制作

网易云音乐" title="网易云音乐">网易云音乐年度歌单的卡通形象联动制作

王小o发布于 10 分钟前

最近朋友圈被很多网易云音乐的年底歌单给刷屏了, 我也去看了我的年度歌单, 发现一个有意思的交互效果, 选择卡通形象, 通过滑动选择人物的不同头像,衣服,裤子 最终塑造成一个拥有独立个性的卡通形象.

界面效果预览

【JS】网易云音乐年度歌单的卡通形象联动制作

交互效果预览

image

【JS】网易云音乐年度歌单的卡通形象联动制作

制作素材

把每个滑动的图片进行了全屏截图, 然后通过图片处理工具去除背景, 制作成统一大小的png图片.

【JS】网易云音乐年度歌单的卡通形象联动制作
【JS】网易云音乐年度歌单的卡通形象联动制作
【JS】网易云音乐年度歌单的卡通形象联动制作

图片的卡通元素都是通过截图获取, 每个元素被处理成统一大小, 部分会有锯齿, 仅供参考. 这里头部比较特殊, 每个形象的头部大小不一, 这里取一个统一的截止线, 方便后面整合成整个形象. 其它类似,顶对齐即可.

分析交互的特点

1. 轮播图

2. 跨屏

3. 滑动循环

4. 部分衣服滑动会触发裤子的改变

5. 部分裤子滑动会触发衣服的改变

6. ...

【JS】网易云音乐年度歌单的卡通形象联动制作
轮播图代码

<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, // 循环

})

【JS】网易云音乐年度歌单的卡通形象联动制作

跨屏轮播图只需加上 cross:true 参数即可. 熟悉BUI的朋友, 一眼就能找到类似的效果, 跨屏轮播图 第1-第3的特点就解决了.

有意思的是第4点第5点, 轮播图切换的时候部分需要相互关联.

实现的核心思路:

  1. 页面有一个静态全屏轮播图, 用于点击下一步,上一步的整屏切换. 静态轮播图的好处是结构可以自定义.
  2. 首屏初始化三个跨屏轮播图, 用于头部,衣服,裤子的正常选择切换;
  3. 点击轮播图的时候, 切换激活状态, 非激活状态隐藏左右两个图片(隐藏通过css), 并禁止滑动 ;
  4. 当滑动选中以后,分别把头部,衣服,裤子的图片地址,索引 缓存在 bui.store (轮播图的to回调里面);
  5. 通过bui.store 创建衣服跟裤子的关联 conection 字段, 当检测到滑动的图片有配套裤子的时候,自动滑动下一个轮播图到指定位置;
  6. 点击下一步去到第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禁止滑动

最终效果

【JS】网易云音乐年度歌单的卡通形象联动制作
【JS】网易云音乐年度歌单的卡通形象联动制作

github地址: https://github.com/imouou/BUI...

codepen地址: https://codepen.io/imouou/ful...

BUI专注移动开发, 灵活超出你的想象, 感谢您的阅读.

【JS】网易云音乐年度歌单的卡通形象联动制作

多页完整代码

<!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/[email protected]/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>

<!-- 垂直布局 -->

<div class="step-item bui-box-center bui-box-vertical fullheight">

<!-- 最终形象 -->

<div class="span1">

<div class="bui-box-center">

<div class="wrap-img">

![](cartoons.profile.head.image)

![](cartoons.profile.body.image)

![](cartoons.profile.foot.image)

</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></script>

<script></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>

html5javascriptjquery前端webapp

阅读 19发布于 10 分钟前

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议


BUI WebApp开发框架

BUI 是一个跨终端,跨平台的UI交互框架, 用于快速开发WebApp,微信, 或结合第三方平台开发混合移动应用 ( ...

avatar

王小o

BUI专注webapp快速开发

301 声望

20 粉丝

0 条评论

得票时间

avatar

王小o

BUI专注webapp快速开发

301 声望

20 粉丝

宣传栏

最近朋友圈被很多网易云音乐的年底歌单给刷屏了, 我也去看了我的年度歌单, 发现一个有意思的交互效果, 选择卡通形象, 通过滑动选择人物的不同头像,衣服,裤子 最终塑造成一个拥有独立个性的卡通形象.

界面效果预览

【JS】网易云音乐年度歌单的卡通形象联动制作

交互效果预览

image

【JS】网易云音乐年度歌单的卡通形象联动制作

制作素材

把每个滑动的图片进行了全屏截图, 然后通过图片处理工具去除背景, 制作成统一大小的png图片.

【JS】网易云音乐年度歌单的卡通形象联动制作
【JS】网易云音乐年度歌单的卡通形象联动制作
【JS】网易云音乐年度歌单的卡通形象联动制作

图片的卡通元素都是通过截图获取, 每个元素被处理成统一大小, 部分会有锯齿, 仅供参考. 这里头部比较特殊, 每个形象的头部大小不一, 这里取一个统一的截止线, 方便后面整合成整个形象. 其它类似,顶对齐即可.

分析交互的特点

1. 轮播图

2. 跨屏

3. 滑动循环

4. 部分衣服滑动会触发裤子的改变

5. 部分裤子滑动会触发衣服的改变

6. ...

【JS】网易云音乐年度歌单的卡通形象联动制作
轮播图代码

<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, // 循环

})

【JS】网易云音乐年度歌单的卡通形象联动制作

跨屏轮播图只需加上 cross:true 参数即可. 熟悉BUI的朋友, 一眼就能找到类似的效果, 跨屏轮播图 第1-第3的特点就解决了.

有意思的是第4点第5点, 轮播图切换的时候部分需要相互关联.

实现的核心思路:

  1. 页面有一个静态全屏轮播图, 用于点击下一步,上一步的整屏切换. 静态轮播图的好处是结构可以自定义.
  2. 首屏初始化三个跨屏轮播图, 用于头部,衣服,裤子的正常选择切换;
  3. 点击轮播图的时候, 切换激活状态, 非激活状态隐藏左右两个图片(隐藏通过css), 并禁止滑动 ;
  4. 当滑动选中以后,分别把头部,衣服,裤子的图片地址,索引 缓存在 bui.store (轮播图的to回调里面);
  5. 通过bui.store 创建衣服跟裤子的关联 conection 字段, 当检测到滑动的图片有配套裤子的时候,自动滑动下一个轮播图到指定位置;
  6. 点击下一步去到第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禁止滑动

最终效果

【JS】网易云音乐年度歌单的卡通形象联动制作
【JS】网易云音乐年度歌单的卡通形象联动制作

github地址: https://github.com/imouou/BUI...

codepen地址: https://codepen.io/imouou/ful...

BUI专注移动开发, 灵活超出你的想象, 感谢您的阅读.

【JS】网易云音乐年度歌单的卡通形象联动制作

多页完整代码

<!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/[email protected]/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>

<!-- 垂直布局 -->

<div class="step-item bui-box-center bui-box-vertical fullheight">

<!-- 最终形象 -->

<div class="span1">

<div class="bui-box-center">

<div class="wrap-img">

![](cartoons.profile.head.image)

![](cartoons.profile.body.image)

![](cartoons.profile.foot.image)

</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></script>

<script></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>

以上是 【JS】网易云音乐年度歌单的卡通形象联动制作 的全部内容, 来源链接: utcz.com/a/109360.html

回到顶部