微信小程序实现3d轮播图效果(非swiper组件)

首先上一下效果图:

效果图

 在做的时候首先想到的是用swiper组件但是发现swiper组件放进去图片的时候会没有3d的效果,原因是swiper组件自带的style属性限制了3d效果所需要的属性,所以单独写了一个组件。

index.html

<view class='page-con'>
    rotate.wxml
    <view class='stage'>
        <view class='wrapper' bindtouchstart='start' bindtouchend='end'>
            <block wx:for='{{swiperList}}'>
                <image class='imgBasic {{index === 0 ? "" : "fold"}} {{item.active ? item.swpClass : ""}}' src='{{item.imgsrc}}' data-index='{{index}}'></image>
            </block>
        </view>
        <view class='dots'>
            <block wx:for='{{swiperList}}' wx:key='unique'>
                <view data-i='{{index}}' bindtap='fn' class='dot {{index === currentImageIndex ? "active" : ""}}'></view>
            </block>
        </view>
    </view>
</view>

index.css:

.stage{
    perspective: 3000rpx;
    perspective-origin: 50% 50%;
    border: 2rpx solid rgba(0, 0, 0, 0.5);
    padding: 20rpx 28rpx;
    background: rgba(255, 255, 255,0.8);
    height: 520rpx;
}
.wrapper{
    height:480rpx;
    margin-top: 20rpx;
    transform-style: preserve-3d;
    position: relative;
}
.imgBasic{
    position: absolute;
    width:480rpx;
    height:480rpx;
    border-radius:10rpx;
    border: 7rpx solid #fff;
}
image:nth-child(1){
    -webkit-transform: rotateY(0deg);
    transform: rotateY(0deg);
}
image:nth-child(2){
    left: 260rpx;
}
image:nth-child(3){
    left: 320rpx;
}
image:nth-child(4){
    left: 380rpx;
}
.fold{
    transform: rotateY(-80deg) scale3d(1,0.85,1) translateZ(-10%);
    -webkit-transform: rotateY(-80deg) scale3d(1,0.85,1);
    background: rgba(255, 255, 255,0.8);
}

.swiper-con{
    height: 520rpx;
}
.scrollCon{
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    flex-wrap: nowrap;
    background: red;
}
.itemParent{
    position: relative;
    width: 100%;
    height: 1000rpx;
}
.item{
    width: 100rpx;
    float: left;
    height: 100rpx;
}
.item-con{
    height:500rpx;
}
swiper-item{
    width:480rpx;
    height:480rpx;
}

