整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

鸿蒙上实现“抽奖”小程序

鸿蒙上实现“抽奖”小程序

者:木棉花潘颖琳

本文是关于鸿蒙 Web 组件抽奖案例(ArkTS)的学习笔记。

本文分享的案例是 Web 组件如何加载本地 H5 小程序。所加载的页面是一个由 HTML+CSS+JavaScript 实现的完整小应用。

至于加载云端的 H5 小程序,实现步骤类似,可移步至 codelabs-Web 组件抽奖案例细览。

https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_HarmonyOS-WebComponent-ArkTS?ha_linker=eyJ0cyI6MTY3NzczNjQ3MjAxOSwiaWQiOiJiNzBiMmI1ODVhY2M0MGY4ODJmZjExYzFhM2QxYzE2NiJ9

效果图如下:

关键知识概念

Web 组件:提供具有网页显示能力的 Web 组件。访问在线网页时需添加网络权限:ohos.permission.INTERNET。

https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-basic-components-web-0000001333720957?ha_linker=eyJ0cyI6MTY3NzczNjcwNTgzMSwiaWQiOiI4ZDBkZTMzZjU1MzY0NDRlYjZkYTQ5MjM1MzcwMjEzZiJ9

runJavaScript:异步执行 JavaScript 脚本,并通过回调方式返回脚本执行的结果。

runJavaScript 需要在 loadUrl 完成后,比如 onPageEnd 中调用。

runJavaScript(options: { script: string, callback?: (result: string)=> void })

onConfirm:网页调用 confirm() 告警时触发此回调。此案例是用于回显抽奖结果。

onConfirm(callback: (event?: { url: string; message: string; result: JsResult })=> boolean)

创建空项目

选择 HarmonyOS 模板,项目 SDK 选择为 API9,选择模型为 Stage 模型。

如果要加载云端 H5 小程序的话,要记得在 module.json5 文件下添加网络权限:

"requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ],

编写本地 H5 页面

在 src/main/resources/rawfile 下分别创建:

  • 文件夹 img 用于存放抽奖展示的图片资源
  • 文件 index.html 用于编写页面布局
  • css 文件夹下再创建文件 index.css,用于编写组件的样式
  • js 文件夹下再创建文件 index.js,用于编写抽奖的函数处理

主要代码(抽奖功能实现):

// 旋转函数
function roll() {
    // 速度衰减
    speed -=50;
    if (speed <=10) {
        speed=10;
    }

    // 每次调用都去掉全部active类名,即去掉选中单元格的效果
    for (let j=0; j < allPrizesLi.length; j++) {
        allPrizesLi[j].classList.remove('active');
    }
    prizesPosition++;

    // 计算转圈次数,每至尾元素则圈数+1
    if (prizesPosition >=allPrizesLi.length - 1) {
        prizesPosition=0;
        count++;
    }

    //为当前选中的单元格添加active类,以添加选中的效果样式
    allPrizesLi[prizesPosition].classList.add('active');
    let initSpeed=500;
    let timer;  //定义定时器
    let totalCount=5; // 至少转动的总圈数

    // 满足转圈数和指定位置就停止
    if (count >=totalCount && (prizesPosition + 1)==index) {
        clearTimeout(timer);
        isClick=true;
        speed=initSpeed;
        timer=setTimeout(openDialog, 1000); // 等待1s打开弹窗
    } else {
        timer=setTimeout(roll, speed); // 不满足条件时调用定时器
        // 最后一圈减速
        if (count >=totalCount - 1 || speed <=50) {
            speed +=100;
        }
    }
}
// 抽奖开始函数
function startDraw() {
    // 防止抽奖多次触发
    if (isClick) {
        count=0;

        // 随机产生中奖位置
        index=Math.floor(Math.random() * prizesArr.length + 1);
        roll();
        isClick=false;
    }
}

function openDialog() {
    confirm(prizesArr[prizesPosition]);
}

调用 web 组件

在 pages 文件下创建文件 MainPage 和 WebPage,其中 WebPage 用于调用 web 组件,在 MainPage 中有用到一个自定义属性,觉得蛮有用的,记录一下:

@Extend(Button) function fancy (top: string) {
  .fontSize(16)
  .fontColor($r('app.color.start_window_background'))
  .width('86.7%')
  .height('5.1%')
  .margin({ top: top })
  .backgroundColor($r('app.color.blue'))
  .borderRadius('20')
}
Navigator({ target:'pages/WebPage', type: NavigationType.Push }) {
          Button($r('app.string.loadLocalH5'))
            .fancy('10%')
        }
        .params({ path:$rawfile('index.html'), tips: $r('app.string.local') })
      }

通过 navigator 组件带参跳转至 WebPage 界面,使用 web 组件前要先创建一个 web 控制器,则添加以下代码:

webController: web_webview.WebviewController=new web_webview.WebviewController();
  @State params: object=router.getParams();

其中,webviewController 要将 IDE 升级到最新版本才能用,是 API9+ 的接口,上述 WebController 接口在最新版本时弃用了。

同时要注意在 EntryAbility.ts 文件下修改:,也要注意查看 main_pages.json 的配置。

WebPage 中主要代码部分:

// web组件加载本地H5
          Web({ src: this.params['path'], controller: this.webController })
            .zoomAccess(false)
            .width('93.3%')
            .aspectRatio(1)
            .margin({ left: '3.3%', right: '3.3%', top:'7.1%'})
            .onConfirm((event)=> {
              AlertDialog.show({
                message: '恭喜您抽中' + `${event.message}`,
                confirm: {
                  value: $r('app.string.web_alert_dialog_button_value'),
                  action: ()=> {
                    event.result.handleConfirm();
                  }
                },
                cancel: ()=> {
                  event.result.handleCancel();
                }
              });
              return true;
            })


