H5 音乐项目总结
方才完成了一个 H5 项目,途中运用 audio 的时刻碰到不少坑,所以写篇项目总结。
项目需求
要经由微信受权才进入。所以只能在微信翻开。
流程:
- 收场有个小的过渡效果,有 bgm
接着一连两张图片显现,有各自的 bgm
- 第二张图片,有笔墨,笔墨的显现要有打字的效果,附带 bgm
主排场
- 具有各个小物品,像时钟、猫、电脑、手机、杂志、durex 等等
- 点击各个物品,对应的图片会切换,而且播放声响,末了显现一个确认框。时钟也会迁移转变
- 点击关灯,进入下一个画面
- 接着又是图片的显现。图片会依据时钟的时候,显现差别的图片。也是简朴的图片渐变显现、打字效果、弹幕和 bgm
- 末了是效果页,效果页有三个按钮,重新来一次,天生截图,外链
也许的需求就是如许,挺简朴的。
碰到的题目
微信 ios 没法自动播放声响
这个处置惩罚起来不难。
// 微信设置后
wx.ready(() => {
audio.play()
})
// 或许
document.addEventListener("WeixinJSBridgeReady", () =>{
WeixinJSBridge.invoke('getNetworkType', {}, () => {
audio.play()
})
}, false)
如许就会自动播放起来了。不过会等当前资本加载终了的时刻才播放。我这个项目由于资本挺多的,所以加载了相称一段时候,然后才会播放音乐。
非微信 ios 怎样自动播放声响?
这个彷佛就处置惩罚不了了。只能经由过程用户对运用触发了交互,才播放起音乐。
比方有个最先按钮,用户点击了这个按钮后,你就可以够实行事宜回调播放音乐。
音乐播放,会有耽误的效果
比方资本还没加载到,不能马上播放。
// html
<audio src='xxx' />
//js
function play(dom) {
const oAudio = document.querySelector(dom)
oAudio.play()
oAudio.muted = true
}
我们能够先让它播放起来,如许资本就会提早加载了,设置了静音,如许就可以保证声响不会被听到。而且 DOM 节点是要一向存在的,除非你不需要再播放这个音乐。
至于在什么时刻提早加载资本,就要看你的项目需求去判断了。
ios 没法设置音量大小
这个真的是蛋疼。。。项目一最先的 bgm 是要比较高声的,背面的流程要下降音量
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 。。。
图片没法疾速加载
能够在项目最先前,提早加载
const loadImg = (img) => {
const isArray = Array.isArray(img)
if (!isArray) {
const oImg = new Image()
oImg.src = img
return new Promise(resolve => {
oImg.onload = () => {
resolve()
}
})
}
const arr = []
img.forEach(v => {
const oImg = new Image()
oImg.src = v
arr.push(new Promise(resolve => {
oImg.onload = () => {
resolve()
}
}))
})
return Promise.all(arr)
}
接收单个字符串或许数组参数,运用 promise 处置惩罚。
加载图片后,再触发动画
让图片加载完了,再触发动画
this.loadImg([img, img_1, img_2_1, img_2_2]).then(() => {
setTimeout(() => {
this.playMusic()
this.setOne()
}, 500)
})
如许就不会图都没有出来,动画就播完了。
截图功用
底本盘算本身用 canvas 依据 dom 衬着到画布上,再 toDataURL 天生图片的,然后找到了一个比较好的库, html2canvas,简朴快速,一键天生。
html2canvas(document.querySelector('.app')).then(canvas => {
// ...
})
内里另有个坑,,截图是不能有跨域的图片存在,否则会空白一片。由于项目末了截图的效果,只要一张图片,所以我先把图片转成 base64,再截屏就可以够了。
createBase64() {
const img = new Image()
img.crossOrigin = true
img.src = this.bg
new Promise(resolve => {
img.onload = () => {
resolve()
}
}).then(() => {
const oc = document.createElement('canvas')
oc.width = img.width
oc.height = img.height
const ctx = oc.getContext('2d')
ctx.drawImage(img, 0, 0)
this.bg = oc.toDataURL()
})
}
页面规划
运用 rem 举行开辟。
最外层 div 直接:
#app {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
overflow: hidden;
}
不涌现滚动条。
背景图就用 background
.bg {
background-size: cover;
background-position: center center;
}
然后其他一些比较狼藉的,就用相对定位
.cat {
position: absolute;
top: 50%;
left: 50%;
}
先把对象定位到全部页面的中间,再用 margin / transform 举行调解位置。程度位置同理。
这些单个对象的,定位的战略就是已中间点为规范,举行定位。而不是以左上点或许左下点。
由于背景图也是直接显现中间部份的,所以单个对象的也要以中间点去定位。
限定资本大小
静态资本是 css, js, image, audio。css 还好,没用什么 ui 库。js 的话,只用了 vue 和 html2canvas。vue-router、vuex、mint-ui 这些都是一切去掉。
图片就用 gulp 合营 tinypng 举行紧缩图片
const gulp = require('gulp')
const tiny = require('gulp-tinypng-nokey')
const gulpLoadPlugins = require('gulp-load-plugins')
// 还要装置 gulp-rename
const plugins = gulpLoadPlugins()
gulp.task('tinypng', function(cb) {
gulp.src('src/assets/**/*.{jpg,jpeg,png,gif}')
.pipe(tiny())
.pipe(plugins.rename(function(path) {
path.dirname = `/assets/${path.dirname}`
}))
.pipe(gulp.dest('./src'))
})
如许是会把原文件给覆蓋掉的,假如你有必要的话,实行前要做好备份
音乐文件的话,由于是客户那里找的,能够举行紧缩下,或许把不会播放到的部份给裁剪到。
裁剪的东西,我用的是 mac 的 QuickTime player.app 举行裁剪的。简朴地裁剪是没题目的。假如像增添或许下降音乐的声响大小,用的是 这个网站,挺好用的。末了就是花样的转换,用的是 MediaHuman Audio Converter.app
末了再把轻微大点的资本扔到相似七牛这类云服务器上,如许既能加速加载速率,又能减低服务器的压力。
总结
此次 H5 的开辟,碰到比较贫苦的是 audio 这块。迥殊大部份 audio 题目是出自 ios 的。。。幸好有 iphone 举行开辟测试,不然调试起来真的是贫苦大了。
静态资本扔到七牛后,加载速率快了许多。
至于网页和代码就不放出来了,如今还没上线,客户那里还在调细节~~