(前端项目实战) 微信 H5音乐项目总结

Wesley13
• 阅读 717

(前端项目实战) 微信 H5音乐项目总结 刚刚完成了一个 H5 项目,途中使用 audio 的时候遇到不少坑,所以写篇项目总结。

项目需求

要经过微信授权才能进入。所以只能在微信打开。

流程:

  1. 开场有个小的过渡效果,有 bgm

  2. 接着连续两张图片显示,有各自的 bgm

  3. 第二张图片,有文字,文字的显示要有打字的效果,附带 bgm

  4. 主场面

  5. 拥有各个小物品,像时钟、猫、电脑、手机、杂志、durex 等等

  6. 点击各个物品,对应的图片会切换,并且播放声音,最后显示一个确认框。时钟也会转动

  7. 点击关灯,进入下一个画面

  8. 接着又是图片的显示。图片会根据时钟的时间,显示不同的图片。也是简单的图片渐变显示、打字效果、弹幕和 bgm

  9. 最后是结果页,结果页有三个按钮,重新来一次,生成截图,外链

大概的需求就是这样,挺简单的。

遇到的问题

微信 ios 无法自动播放声音

这个处理起来不难。

  1. // 微信配置后

  2. wx.ready(() => {

  3. audio.play()

  4. })

  5. // 或者

  6. document.addEventListener("WeixinJSBridgeReady", () =>{

  7. WeixinJSBridge.invoke('getNetworkType', {}, () => {

  8. audio.play()

  9. })

  10. }, false)

这样就会自动播放起来了。不过会等当前资源加载完毕的时候才播放。我这个项目因为资源挺多的,所以加载了相当一段时间,然后才会播放音乐。

非微信 ios 如何自动播放声音?

这个好像就处理不了了。只能通过用户对应用触发了交互,才能播放起音乐。

比如有个开始按钮,用户点击了这个按钮后,你就可以执行事件回调播放音乐。

音乐播放,会有延迟的效果

比如资源还没加载到,不能立刻播放。

  1. // html

  2. <audio src='xxx' />

  3. //js

  4. function play(dom) {

  5. const oAudio = document.querySelector(dom)

  6. oAudio.play()

  7. oAudio.muted = true

  8. }

我们可以先让它播放起来,这样资源就会提前加载了,设置了静音,这样就能保证声音不会被听到。而且 DOM 节点是要一直存在的,除非你不需要再播放这个音乐。

至于在什么时候提前加载资源,就要看你的项目需求去判断了。

ios 无法设置音量大小

这个真的是蛋疼。。。项目一开始的 bgm 是要比较大声的,后面的流程要降低音量

  1. audio.volume = 0.5

安卓是没问题的,但是 ios 是无效的,就算在 dom 设置 volume 也是无效的。

苹果官网文档

在上面有一句话是说到这个问题:The volume property is not settable in JavaScript. Reading the volume property always returns 1.

最后。。。只能用两个相同的 bgm 但是不同音量的文件解决。但是这个 bgm 的文件大小有 500kb 。。。

图片无法快速加载

可以在项目开始前,提前加载

  1. const loadImg = (img) => {

  2. const isArray = Array.isArray(img)

  3. if (!isArray) {

  4. const oImg = new Image()

  5. oImg.src = img

  6. return new Promise(resolve => {

  7. oImg.onload = () => {

  8. resolve()

  9. }

  10. })

  11. }

  12. const arr = []

  13. img.forEach(v => {

  14. const oImg = new Image()

  15. oImg.src = v

  16. arr.push(new Promise(resolve => {

  17. oImg.onload = () => {

  18. resolve()

  19. }

  20. }))

  21. })

  22. return Promise.all(arr)

  23. }

接受单个字符串或者数组参数,使用 promise 处理。

加载图片后,再触发动画

让图片加载完了,再触发动画

  1. this.loadImg([img, img_1, img_2_1, img_2_2]).then(() => {

  2. setTimeout(() => {

  3. this.playMusic()

  4. this.setOne()

  5. }, 500)

  6. })

这样就不会图都没有出来,动画就播完了。

截图功能

原本打算自己用 canvas 根据 dom 渲染到画布上,再 toDataURL 生成图片的,然后找到了一个比较好的库, html2canvas,简单快捷,一键生成。

  1. html2canvas(document.querySelector('.app')).then(canvas => {

  2. // ...

  3. })