.idx-content {
  perspective: 1500;
}
.idx-content .idx-swiper {
  position: relative;
  margin: 40rpx 0;
  padding-bottom: 100%;
  transform-style: preserve-3d;
}
.idx-content .idx-swiper .idx-cswp {
  width: 70%;
  height: 100%;
  position: absolute;
  transform-style: preserve-3d;
  top: 0;
  border-radius: 6px;
}
.idx-content .idx-swiper .idx-cswp image {
  width: 100%;
  max-height: 600rpx;
}
.idx-content .idx-swiper .idx-cswp .swp-title .swp-btime {
  text-align: center;
  font-size: 28rpx;
}
.idx-content .idx-swiper .idx-cswp .swp-title .swp-bname {
  text-align: center;
  font-size: 24rpx;
}
/*
    右边的图片展开动画效果
*/
@keyframes rotateImage{
    from{
        transform:rotateY(-80deg);
        -webkit-transform:rotateY(-80deg);
        left: 250rpx;
    }
    to{
        transform: rotateY(0deg) scale3d(1,1,1);
        -webkit-transform: rotateY(0deg) scale3d(1,1,1);
        left: 0rpx;
    }
}
@keyframes backRotateImage{
    from{
        transform: roateteY(0deg) scale3d(1,1,1);
        -webkit-animation: rotateY(0deg) scale3d(1,1,1);
        filter: contrast(100%) brightness(100%);
    }
    to{
        transform: rotateY(280deg) scale3d(1,0.85,1);
        -webkit-animation: rotateY(280deg) scale3d(1,0.85,1);
        left: 210rpx;
    }
}
@keyframes leftMoveAnimation{
    from{
        /* transform:translateX(-300rpx); */
        /* left: 260rpx; */
    }to{
        transform:translateX(-40%) scale3d(1,0.85,1) rotateY(-80deg);
        -webkit-transform:translateX(-40%) scale3d(1,0.85,1) rotateY(-80deg);
    }
}
@keyframes leftMove2Animation{
    from{
        
    }to{
        transform:translateX(-35%) scale3d(1,0.85,1) rotateY(-80deg);
        -webkit-transform:translateX(-35%) scale3d(1,0.85,1) rotateY(-80deg);
    }
}
/*
    功能介绍:向左边展开,放大,位移操作
*/
.swp-left {
  animation: rotateImage 1s normal;
  -webkit-animation: rotateImage 1s normal;
  animation-iteration-count:1;
  animation-fill-mode: forwards;
  transform-origin: right;
  backface-visibility: hidden;
}
/*
    功能介绍:单独从左侧位移到屏幕的最后侧位置并且播放折叠动画
*/
.swp-right {
    animation: backRotateImage 1s normal;
    -webkit-animation: backRotateImage 1s normal;
    animation-iteration-count:1;
    animation-fill-mode: forwards;
    transform-origin: right;
    backface-visibility: hidden;
}
/*
  右边的动画依次向左移动,放大,旋转操作
*/
.move-left1{
    transform:rotateY(-80deg) scale3d(1,0.85,1);
    animation: leftMoveAnimation 1s normal;
    -webkit-animation: leftMoveAnimation 1s normal;
    animation-iteration-count:1;
    animation-fill-mode: forwards;
    transform-origin: right;
    backface-visibility: hidden;
}
.move-left2{
    transform:rotateY(-80deg) scale3d(1,0.85,1);
    animation: leftMove2Animation 1s normal;
    -webkit-animation: leftMove2Animation 1s normal;
    animation-iteration-count:1;
    animation-fill-mode: forwards;
    transform-origin: right;
    backface-visibility: hidden;
}
.dots{
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: center;
    margin: 0 8rpx;
    position: absolute;
    left: 0rpx;
    right: 0rpx;
    bottom: 15rpx;
}
.dot{
    margin: 0 8rpx;
    height: 15rpx;
    width: 15rpx;
    background: #da91f5;
    border-radius: 15rpx;
}
.active{
    width: 40rpx;
    height: 15rpx;
    border-radius: 15rpx;
}

控制层index.js:

// pages/lck/testJing/perfact.js
let app = getApp();
Page({

    /**
     * 页面的初始数据
     */
    data: {
        host: app.host,
        dkheight: 300,
        dkcontent: `你好<br/>nihao,<br/><br/><br/><br/><br/><br/><br/>这个是测试<br/><br/>你同意了吗<br/><br/><br/>hehe<b class='nihao'>n你好啊,我加粗了kk</b >
      <p><img src='http://shop.ykplay.com/upload/1/App.ico'/><strong>asdfasdfasd</strong></p>`,
        typeValue: null,
        showRightToast: false,
        changeImg: false,
        show: true,
        swiperList: [
            {
                index: 0,
                aurl: "../start/start",
                swpClass: "swp-left",
                active: false,
                imgsrc: "../../resources/test.png",
            },
            {
                index: 1,
                aurl: "#",
                swpClass: "swp-right",
                active: false,
                imgsrc: "../../resources/800.jpg"
            },
            {
                index: 2,
                aurl: "#",
                swpClass: "swp-right",
                active: false,
                imgsrc: "../../resources/900.jpg"
            },
            {
                index: 3,
                aurl: "#",
                swpClass: "swp-right",
                active: false,
                imgsrc: "../../resources/1000.jpg"
            }],
        played: false,
        //滑动触点开始的时候
        startPoint: 0,
        currentImageIndex: 0

    },

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
        this.data.typeValue = {};
        this.data.typeValue.size = 'M';
        this.data.typeValue.color = 'red';
        console.log("typeValue is ", this.data.typeValue);
        this.setData({
            typeValue: this.data.typeValue
        })
        let winPage = this;
        wx.getSystemInfo({
            success: function (res) {
                let winHeight = res.windowHeight;
                console.log(winHeight);
                winPage.setData({
                    dkheight: winHeight - winHeight * 0.05 - 80
                })
            }
        })

        wxParse.wxParse('dkcontent', 'html', this.data.dkcontent, this, 5);
    },

    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady: function () {

    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow: function () {
        //   wx.hideLoading();
    },

    /**
     * 生命周期函数--监听页面隐藏
     */
    onHide: function () {

    },

    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload: function () {

    },

    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh: function () {

    },

    /**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom: function () {

    },

    /**
     * 用户点击右上角分享
     */
    onShareAppMessage: function () {

    },
    previewImage: function (e) {
        var that = this,
            //获取当前图片的下表
            index = e.currentTarget.dataset.index,
            //数据源
            pictures = this.data.pictures;
        wx.previewImage({
            //当前显示下表
            current: pictures[index],
            //数据源
            urls: pictures
        })
    },
    onShareAppMessage: function (ops) {
        
    },

    show: function (event) {
        this.setData({
            show: true
        })
    },
    back: function () {
        this.setData({
            show: false
        })
    },
    //显示求换按钮
    swpBtn: function (event) {
        let swp = this.data.swiperList;
        let max = swp.length;
        let dataSet = event.currentTarget.dataset;
        let idx = dataSet.index;
        console.log("idx is ", idx);
        let prev = swp[idx - 1];
        let curView = swp[idx];
        let next = swp[idx + 1];
        console.log("prev is ", prev);
        console.log("curView is ", curView);
        for (let j = 0; j < max; j++) {
            swp[j].active = true;
        }
        if (idx == 1 && prev && next) {
            prev.swpClass = 'swp-right';
            curView.swpClass = 'swp-left';
            console.log("curView.index is ", curView.index);
            for (let i = 2; i < max; i++) {
                if (i === 2) {
                    swp[i].swpClass = 'move-left1';
                } else if (i === 3) {
                    swp[i].swpClass = 'move-left2';
                }
            }
            let self = this;
            this.setData({
                swiperList: swp
            }, () => {
                console.log("外层的setData被调用");
                //将数组中的第一个元素删除放到最后的位置
                let first = swp.shift();
                swp.push(first);
                console.log("swp is ", swp);
                self.data.swiperList = swp;
                self.setData({
                    swiperList: swp
                }, () => {
                    console.log("最内层的setData被调用");
                })
            })
        }
    },
    start: function (e) {
        console.log("e is ", e);
        this.data.startPoint = e.changedTouches[0].pageX;
        console.log("startPoint is ", this.data.startPoint);
    },
    end: function (e) {
        let isLeft = false;
        let isRight = false;
        console.log("e is ", e);
        console.log("endPoint is ", e.changedTouches[0].pageX);
        let endPoint = e.changedTouches[0].pageX;
        console.log("是否向左移动?", (endPoint - this.data.startPoint) < 0 ? (isLeft = true) : (isRight = true));
        console.log("isLeft is ", isLeft);
        console.log("isRight is ", isRight);
        //如果向左移动的话执行相应方法
        if (isLeft) {
            this.moveLeft(1);
        } else {
            // this.moveRight();
        }
    },
    moveLeft: function (idx) {
        if (idx === 1) {
            let swp = this.data.swiperList;
            let max = swp.length;
            let prev = swp[idx - 1];
            let curView = swp[1];
            let next = swp[idx + 1];
            console.log("prev is ", prev);
            console.log("curView is ", curView);
            for (let j = 0; j < max; j++) {
                swp[j].active = true;
            }
            if (prev && next) {
                prev.swpClass = 'swp-right';
                curView.swpClass = 'swp-left';
                console.log("curView.index is ", curView.index);
                // this.data.currentImageIndex = curView.index;
                this.setData({
                    currentImageIndex: curView.index
                })
                for (let i = 2; i < max; i++) {
                    if (i === 2) {
                        swp[i].swpClass = 'move-left1';
                    } else if (i === 3) {
                        swp[i].swpClass = 'move-left2';
                    }
                }
                let self = this;
                this.setData({
                    swiperList: swp
                }, () => {
                    console.log("外层的setData被调用");
                    //将数组中的第一个元素删除放到最后的位置
                    let first = swp.shift();
                    swp.push(first);
                    console.log("swp is ", swp);
                    self.data.swiperList = swp;
                    self.setData({
                        swiperList: swp
                    }, () => {
                        console.log("最内层的setData被调用");
                    })
                })
            }
        }
    },
    icon: function (e) {
        console.log("e is ", e);
    }
})

源码地址:rotate3d

现在的功能是左滑移动,感兴趣的朋友可以试试右滑移动。

猜你喜欢

转载自blog.csdn.net/lck8989/article/details/84431295