下方的按钮,异步执行 JavaScript 脚本 startDraw()。

Button($r('app.string.btnValue'))
            .fontSize(16)
            .fontColor($r('app.color.start_window_background'))
            .margin({ top: '10%' })
            .width('86.7%')
            .height('5.1%')
            .backgroundColor($r('app.color.blue'))
            .borderRadius('20')
            .onClick(()=> {
              this.webController.runJavaScript('startDraw()');
            })


到此,然后就可以运行模拟器 P50 进行调试了!

近年末,又到了各大公司举办年会的时候了。对于年会,大家最关心的应该就是抽奖了吧?虽然中奖概率通常不高,但总归是个机会,期待一下也是好的。

最近,我们部门举办了年会,也有抽奖环节。临近年会的前几天,Boss 突然找到我,说要做一个抽奖程序,部门年会要用。我当时都懵了:就三天时间,万一做的程序有bug,岂不是要被现场百十号人的唾沫给淹死?没办法,Boss 看起来对我很有信心,我也只能硬着头皮上了。

需求

  1. 要一个设置页面,包括设置奖项、参与人员名单等。
  2. 如果单个奖项中奖人数过多,可分批抽取,每批人数可设置。
  3. 默认按奖项顺序抽奖,也可选定某个奖项开始。
  4. 可删除没到场的中奖者,同时可再次抽取以作替补。
  5. 可在任意奖项之间切换,可查中奖记录名单
  6. 支持撤销当前轮次的抽奖结果,重新抽取。

实现

身为Web前端开发,自然想到用Web技术来实现。本着不重复造轮子的原则,首先求助Google,Github。搜了一圈好像没有找到特别好用的程序能直接用的。后来看到一个Github上的一个项目,用 TagCanvas 做的抽奖程序,界面挺好,就是逻辑有问题,点几次就崩溃了。代码是不能拿来用了,标签云这种抽奖形式倒是可以借鉴。于是找来文档看了下基本用法,很快就集成到页面里了。

由于设置页面涉及多种交互,纯手写太费时间了,直接用框架。平时 Element UI 用得比较多,自然就用它了。考虑到年会现场可能没有网络,就把框架相关的JS和CSS都下载到本地,直接引用。为了快速开发,也没搭建webpack构建工具了,直接在浏览器里引入JS。

    <link rel="stylesheet" href="css/reset.css" />
    <link
      rel="stylesheet"
      href="js/element-ui@2.4.11/lib/theme-chalk/index.css"
    />
    <script src="js/polyfill.min.js"></script>
    <script src="js/vue.min.js"></script>
    <script src="js/element-ui@2.4.11/lib/index.js"></script>
    <script src="js/member.js"></script>
复制代码
  1. 先设计数据结构。 奖项列表 awards
[{
    "name": "二等奖",
    "count": 25,
    "award": "办公室一日游"
}, {
    "name": "一等奖",
    "count": 10,
    "award": "BMW X5"
}, {
    "name": "特等奖",
    "count": 1,
    "award": "深圳湾一号"
}]

复制代码

参与人列表 members

[{
  "id": 1,
  "name": "张三"
}, {
  "id": 2,
  "name": "李四"
}]
复制代码

待抽奖人员列表players,是members 的子集

[{
  "id": 1,
  "name": "张三"
}]
复制代码

抽奖结果列表result,按奖项顺序索引

[[{
    "id": 1,
    "name": "张三"
}], [{
    "id": 2,
    "name": "李四"
}]]

复制代码
  1. 设置页面 包括奖项设置和参与人员列表。



  1. 抽奖页面

老男孩老师特别为大家准备了学习AI人工智能的干货礼包,后台私信1可获取5000G珍藏大礼包(培训视频、精选软件、内部资料)~让我们一起让IT学习更简单!

条的大佬们,我又来了,今天做个小东西,用CSS3做一个骰子玩一玩,具体的代码我全贴出来了,你们自己也试试。

这里还是要说一下我自己建的前端javascript学习群:204436223,不说别的,能进我群的没两把刷子怎么可能呢,当然小白我也挺欢迎,毕竟整天有人大神大神的叫,哈哈,也挺爽,不定期分享干货。想学到东西的都可以来,欢迎初学和进阶中的小伙伴

抽奖或游戏之类的动画很多时候用到掷骰子,一般采用gif图片格式实现动画效果。gif图片占内存较大,用户体验不好,下面用css3实现的掷骰子效果,骰子点数、面和转动效果都是有css,css3完成的。

效果图如下

制作过程如下:

一、制作六个面,如下图:

完全用css写出来,为了使其更加真实,可以让点数的圆圈加一些阴影,这一步比较简单。

二、将六个面拼成一个骰子

这一步需要用到css3的transform中rotate和translate。下面的css代码会纤细讲到。

三、让骰子动起来

这一步需要用到css3的animation。详细看下面css代码。

1.模板如下:

2.css

最后,我还要说一个问题,最近老有初学者问我,学前端要会英语吗??要数学很好吗?如果是的我不学了,在这里我可以告诉大家,英语和数学只能决定你的高度,和学习的能力,并不是说你英语和数学不好,前端就学不好。

如果想看到更加系统的文章和学习方法经验可以关注我的微信公众号:‘web前端课程’关注后回复‘给我资料’可以领取一套完整的学习视频