里面还有个坑,,截图是不能有跨域的图片存在,否则会空白一片。因为项目最后截图的效果,只有一张图片,所以我先把图片转成 base64,再截屏就可以了。

  1. createBase64() {

  2. const img = new Image()

  3. img.crossOrigin = true

  4. img.src = this.bg

  5. new Promise(resolve => {

  6. img.onload = () => {

  7. resolve()

  8. }

  9. }).then(() => {

  10. const oc = document.createElement('canvas')

  11. oc.width = img.width

  12. oc.height = img.height

  13. const ctx = oc.getContext('2d')

  14. ctx.drawImage(img, 0, 0)

  15. this.bg = oc.toDataURL()

  16. })

  17. }

页面布局

使用 rem 进行开发。

最外层 div 直接:

  1. #app {

  2. position: absolute;

  3. top: 0;

  4. left: 0;

  5. width: 100%;

  6. height: 100vh;

  7. overflow: hidden;

  8. }

不出现滚动条。

背景图就用 background

  1. .bg {

  2. background-size: cover;

  3. background-position: center center;

  4. }

然后其他一些比较散乱的,就用绝对定位

  1. .cat {

  2. position: absolute;

  3. top: 50%;

  4. left: 50%;

  5. }

先把对象定位到整个页面的中间,再用 margin / transform 进行调整位置。水平位置同理。

这些单个对象的,定位的策略就是已中心点为标准,进行定位。而不是以左上点或者左下点。

因为背景图也是直接显示中心部分的,所以单个对象的也要以中心点去定位。

限制资源大小

静态资源是 css, js, image, audio。css 还好,没用什么 ui 库。js 的话,只用了 vue 和 html2canvas。vue-router、vuex、mint-ui 这些都是统统去掉。

图片就用 gulp 配合 tinypng 进行压缩图片

  1. const gulp = require('gulp')

  2. const tiny = require('gulp-tinypng-nokey')

  3. const gulpLoadPlugins = require('gulp-load-plugins')

  4. // 还要安装 gulp-rename

  5. const plugins = gulpLoadPlugins()

  6. gulp.task('tinypng', function(cb) {

  7. gulp.src('src/assets/**/*.{jpg,jpeg,png,gif}')

  8. .pipe(tiny())

  9. .pipe(plugins.rename(function(path) {

  10. path.dirname = `/assets/${path.dirname}`

  11. }))

  12. .pipe(gulp.dest('./src'))

  13. })

这样是会把原文件给覆盖掉的,如果你有必要的话,执行前要做好备份

音乐文件的话,因为是客户那边找的,可以进行压缩下,或者把不会播放到的部分给裁剪到。

裁剪的工具,我用的是 mac 的 QuickTime player.app 进行裁剪的。简单地裁剪是没问题的。如果像增加或者降低音乐的声音大小,用的是 这个网站,挺好用的。最后就是格式的转换,用的是 MediaHuman Audio Converter.app

最后再把稍微大点的资源扔到类似七牛这种云服务器上,这样既能加快加载速度,又能减低服务器的压力。

总结

这次 H5 的开发,遇到比较麻烦的是 audio 这块。特别大部分 audio 问题是出自 ios 的。。。幸好有 iphone 进行开发测试,不然调试起来真的是麻烦大了。

静态资源扔到七牛后,加载速度快了很多。

至于网页和代码就不放出来了,现在还没上线,客户那边还在调细节~~

源自:segmentfault

声明:文章著作权归作者所有,如有侵权,请联系小编删除。

感谢 · 转发欢迎大家留言

(前端项目实战) 微信 H5音乐项目总结

本文分享自微信公众号 - web前端学习圈(web-xxq)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
梦
3年前
微信小程序new Date()转换时间异常问题
微信小程序苹果手机页面上显示时间异常,安卓机正常问题image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/b691e1230e2f15efbd81fe11ef734d4f.png)错误代码vardate'2021030617:00:00'vardateT
Easter79 Easter79
3年前
Taro小程序自定义顶部导航栏
微信自带的顶部导航栏是无法支持自定义icon和增加元素的,在开发小程序的时候自带的根本满足不了需求,分享一个封装好的组件,支持自定义icon、扩展dom,适配安卓、ios、h5,全面屏。我用的是京东的Taro多端编译框架写的小程序,原生的也可以适用,用到的微信/taro的api做调整就行,实现效果如下。!在这里插入图片描述(https://i
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这