最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端活动抽奖组件设计

    正文概述 掘金(Sherlock09)   2021-01-12   427

    一 项目背景

    公司内部资料以及安全红线 只讨论技术细节 不透漏相关交互和设计
    

    二 交互以及视觉

        整体视觉:

        抽奖模块:大概是以一个花朵的花瓣为抽奖背景,旋转的时候不同的花瓣点亮

       前端活动抽奖组件设计

    三 分析需要解决的问题

        当做一个没有做过的东西的时候,这时候应该分析下完成这个效果需要考虑的问题,然后分解分析,然后逐步实施,分析总结遇到过的问题,是否有没考虑到的。

        其实这种抽奖模块在现在的活动页中十分的常见,尤其是在活动页中。

        首先,整理了TODO List

    1. 需要写成组件的形式,方便复用,需要考虑组件需要的传递的参数等等。
    2. 后端是接口的形式,也就是说,用户点击抽奖的时候,已经获得了中奖信息
    3. 前端需要执行一下抽奖轮转的动画,这个动画的时间、转动速率、转动期间禁止需要重复点击、初始的指针位置都需要前端来控制。
    4. 状态管理,针对不同抽奖次数、区分是否登陆、是否在APP内等相应的状态进行处理,弹窗或者跳转相应的URL
    5. 前端埋点相关和数据上报相关。
    6. 样式问题,设计交互的思路实际上是一个九宫格抽奖,但是视觉样式却是偏向指针类的轮盘抽奖,逻辑层面暂定的是按照九宫格的思路去实现,但是需要样式方面进行调整
    7. 抽奖的结果也需要写成一个弹窗组件,并且需要定义传入的参数
    8. 异常展示,当接口调用失败、后端数据库库存不足等等需要相应的warning弹窗组件

    四 具体设计

    4.1 封装成公共组件,主要是对组件传递的参数进行定义,首先在首页需要调用抽奖组件,必传的有三个参数
    

                showLuckDraw // 是否展示抽奖模块,如果用户已经抽过奖,默认不展示此模块,直接展示抽奖结果

                userStatus        // 用户状态:首页接口中会返回此信息,需要传入到组件中

                drawStatus       // 抽奖状态:

                此外还需要给抽奖组件的子组件–抽奖结果组件传递参数

                showSpecial&&type

    props: {
      // 是否展示抽奖模块,如果用户已经抽过奖,默认不展示此模块,直接展示抽奖结果
      showLuckDraw: {
       	type: Boolean
      },
      // 用户状态
      userStatus: {
        type: Number,
        required: true
      },
      // 抽奖状态 0: 跳转活动页 1: 需要通过活动增加抽奖次数 3: 不可抽奖
      drawStatus: {
        type: Number,
        required: true
      },
      // 是否已登陆 未登陆吊起登陆组件
      hasLogin: {
        type: Boolean,
        required: true
      },
      // 特殊弹窗 展示抽奖的结果
      showSpecial: {
        type: Boolean,
        default: false
      },
      // 向抽奖结果弹窗 传的值 显示对应的抽奖结果
      type: {
        type: Number,
        required: true,
      }
    },
    
    4.2 抽奖动画(核心逻辑)
    

            核心的思路是,当点击抽奖的时候,调用后端接口,并且设置转盘所需要的初始参数,包括如下

    diff           速度累加变量,控制逐渐加快/逐渐减慢
    star           开始按钮点击态,如果用户已经无法抽奖,直接禁用
    speed          抽奖初始速度
    isDisable      是否禁用开始抽奖按钮,防止重复抽奖,保证在在抽奖动画结束后才能再次抽奖,避免重复调用后端接口        
    
    drawStatus     设置抽奖状态初始值
    
    startTime      记录转动开始时间,用来控制动画时长
    

          同时,设置一个定时器,轮盘的背景图片依次切换来实现动画的效果,利用定期器的milliseconds 时间间隔进行速度控制,当达到预设的转动时间时,开始做减速运动,且如果后端返回的奖品id和前端设置的奖品id能对应上时,清除定时器,同时return中止函数,且重新设置转盘的状态值,完成抽奖动画。

        html 部分使用的简洁的jade,虽然刚开始上手有些不适应,但是用惯了之后,感觉十分简洁干净,不需要在大段的html代码里寻找class等

    <template lang="jade">
      .award-box(v-if="showLuckDraw")
      	.award-bg
      		.award(:class="'active' + (current)")
        button.start-btn(
          @click="start",
          :disabled="isDisable",
          :class="star ? 'star': '' "
        )
      .award-num 当前抽奖次数 
      	i.award-n {{ currentNum = +this.drawStatus === 2 ? 1 : 0 }} 
        i 次
      special-dialog(:show-special="showSpecial", :type="id")
    </template>
    
    
    
     move() {
        if (timeout) clearTimeout(timeout);
        const timeout = setTimeout( () => {
            this.current++; // 切换背景图,初始值可以随意设置
            if ( this.current > 4) { // 因为只有5个奖品,所以当current 从0开始大于4的时候,重新加载第一张图片
                this.current = 0;
            }
            // 若抽中的奖品id存在,且转动时间大于2秒,则开始减速转动
            if ( this.award.id && ( Date.now() - this.startTime ) / 1000 > 2 ) {
                this.speed += this.diff; // 转动减速
                //若转动超过4秒,并且奖品id等于格子的奖品id,则停下来
                // this.awards 是从后端获取的中奖结果,如果和前端对应的奖品id对应上的话则为中奖
                if ( ( Date.now() - this.startTime ) / 1000 > 4 && this.award.id == this.awards[this.current].id ) {
                    clearTimeout( timeout );
                    this.star        = false;
                    this.isDisable   = false;
                    this.showSpecial = true;    // 调用抽奖结果组件
                    this.type        = this.id; // 将中奖结果赋值给type,显示对应的抽奖结果组件
                    setTimeout( () => {
                        console.log(this.award.id);
                    },0);
                    return; // 抽中奖后停止定时器
                }
            //若抽中的奖品不存在,则加速转动    
            } else { 
                // todo:如果后端接口200且返回的中奖结果是错的,这里可以处理下异常
                this.speed -= this.diff;
            }
            this.move();
        }, this.speed );
      },
    
    4.3 状态管理,在调用move() 抽奖动画的之前,就对相应的用户状态做处理,未登陆的吊起登陆,没有次数的去获取次数,不可抽奖调用弹窗等等
    
    4.4 埋点这里在工具函数里封装了一个公共的函数,直接调用传参记录埋点信息,关于埋点的话有空再展开
    
    4.5 样式方面,遇到了一些问题
    
    • 最开始的想法是只改变花瓣的背景图,但是最后发现,图片是不规则的,是有角度的,难以定位准确。而且定位位置的计算在不同机型上有差异,所以采用整体图片的替换
    • 整体图片的替换又遇到一个闪烁问题:
      • 成因:因为当图片花瓣旋转时视觉上只是每个花瓣的变化,实际上是整张图片的变化,通过动态的切换calss来完成背景图片的替换。正因为这样,新的问题就产生了,当代码构建部署打包发不到线上时,静态资源一般会有单独的服务器,也就是说图片的资源请求会有一定延迟,这就导致了第一次加载点击抽奖的时候,页面花瓣转动会有闪烁,而第二次图片会走缓存,所以这个问题只出现一次,但是却是致命的
      • 解决方法:把url改为base64的Data URL,实际上就是利用base64编码把图片数据翻译成标准ASCII字符,Data URL是在本地直接绘制图片,不是从服务器加载,所以节省了HTTP连接,起到加速网页的作用,但是弊端就是IE8以下浏览器不支持这种方法(当然app内肯定是支持的,绝大部分手机也是支持的)。用这种方法会加重客户端的CPU和内存负担,总之有利有弊,而且不适合大图片,针对这个图片找UI替换了体积更小的图片,以减轻客户端的内存负担。

    4.6 针对中奖结果的弹窗,封装另一个组件,只需要传递type的参数就显示不同的中奖结果,类似的还有挂在到全局的弹窗组件,异常的时候及时抛出错误弹窗
    

    五 总结和反思

        虽然说现在活动页比较多且交互复杂,但是可以尽可能的封装一些公共的组件,提供基本的骨架,只需要修改一些css就能快速完成一个功能。

        还有对于没有做过的东西要具体分析,拆解成步骤,一步一步的完成,同时预留好一定的buffer时间,最重要的,经常总结与反思,查找自身的不足,在繁忙的工作中提升自己。


    起源地下载网 » 前端活动抽奖组件设计

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元