微信公众号最佳实践 ( 9.4)大转盘

大转盘

为了加强跟用户的互动,很多微信公众号配置了抽奖等营销活动功能,大转盘就是最常用的一种,相比广告推广方式,大转盘互动性强、趣味性高、深受用户喜爱

页面布局:
最重要的材料就是转盘图片和指针图片,要实现页面布局,其中将转盘设置为前景,指针设置为背景,以此定义外部,内部两个容器。
代码如下:

<div id="outercont"  >
        <div id="outer-cont">
          <div id="outer"><img src="img/activity-lottery-5.png"></div>
        </div>
        <div id="inner-cont">
          <div id="inner"><img src="img/activity-lottery-2.png"></div>
        </div>
      </div>

在定义一些显示的内容区域,主要有中奖结果区,奖项设置区,活动说明区。
代码如下:

<div class="boxcontent boxyellow">
          <div class="box">
            <div class="title-green"><span>奖项设置:</span></div>
            <div class="Detail">
              <p>一等奖:iphone6 奖品数量:10 </p>
              <p>二等奖:ipad6 。 奖品数量:20 </p>
              <p>三等奖:ipad mini2奖品数量:100 </p>
              <p>四等奖:iphone6 。奖品数量:10 </p>
              <p>五等奖:ipad6 。  奖品数量:20 </p>
              <p>六等奖:ipad mini 奖品数量:100 </p>
            </div>
          </div>
        </div>
        <div class="boxcontent boxyellow">
          <div class="box">
            <div class="title-green">活动说明:</div>
            <div class="Detail">
              <p>本次活动每人可以转 3 次 </p>
              <p>亲,大奖转出来,祝您好运哦!!  </p>
            </div>
          </div>

开发实现:

我们需要实现抽奖算法及中奖通知的功能。

首先定义指针转动时的中奖的角度和未中奖的角度,以便判断用户是否中奖,图中 有6个奖项区域,相应的有6个未中奖区域,奖项角度及其他变量定义如下:

 var totalAngle  = 0;
        var steps = [];
        var loseAngle = [36, 96, 156, 216, 276,336];
        var winAngle = [6, 66, 126,186,246,306];
        var prizeLevel;
        var count = 0;
        var now = 0;
        var a = 0.01;
        var outter, inner, timer, running = false;

这里写图片描述
这里写图片描述
这里写图片描述

