剛剛完成了一個 H5 項目荒适,途中使用 audio 的時候遇到不少坑梨熙,所以寫篇項目總結(jié)。
項目需求
要經(jīng)過微信授權(quán)才能進入刀诬。所以只能在微信打開咽扇。
流程:
開場有個小的過渡效果,有 bgm
接著連續(xù)兩張圖片顯示陕壹,有各自的 bgm
第二張圖片质欲,有文字,文字的顯示要有打字的效果糠馆,附帶 bgm
主場面
擁有各個小物品嘶伟,像時鐘、貓榨惠、電腦奋早、手機、雜志赠橙、durex 等等
點擊各個物品耽装,對應(yīng)的圖片會切換,并且播放聲音期揪,最后顯示一個確認框掉奄。時鐘也會轉(zhuǎn)動
點擊關(guān)燈,進入下一個畫面
接著又是圖片的顯示凤薛。圖片會根據(jù)時鐘的時間姓建,顯示不同的圖片。也是簡單的圖片漸變顯示缤苫、打字效果速兔、彈幕和 bgm
最后是結(jié)果頁,結(jié)果頁有三個按鈕活玲,重新來一次涣狗,生成截圖谍婉,外鏈
大概的需求就是這樣,挺簡單的镀钓。
遇到的問題
微信 ios 無法自動播放聲音
這個處理起來不難穗熬。
// 微信配置后
wx.ready(() => {
? audio.play()
})
// 或者
document.addEventListener("WeixinJSBridgeReady", () =>{ ?
?WeixinJSBridge.invoke('getNetworkType', {}, () => {
? ?audio.play()
?})
}, false)
這樣就會自動播放起來了。不過會等當(dāng)前資源加載完畢的時候才播放丁溅。我這個項目因為資源挺多的唤蔗,所以加載了相當(dāng)一段時間,然后才會播放音樂窟赏。
非微信 ios 如何自動播放聲音妓柜?
這個好像就處理不了了。只能通過用戶對應(yīng)用觸發(fā)了交互饰序,才能播放起音樂领虹。
比如有個開始按鈕,用戶點擊了這個按鈕后求豫,你就可以執(zhí)行事件回調(diào)播放音樂塌衰。
音樂播放,會有延遲的效果
比如資源還沒加載到蝠嘉,不能立刻播放最疆。
// html
//js
function play(dom) {
?const oAudio = document.querySelector(dom)
?oAudio.play()
?oAudio.muted = true
}
我們可以先讓它播放起來,這樣資源就會提前加載了蚤告,設(shè)置了靜音努酸,這樣就能保證聲音不會被聽到。而且 DOM 節(jié)點是要一直存在的杜恰,除非你不需要再播放這個音樂获诈。
至于在什么時候提前加載資源,就要看你的項目需求去判斷了心褐。
ios 無法設(shè)置音量大小
這個真的是蛋疼舔涎。。逗爹。項目一開始的 bgm 是要比較大聲的亡嫌,后面的流程要降低音量
audio.volume = 0.5
安卓是沒問題的,但是 ios 是無效的掘而,就算在 dom 設(shè)置 volume 也是無效的挟冠。
蘋果官網(wǎng)文檔
在上面有一句話是說到這個問題:Thevolumeproperty is not settable in JavaScript. Reading thevolumeproperty 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)
}
接受單個字符串或者數(shù)組參數(shù)逸寓,使用 promise 處理。
加載圖片后覆山,再觸發(fā)動畫
讓圖片加載完了竹伸,再觸發(fā)動畫
this.loadImg([img, img_1, img_2_1, img_2_2]).then(() => {
?setTimeout(() => {
? ?this.playMusic()
? ?this.setOne()
?}, 500)
})
這樣就不會圖都沒有出來,動畫就播完了簇宽。
截圖功能
原本打算自己用 canvas 根據(jù) dom 渲染到畫布上勋篓,再 toDataURL 生成圖片的,然后找到了一個比較好的庫魏割, html2canvas譬嚣,簡單快捷,一鍵生成钞它。
html2canvas(document.querySelector('.app')).then(canvas => {
?// ...
})
里面還有個坑拜银,,截圖是不能有跨域的圖片存在遭垛,否則會空白一片尼桶。因為項目最后截圖的效果,只有一張圖片锯仪,所以我先把圖片轉(zhuǎn)成 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 進行開發(fā)庶喜。
最外層 div 直接:
#app {
?position: absolute;
?top: 0;
?left: 0;
?width: 100%;
?height: 100vh;
?overflow: hidden;
}
不出現(xiàn)滾動條小腊。
背景圖就用 background
.bg {
?background-size: cover;
?background-position: center center;
}
然后其他一些比較散亂的,就用絕對定位
.cat {
?position: absolute;
?top: 50%;
?left: 50%;
}
先把對象定位到整個頁面的中間久窟,再用 margin / transform 進行調(diào)整位置秩冈。水平位置同理。
這些單個對象的瘸羡,定位的策略就是已中心點為標(biāo)準漩仙,進行定位。而不是以左上點或者左下點犹赖。
因為背景圖也是直接顯示中心部分的队他,所以單個對象的也要以中心點去定位。
限制資源大小
靜態(tài)資源是 css, js, image, audio峻村。css 還好麸折,沒用什么 ui 庫。js 的話粘昨,只用了 vue 和 html2canvas垢啼。vue-router窜锯、vuex、mint-ui 這些都是統(tǒng)統(tǒng)去掉芭析。
圖片就用 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'))
})
這樣是會把原文件給覆蓋掉的锚扎,如果你有必要的話,執(zhí)行前要做好備份
音樂文件的話馁启,因為是客戶那邊找的驾孔,可以進行壓縮下,或者把不會播放到的部分給裁剪到惯疙。
裁剪的工具翠勉,我用的是 mac 的QuickTime player.app進行裁剪的。簡單地裁剪是沒問題的霉颠。如果像增加或者降低音樂的聲音大小对碌,用的是?這個網(wǎng)站,挺好用的蒿偎。最后就是格式的轉(zhuǎn)換朽们,用的是MediaHuman Audio Converter.app
最后再把稍微大點的資源扔到類似七牛這種云服務(wù)器上,這樣既能加快加載速度酥郭,又能減低服務(wù)器的壓力华坦。
總結(jié)
這次 H5 的開發(fā),遇到比較麻煩的是 audio 這塊不从。特別大部分 audio 問題是出自 ios 的惜姐。。椿息。幸好有 iphone 進行開發(fā)測試歹袁,不然調(diào)試起來真的是麻煩大了。
靜態(tài)資源扔到七牛后寝优,加載速度快了很多条舔。
至于網(wǎng)頁和代碼就不放出來了,現(xiàn)在還沒上線乏矾,客戶那邊還在調(diào)細節(jié)~~