bigwheel.php

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no;">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="format-detection" content="telephone=no">
    <title>幸运大转盘抽奖</title>
    <link href="css/activity-style.css" rel="stylesheet" type="text/css">
  </head>

  <body class="activity-lottery-winning" >
    <div class="main" >
      <script type="text/javascript">
        var loadingObj = new loading(document.getElementById('loading'),{radius:20,circleLineWidth:8});
        loadingObj.show();
      </script>
      <div id="outercont"  >
        <div id="outer-cont">
          <div id="outer"><img src="img/activity-lottery-5.png"></div>
        </div>
        <div id="inner-cont">
          <div id="inner"><img src="img/activity-lottery-2.png"></div>
        </div>
      </div>
      <div class="content"  >
        <div class="boxcontent boxyellow" id="result" style="display:none" >
          <div class="box">
            <div class="title-orange"><span>恭喜你中奖了</span></div>
            <div class="Detail">
              <p>你中了:<span class="red" id="prizelevel" ></span></p>
              <p class="red" id="red">你可向公众号发送【中奖】查询您的中奖结果!  </p>
            </div>
          </div>
        </div>
        <div class="boxcontent boxyellow">
          <div class="box">
            <div class="title-green"><span>奖项设置:</span></div>
            <div class="Detail">
              <p>一等奖:iphone6 奖品数量:10 </p>
              <p>二等奖:ipad6 。 奖品数量:20 </p>
              <p>三等奖:ipad mini2奖品数量:100 </p>
              <p>四等奖:iphone6 。奖品数量:10 </p>
              <p>五等奖:ipad6 。  奖品数量:20 </p>
              <p>六等奖:ipad mini 奖品数量:100 </p>
            </div>
          </div>
        </div>
        <div class="boxcontent boxyellow">
          <div class="box">
            <div class="title-green">活动说明:</div>
            <div class="Detail">
              <p>本次活动每人可以转 3 次 </p>
              <p>亲,大奖转出来,祝您好运哦!!  </p>
            </div>
          </div>
        </div>
      </div>

    </div>

    <script src="js/jquery.js" type="text/javascript"></script>
    <script src="js/alert.js" type="text/javascript"></script>
    <script type="text/javascript">
      $(function() {
        window.requestAnimFrame = (function() {
          return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
          function(callback) {
            window.setTimeout(callback, 1000 / 60)
          }
        })();
        var totalAngle  = 0;
        var steps = [];
        var loseAngle = [36, 96, 156, 216, 276,336];
        var winAngle = [6, 66, 126,186,246,306];
        var prizeLevel;
        var count = 0;
        var now = 0;
        var a = 0.01;
        var outter, inner, timer, running = false;
        function countSteps() {
          var t = Math.sqrt(2 * totalAngle / a);
          var v = a * t;
          for (var i = 0; i < t; i++) {
            steps.push((2 * v * i - a * i * i) / 2)
          }
          steps.push(totalAngle)
        }
        function step() {
          outter.style.webkitTransform = 'rotate(' + steps[now++] + 'deg)';
          outter.style.MozTransform = 'rotate(' + steps[now++] + 'deg)';
          outter.style.oTransform = 'rotate(' + steps[now++] + 'deg)';
          outter.style.msTransform = 'rotate(' + steps[now++] + 'deg)';
          if (now < steps.length) {
            requestAnimFrame(step)
          } else {
            running = false;
            setTimeout(function() {
              if (prizeLevel != null) {
                var levelName= new Array("", "一等奖", "二等奖", "三等奖", "四等奖", "五等奖", "六等奖")
                // var levelName = "";
                // if (prizeLevel == 1) {
                  // levelName = "一等奖"
                // } else if (prizeLevel == 2) {
                  // levelName = "二等奖"
                // } else if (prizeLevel == 3) {
                  // levelName = "三等奖"
                // } else if (prizeLevel == 4) {
                  // levelName = "四等奖"
                // } else if (prizeLevel == 5) {
                  // levelName = "五等奖"
                // } else if (prizeLevel == 6) {
                  // levelName = "六等奖"
                // }
                $("#prizelevel").text(levelName[prizeLevel]);
                $("#result").slideToggle(500);  //显示中奖结果
                $("#outercont").slideUp(500)    //隐藏转盘
              } else {
                alert("亲,继续努力哦!")
              }
            },
            200)
          }
        }
        function start(deg) {
          deg = deg || loseAngle[parseInt(loseAngle.length * Math.random())];
          running = true;
          clearInterval(timer);
          totalAngle  = 360 * 1 + deg;
          steps = [];
          now = 0;
          countSteps();
          requestAnimFrame(step)
        }
        window.start = start;
        outter = document.getElementById('outer');
        inner = document.getElementById('inner');
        i = 10;
        $("#inner").click(function() {
          if (running) return;
          if (count >= 3) {
            alert("您已经抽了 3 次奖,不能再抽了,下次再来吧!");
            return
          }
          //没有获得中奖json返回,让用户退出
          if (prizeLevel != null) {
            alert("亲,你不能再参加本次活动了喔!下次再来吧~");
            return
          }
          $.ajax({
            url: "data.php",
            dataType: "json",
            data: {
              openid: "o7MB9jg5Oi_VNIZzeBX9mWPZP3Y4",
              time: (new Date()).valueOf()
            },
            beforeSend: function() {
              running = true;
              timer = setInterval(function() {
                i += 5;
                outter.style.webkitTransform = 'rotate(' + i + 'deg)';
                outter.style.MozTransform = 'rotate(' + i + 'deg)'
              },
              1)
            },
            success: function(data) {
              //达到最大抽奖次数
              if (data.error == "max_times") {
                alert("您已经抽了 3 次奖,不能再抽了,下次再来吧!");
                count = 3;
                clearInterval(timer);
                return
              }
              //已中奖
              if (data.error == "ok") {
                $("#tel").val(data.tel);
                $("#red").text(data.message);
                // alert(data.message);
                count = 3;
                clearInterval(timer);
                prizeLevel = data.prizelevel;
                start(winAngle[data.prizelevel - 1]);
                return
              }
              //未中奖则累加次数
              running = false;
              count++
              prizeLevel = null;
              start()
            },
            //未获取json返回时
            error: function() {
              // alert(data.message);
              prizeLevel = null;
              start();
              running = false;
              count++
            },
            timeout: 4000
          })
        })
      });

      //保存用户中奖信息,手机号
      $("#save-btn").bind("click",
      function() {
        var btn = $(this);
        var tel = $("#tel").val();
        if (tel == '') {
          alert("请输入手机号");
          return
        }

        var submitData = {
          openid: 20,
          // code: $("#sncode").text(),
          tel: tel
        };
        $.post('data.php', submitData,
        function(data) {
          if (data.error == "ok") {
            alert(data.message);
            $("#result").slideUp(500);  //隐藏中奖结果
            $("#outercont").slideToggle(500)    //显示转盘
            return
          }
        },
        "json")
      });

    </script>
  </body>
</html>

data.php

<?php

// $openid = $_GET["openid"];
// $candidate = $_GET["candidate"];
// logger2($_GET['token']);
// logger2($_GET['t']);
// // error 是否中奖 ok 中奖, 
// // message 提示说明
// // prizelevel 奖品等级
// logger2($_GET['time']);
// logger2($_GET['openid']);
// logger2($_GET['tel']);
if (rand(1, 1000) <= 400){
    //将中奖记录写入数据库
    // logger2($_GET['time']);
    // logger2($_GET['openid']);
    // logger2($_GET['tel']);
    echo '{
        "error": "ok",
        "message": "奖品为iPhone5",
        "prizelevel": "2", 
        "success": "y"
    }';
}

function logger2($log_content)
{
    if(isset($_SERVER['HTTP_BAE_ENV_APPID'])){   //BAE
        require_once "BaeLog.class.php";
        $logger = BaeLog::getInstance();
        $logger ->logDebug($log_content);
    }else if (isset($_SERVER['HTTP_APPNAME'])){   //SAE
        sae_set_display_errors(false);
        sae_debug($log_content);
        sae_set_display_errors(true);
    }else {
        $max_size = 100000;
        $log_filename = "log.xml";
        if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}
        file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND);
    }
}
?>

整体index.php代码如下:

<?php
/*
    CopyRight 2018 All Rights Reserved
*/

define("TOKEN", "weixin");

$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
    $wechatObj->responseMsg();
}else{
    $wechatObj->valid();
}

class wechatCallbackapiTest
{
    public function valid()
    {
        $echoStr = $_GET["echostr"];
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }

    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];
        $token = TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if($tmpStr == $signature){
            return true;
        }else{
            return false;
        }
    }

    public function responseMsg()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        if (!empty($postStr)){
            $this->logger("R ".$postStr);
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $RX_TYPE = trim($postObj->MsgType);

            switch ($RX_TYPE)
            {
                case "event":
                    $result = $this->receiveEvent($postObj);
                    break;
                case "text":
                    $result = $this->receiveText($postObj);
                    break;
            }
            $this->logger("T ".$result);
            echo $result;
        }else {
            echo "";
            exit;
        }
    }

    private function receiveEvent($object)
    {
        $content = "";
        switch ($object->Event)
        {
            case "subscribe":
                $content = "欢迎关注 德强1012 ";
                break;
            case "unsubscribe":
                $content = "取消关注";
                break;
        }
        $result = $this->transmitText($object, $content);
        return $result;
    }

    private function receiveText($object)
    {
        $keyword = trim($object->Content);
        $category = substr($keyword,0,6);
        $code = trim(substr($keyword,6,strlen($keyword)));
        switch ($category)
        {
            case "会员":
                $content[] = array("Title" =>"会员卡", 
                "Description" =>"点击图片领取会员卡", 
                "PicUrl" =>"http://pic2.ooopic.com/01/38/77/75bOOOPICea.jpg", 
                "Url" =>"http://1.dq095.applinzi.com/91_membercard/member.php?openid=".$object->FromUserName);
                break;http:
            case "预约":
                $content[] = array("Title" =>"预约口腔医生", 
                "Description" =>"点击图片开始预约", 
                "PicUrl" =>"http://pic4.nipic.com/20091021/3320206_171831027464_2.jpg", 
                "Url" =>"http://1.dq095.applinzi.com/92_order/order.php?openid=".$object->FromUserName);
                break;
            case "相册":
                $content[] = array("Title" =>"产品相册", 
                "Description" =>"点击图片开始预约", 
                "PicUrl" =>"http://img2.imgtn.bdimg.com/it/u=3675030458,1339124782&fm=26&gp=0.jpg", 
                "Url" =>"//1.dq095.applinzi.com/93_album/1/huxing.php");
                break;
            case "照片":
                $content[] = array("Title" =>"产品相册", 
                "Description" =>"点击图片开始预约", 
                "PicUrl" =>"http://pic.90sjimg.com/back_pic/u/00/02/82/06/561c95213aaa4.jpg", 
                "Url" =>"http://1.dq095.applinzi.com/93_album/2/examples/jquery-mobile-2.html");
                break;
             case "转盘":
                $content[] = array("Title" =>"大转盘", 
                "Description" =>"大奖等你来拿哦", 
                "PicUrl" =>"http://www.96815.com.cn/images/kdlksx4Sd/cxxx/xscx/2017/5/11/85a9d876-0e9c-4a2d-aad8-8a7f365b4c98.jpeg", 
                "Url" =>"http://1.dq095.applinzi.com/94_bigwheel/index.php");
                break;
            default:
                $content = "";
                break;
        }
        if(is_array($content)){
            $result = $this->transmitNews($object, $content);
        }else{
            $result = $this->transmitText($object, $content);
        }
        return $result;
    }

    private function transmitText($object, $content)
    {
        $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[text]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                    </xml>";
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
        return $result;
    }

    private function transmitNews($object, $arr_item)
    {
        if(!is_array($arr_item))
            return;

        $itemTpl = "    <item>
                            <Title><![CDATA[%s]]></Title>
                            <Description><![CDATA[%s]]></Description>
                            <PicUrl><![CDATA[%s]]></PicUrl>
                            <Url><![CDATA[%s]]></Url>
                        </item>
                    ";
        $item_str = "";
        foreach ($arr_item as $item)
            $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);

        $newsTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[news]]></MsgType>
                        <Content><![CDATA[]]></Content>
                        <ArticleCount>%s</ArticleCount>
                        <Articles>
                        $item_str</Articles>
                    </xml>";

        $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));
        return $result;
    }

    private function logger($log_content)
    {
    }
}


?>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值