
mui使用百度语音合成来制作文字转语音来播放
百度语音合成中有对应的webapi可以使用,这个相对比较简单,废话不多说直接上代码吧。代码比较简单,老规矩不懂的在下方评论留言,觉得好就点个赞,转发请注明出处:https://blog.csdn.net/baidu_21919557;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet"/>
</head>
<body>
<div id="">
<textarea id="content" name="" rows="3" cols="20" style="top: 20px;height: 600px;"></textarea>
<input id="play" type="button" class="mui-btn mui-btn-block mui-btn-blue" style="height: 50px;" value="播放"></input>
<input id="puase" type="button" class="mui-btn mui-btn-block mui-btn-blue" style="height: 50px;" value="暂停"></input>
</div>
<script type="text/javascript" charset="utf-8">
var tokenUrl = "https://openapi.baidu.com/oauth/2.0/token";
var client_id = "client_id ";//此处为申请的client_id;
var client_secret = "client_secret ";/此处为申请的client_secret ;
var access_token;
var data = "grant_type=client_credentials&client_id="+client_id+"&client_secret="+client_secret;
var p = document.createElement("audio");//创建一个潜在的audio播放器
mui("body").on("tap","#play",function(){
var tex = document.getElementById("content").value.replace(/[\r\n]/g,"").replace(/\ +/g,"").replace(/-/g, '').trim();//对文本进行去空格和换行;
var a=0,b=0,c=0;
var contentArray = new Array();
if(tex.length/500>=0){//接口上传限制字数,避免出现接口腻出,限制上传字数
for (var i = 0; i < tex.length/500; i++) {
a = a + 500;
splitTex = tex.slice(b,a);
b=a;
contentArray.push(splitTex);
}
}
mui.ajax({
type:"get",
url:tokenUrl,
data:data,
async:true,
success:function(resp){
if(resp.access_token){
access_token = resp.access_token;
var shibieUrl = "http://tsn.baidu.com/text2audio";
tex = encodeURI(encodeURI(contentArray[0]));
var data = "tex="+tex+"&tok="+access_token+"&cuid=00:00:00:00:00:00&ctp=1&lan=zh&spd=5&pit=5&vol=5&per=0&aue=3";
p.controls="controls";
p.src = shibieUrl+"?"+data;
p.play();
c++;
}else{
}
},
error:function(error){
}
});
setTimeout(function(){
p.addEventListener('ended', function () {
if(contentArray.length>0&&c<=contentArray.length){
var shibieUrl = "http://tsn.baidu.com/text2audio";
tex = encodeURI(encodeURI(contentArray[c]));
var data = "tex="+tex+"&tok="+access_token+"&cuid=00:00:00:00:00:00&ctp=1&lan=zh&spd=5&pit=5&vol=5&per=0&aue=3";
p.src = shibieUrl+"?"+data;
p.play();
c++;
}else{
c=0;
}
});
},500);
});
mui("body").on("tap","#puase",function(){
if(p.paused) {
p.play();
}else{
p.pause();
}
});
</script>
</body>
</html>
百度语音合成中有对应的webapi可以使用,这个相对比较简单,废话不多说直接上代码吧。代码比较简单,老规矩不懂的在下方评论留言,觉得好就点个赞,转发请注明出处:https://blog.csdn.net/baidu_21919557;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet"/>
</head>
<body>
<div id="">
<textarea id="content" name="" rows="3" cols="20" style="top: 20px;height: 600px;"></textarea>
<input id="play" type="button" class="mui-btn mui-btn-block mui-btn-blue" style="height: 50px;" value="播放"></input>
<input id="puase" type="button" class="mui-btn mui-btn-block mui-btn-blue" style="height: 50px;" value="暂停"></input>
</div>
<script type="text/javascript" charset="utf-8">
var tokenUrl = "https://openapi.baidu.com/oauth/2.0/token";
var client_id = "client_id ";//此处为申请的client_id;
var client_secret = "client_secret ";/此处为申请的client_secret ;
var access_token;
var data = "grant_type=client_credentials&client_id="+client_id+"&client_secret="+client_secret;
var p = document.createElement("audio");//创建一个潜在的audio播放器
mui("body").on("tap","#play",function(){
var tex = document.getElementById("content").value.replace(/[\r\n]/g,"").replace(/\ +/g,"").replace(/-/g, '').trim();//对文本进行去空格和换行;
var a=0,b=0,c=0;
var contentArray = new Array();
if(tex.length/500>=0){//接口上传限制字数,避免出现接口腻出,限制上传字数
for (var i = 0; i < tex.length/500; i++) {
a = a + 500;
splitTex = tex.slice(b,a);
b=a;
contentArray.push(splitTex);
}
}
mui.ajax({
type:"get",
url:tokenUrl,
data:data,
async:true,
success:function(resp){
if(resp.access_token){
access_token = resp.access_token;
var shibieUrl = "http://tsn.baidu.com/text2audio";
tex = encodeURI(encodeURI(contentArray[0]));
var data = "tex="+tex+"&tok="+access_token+"&cuid=00:00:00:00:00:00&ctp=1&lan=zh&spd=5&pit=5&vol=5&per=0&aue=3";
p.controls="controls";
p.src = shibieUrl+"?"+data;
p.play();
c++;
}else{
}
},
error:function(error){
}
});
setTimeout(function(){
p.addEventListener('ended', function () {
if(contentArray.length>0&&c<=contentArray.length){
var shibieUrl = "http://tsn.baidu.com/text2audio";
tex = encodeURI(encodeURI(contentArray[c]));
var data = "tex="+tex+"&tok="+access_token+"&cuid=00:00:00:00:00:00&ctp=1&lan=zh&spd=5&pit=5&vol=5&per=0&aue=3";
p.src = shibieUrl+"?"+data;
p.play();
c++;
}else{
c=0;
}
});
},500);
});
mui("body").on("tap","#puase",function(){
if(p.paused) {
p.play();
}else{
p.pause();
}
});
</script>
</body>
</html>

请管理员,能否帮忙审下流应用,比较急
appid=H5C7685CB
希望审核大大看到后,帮忙审核通过下
小弟在此万分感谢
客户催的比较急
appid=H5C7685CB
希望审核大大看到后,帮忙审核通过下
小弟在此万分感谢
客户催的比较急

地图经纬度转换工具
实际在开发 UNI-APP过程用,要用到打开 高德地图APP 需求,看了5+ APP 接口,得把经纬度转 wgs84
在网上找的代码,简单封了一下,自己也是小白,参考高德地图小程序 SDK 简单封了一下,适合uni-app 小程序。不喜勿喷。
function mapTool() {
this.x_PI = 3.14159265358979324 * 3000.0 / 180.0,
this.PI = 3.1415926535897932384626,
this.ee = 0.00669342162296594323,
this.a = 6378245.0;
}
/**
* GCJ02 转换为 WGS84
* @param lng
* @param lat
* @returns {*[]}
*/
mapTool.prototype.gcj02towgs84 = function(lng, lat) {
if (this.out_of_china(lng, lat)) {
return [lng, lat]
} else {
let dlat = this.transformlat(lng - 105.0, lat - 35.0);
let dlng = this.transformlng(lng - 105.0, lat - 35.0);
let radlat = lat / 180.0 * this.PI;
let magic = Math.sin(radlat);
magic = 1 - this.ee * magic * magic;
let sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI);
dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI);
let mglat = lat + dlat;
let mglng = lng + dlng;
return [lng * 2 - mglng, lat * 2 - mglat]
}
},
/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
* 即谷歌、高德 转 百度
* @param lng
* @param lat
* @returns {*[]}
*/
mapTool.prototype.gcj02tobd09 = function(lng, lat) {
let z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * this.x_PI);
let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * this.x_PI);
let bd_lng = z * Math.cos(theta) + 0.0065;
let bd_lat = z * Math.sin(theta) + 0.006;
return [bd_lng, bd_lat]
},
/**
* WGS84转GCj02
* @param lng
* @param lat
* @returns {*[]}
*/
mapTool.prototype.wgs84togcj02 = function(lng, lat) {
if (this.out_of_china(lng, lat)) {
return [lng, lat]
} else {
let dlat = this.transformlat(lng - 105.0, lat - 35.0);
let dlng = this.transformlng(lng - 105.0, lat - 35.0);
let radlat = lat / 180.0 * this.PI;
let magic = Math.sin(radlat);
magic = 1 - this.ee * magic * magic;
let sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI);
dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI);
let mglat = lat + dlat;
let mglng = lng + dlng;
return [mglng, mglat]
}
},
/**
* GCJ02 转换为 WGS84
* @param lng
* @param lat
* @returns {*[]}
*/
mapTool.prototype.gcj02towgs84 = function(lng, lat) {
if (this.out_of_china(lng, lat)) {
return [lng, lat]
} else {
let dlat = this.transformlat(lng - 105.0, lat - 35.0);
let dlng = this.transformlng(lng - 105.0, lat - 35.0);
let radlat = lat / 180.0 * this.PI;
let magic = Math.sin(radlat);
magic = 1 - this.ee * magic * magic;
let sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI);
dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI);
let mglat = lat + dlat;
let mglng = lng + dlng;
return [lng * 2 - mglng, lat * 2 - mglat]
}
},
mapTool.prototype.transformlat = function(lng, lat) {
let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * this.PI) + 40.0 * Math.sin(lat / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * this.PI) + 320 * Math.sin(lat * this.PI / 30.0)) * 2.0 / 3.0;
return ret
},
mapTool.prototype.transformlng = function(lng, lat) {
let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * this.PI) + 40.0 * Math.sin(lng / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * this.PI) + 300.0 * Math.sin(lng / 30.0 * this.PI)) * 2.0 / 3.0;
return ret
},
/**
* 判断是否在国内,不在国内则不做偏移
* @param lng
* @param lat
* @returns {boolean}
*/
mapTool.prototype.out_of_china = function(lng, lat) {
return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
},
module.exports.mapTool = mapTool;
实际在开发 UNI-APP过程用,要用到打开 高德地图APP 需求,看了5+ APP 接口,得把经纬度转 wgs84
在网上找的代码,简单封了一下,自己也是小白,参考高德地图小程序 SDK 简单封了一下,适合uni-app 小程序。不喜勿喷。
function mapTool() {
this.x_PI = 3.14159265358979324 * 3000.0 / 180.0,
this.PI = 3.1415926535897932384626,
this.ee = 0.00669342162296594323,
this.a = 6378245.0;
}
/**
* GCJ02 转换为 WGS84
* @param lng
* @param lat
* @returns {*[]}
*/
mapTool.prototype.gcj02towgs84 = function(lng, lat) {
if (this.out_of_china(lng, lat)) {
return [lng, lat]
} else {
let dlat = this.transformlat(lng - 105.0, lat - 35.0);
let dlng = this.transformlng(lng - 105.0, lat - 35.0);
let radlat = lat / 180.0 * this.PI;
let magic = Math.sin(radlat);
magic = 1 - this.ee * magic * magic;
let sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI);
dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI);
let mglat = lat + dlat;
let mglng = lng + dlng;
return [lng * 2 - mglng, lat * 2 - mglat]
}
},
/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
* 即谷歌、高德 转 百度
* @param lng
* @param lat
* @returns {*[]}
*/
mapTool.prototype.gcj02tobd09 = function(lng, lat) {
let z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * this.x_PI);
let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * this.x_PI);
let bd_lng = z * Math.cos(theta) + 0.0065;
let bd_lat = z * Math.sin(theta) + 0.006;
return [bd_lng, bd_lat]
},
/**
* WGS84转GCj02
* @param lng
* @param lat
* @returns {*[]}
*/
mapTool.prototype.wgs84togcj02 = function(lng, lat) {
if (this.out_of_china(lng, lat)) {
return [lng, lat]
} else {
let dlat = this.transformlat(lng - 105.0, lat - 35.0);
let dlng = this.transformlng(lng - 105.0, lat - 35.0);
let radlat = lat / 180.0 * this.PI;
let magic = Math.sin(radlat);
magic = 1 - this.ee * magic * magic;
let sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI);
dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI);
let mglat = lat + dlat;
let mglng = lng + dlng;
return [mglng, mglat]
}
},
/**
* GCJ02 转换为 WGS84
* @param lng
* @param lat
* @returns {*[]}
*/
mapTool.prototype.gcj02towgs84 = function(lng, lat) {
if (this.out_of_china(lng, lat)) {
return [lng, lat]
} else {
let dlat = this.transformlat(lng - 105.0, lat - 35.0);
let dlng = this.transformlng(lng - 105.0, lat - 35.0);
let radlat = lat / 180.0 * this.PI;
let magic = Math.sin(radlat);
magic = 1 - this.ee * magic * magic;
let sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI);
dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI);
let mglat = lat + dlat;
let mglng = lng + dlng;
return [lng * 2 - mglng, lat * 2 - mglat]
}
},
mapTool.prototype.transformlat = function(lng, lat) {
let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * this.PI) + 40.0 * Math.sin(lat / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * this.PI) + 320 * Math.sin(lat * this.PI / 30.0)) * 2.0 / 3.0;
return ret
},
mapTool.prototype.transformlng = function(lng, lat) {
let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * this.PI) + 40.0 * Math.sin(lng / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * this.PI) + 300.0 * Math.sin(lng / 30.0 * this.PI)) * 2.0 / 3.0;
return ret
},
/**
* 判断是否在国内,不在国内则不做偏移
* @param lng
* @param lat
* @returns {boolean}
*/
mapTool.prototype.out_of_china = function(lng, lat) {
return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
},
module.exports.mapTool = mapTool;
收起阅读 »

【分享】视频录制限制拍摄时长
安卓代码摘自论坛 http://ask.dcloud.net.cn/question/45756
IOS 代码核心就是一个 videoMaximumDuration 参数
注意事项为 IOS 必须使用HbuilderX 真机调试、打包
使用到的5+ API http://www.html5plus.org/doc/zh_cn/camera.html#plus.camera.CameraOptions
附件为测试代码
function captureVideo(callback){
var TIMEOUT = 5; //录像时间 5 秒
if(mui.os.android) {
// 调用原生android摄像头
var VIDEOZOOM = 200;
var MediaStore = plus.android.importClass("android.provider.MediaStore");
var Intent = plus.android.importClass("android.content.Intent");
// 导入后可以使用new方法创建类的示例对象
var intent = new Intent("android.media.action.VIDEO_CAPTURE");
intent.putExtra("android.intent.extra.videoQuality", 0); //0 means low quality, 1 means high quality
// intent.putExtra("android.provider.MediaStore.EXTRA_OUTPUT", url);
intent.putExtra("android.intent.extra.durationLimit", TIMEOUT); //设置录像时间,5秒钟
var main = plus.android.runtimeMainActivity();
main.startActivityForResult(intent, VIDEOZOOM);
// 获取返回参数
main.onActivityResult = function(requestCode, resultCode, data) {
var context = main;
plus.android.importClass(data);
var uri = data.getData();
var resolver = context.getContentResolver();
plus.android.importClass(resolver);
var cursor = resolver.query(uri, null, null, null, null);
plus.android.importClass(cursor);
cursor.moveToFirst();
var column = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
// 获取录制的视频路径
var path = cursor.getString(column);
if(path) {
callback && callback(path);
} else {
mui.toast("录制小视频失败");
}
}
} else {
/**
* HBuilderX已更新:iOS平台 新增 支持摄像头录像(plus.camera.startVideoCapture)设置视频长度(videoMaximumDuration)
* http://ask.dcloud.net.cn/question/59024
*/
var cmr = plus.camera.getCamera();
var res = cmr.supportedVideoResolutions[0];
var fmt = cmr.supportedVideoFormats[0];
cmr.startVideoCapture(function(path) {
callback && callback(path);
}, function(error) {
mui.toast("取消录制小视频");
}, {
resolution: res,
format: fmt,
filename: "_downloads/ibos/video/",
videoMaximumDuration:TIMEOUT //该参数仅支持HBuilderX 打包
});
}
}
安卓代码摘自论坛 http://ask.dcloud.net.cn/question/45756
IOS 代码核心就是一个 videoMaximumDuration 参数
注意事项为 IOS 必须使用HbuilderX 真机调试、打包
使用到的5+ API http://www.html5plus.org/doc/zh_cn/camera.html#plus.camera.CameraOptions
附件为测试代码
function captureVideo(callback){
var TIMEOUT = 5; //录像时间 5 秒
if(mui.os.android) {
// 调用原生android摄像头
var VIDEOZOOM = 200;
var MediaStore = plus.android.importClass("android.provider.MediaStore");
var Intent = plus.android.importClass("android.content.Intent");
// 导入后可以使用new方法创建类的示例对象
var intent = new Intent("android.media.action.VIDEO_CAPTURE");
intent.putExtra("android.intent.extra.videoQuality", 0); //0 means low quality, 1 means high quality
// intent.putExtra("android.provider.MediaStore.EXTRA_OUTPUT", url);
intent.putExtra("android.intent.extra.durationLimit", TIMEOUT); //设置录像时间,5秒钟
var main = plus.android.runtimeMainActivity();
main.startActivityForResult(intent, VIDEOZOOM);
// 获取返回参数
main.onActivityResult = function(requestCode, resultCode, data) {
var context = main;
plus.android.importClass(data);
var uri = data.getData();
var resolver = context.getContentResolver();
plus.android.importClass(resolver);
var cursor = resolver.query(uri, null, null, null, null);
plus.android.importClass(cursor);
cursor.moveToFirst();
var column = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
// 获取录制的视频路径
var path = cursor.getString(column);
if(path) {
callback && callback(path);
} else {
mui.toast("录制小视频失败");
}
}
} else {
/**
* HBuilderX已更新:iOS平台 新增 支持摄像头录像(plus.camera.startVideoCapture)设置视频长度(videoMaximumDuration)
* http://ask.dcloud.net.cn/question/59024
*/
var cmr = plus.camera.getCamera();
var res = cmr.supportedVideoResolutions[0];
var fmt = cmr.supportedVideoFormats[0];
cmr.startVideoCapture(function(path) {
callback && callback(path);
}, function(error) {
mui.toast("取消录制小视频");
}, {
resolution: res,
format: fmt,
filename: "_downloads/ibos/video/",
videoMaximumDuration:TIMEOUT //该参数仅支持HBuilderX 打包
});
}
}
收起阅读 »

IOS离线打包适配IPhoneX,Widget为实例,webView方式集成方法同理
近期在负责公司的IOS打包,因为要接入第三方渠道所以采用了离线打包方式
因为我司是做H5游戏开发的,需要设置沉浸式状态栏等
在IPhoneX适配时发现最新版本的ios以及xcode打包出来并不能完全适配,研究了两天ios发现完美解决方法

1.判断当前机器是否是IphoneX
+(BOOL)isIhoneX{
return (CGSizeEqualToSize(CGSizeMake(375.f, 812.f), [UIScreen mainScreen].bounds.size) || CGSizeEqualToSize(CGSizeMake(812.f, 375.f), [UIScreen mainScreen].bounds.size));
}
2.代码设定()
appDelegte.m中
application方法
在self.window = window;
此行代码下添加如下代码
NSInteger viewheight=0;
if ([AppDelegate isIhoneX]) {
viewheight=44; //IphoneX上下间距44PX
}else{
viewheight=0; //普通机型则设置为0,全屏显示
}
// 用来设定Frame的大小
self.window.frame = CGRectMake(0, viewheight, self.window.frame.size.width, self.window.frame.size.height - viewheight);
3.底部适配
在manifest.json文件中plus项中添加
"safearea": {
"background": "#000",
"bottom": {
"offset": "auto"
}
},
近期在负责公司的IOS打包,因为要接入第三方渠道所以采用了离线打包方式
因为我司是做H5游戏开发的,需要设置沉浸式状态栏等
在IPhoneX适配时发现最新版本的ios以及xcode打包出来并不能完全适配,研究了两天ios发现完美解决方法
1.判断当前机器是否是IphoneX
+(BOOL)isIhoneX{
return (CGSizeEqualToSize(CGSizeMake(375.f, 812.f), [UIScreen mainScreen].bounds.size) || CGSizeEqualToSize(CGSizeMake(812.f, 375.f), [UIScreen mainScreen].bounds.size));
}
2.代码设定()
appDelegte.m中
application方法
在self.window = window;
此行代码下添加如下代码
NSInteger viewheight=0;
if ([AppDelegate isIhoneX]) {
viewheight=44; //IphoneX上下间距44PX
}else{
viewheight=0; //普通机型则设置为0,全屏显示
}
// 用来设定Frame的大小
self.window.frame = CGRectMake(0, viewheight, self.window.frame.size.width, self.window.frame.size.height - viewheight);
3.底部适配
在manifest.json文件中plus项中添加
"safearea": {
"background": "#000",
"bottom": {
"offset": "auto"
}
},
收起阅读 »

HBuilderX关于引用微信小程序自定义组件像素单位的问题
经测试,在引用微信小程序自定义组件时,发生的一些问题:
1、wxcomponents目录下的小程序组件样式表不支持使用upx单位,使用upx单位会渲染失效。
2、wxcomponents目录下的小程序组件样式表里若使用px单位,在设置transformPx=true时也未能自动转换为upx。
暂缓解决办法:修改wxcomponents目录下的小程序组件样式里的px单位改为rpx,这样就有一个问题,vue页面使用的样式是upx,组件使用rpx就会造成组件大小不一的现象,若vue页面也改为rpx,那么后期也无法支持其他的平台,所以很纠结。
期望问题解决办法:希望能够在wxcomponents目录下的小程序组件样式里支持upx,或者transformPx=true,编译时对该目录下的所有样式进行自动转换为upx,这样才能统一像素单位,在写样式时也没有那么乱,UNI-APP统一像素单位是好事,既然统一的话就请全部调整规范做好适配吧。
感谢HBuilderX技术团队的无私奉献,让我们有这么好的一款国产跨平台开发编译平台
经测试,在引用微信小程序自定义组件时,发生的一些问题:
1、wxcomponents目录下的小程序组件样式表不支持使用upx单位,使用upx单位会渲染失效。
2、wxcomponents目录下的小程序组件样式表里若使用px单位,在设置transformPx=true时也未能自动转换为upx。
暂缓解决办法:修改wxcomponents目录下的小程序组件样式里的px单位改为rpx,这样就有一个问题,vue页面使用的样式是upx,组件使用rpx就会造成组件大小不一的现象,若vue页面也改为rpx,那么后期也无法支持其他的平台,所以很纠结。
期望问题解决办法:希望能够在wxcomponents目录下的小程序组件样式里支持upx,或者transformPx=true,编译时对该目录下的所有样式进行自动转换为upx,这样才能统一像素单位,在写样式时也没有那么乱,UNI-APP统一像素单位是好事,既然统一的话就请全部调整规范做好适配吧。
感谢HBuilderX技术团队的无私奉献,让我们有这么好的一款国产跨平台开发编译平台
收起阅读 »
使用plus.gallery.pick打开本地相册
使用plus.gallery.pick打开本地相册,必须在manifest.json里配置竖屏权限,不然打包后在ios里无法打开本地相册,会卡死,闪退
使用plus.gallery.pick打开本地相册,必须在manifest.json里配置竖屏权限,不然打包后在ios里无法打开本地相册,会卡死,闪退

hbuider plus app 用户退出登录逻辑-做贡献
啥也不说直上代码,可能有逻辑不严谨的地方,如果有懂的朋友希望给指出。
$('#goOut')[0].addEventListener('tap', function(e) {
//清除用户数据
localStorage.setItem('$user', '{}');
//清除是否长登录
localStorage.setItem('$userLogin', '{}');
/**
* 关闭除了 login 外的所有窗口
* 因为原生 activity 活动(窗口)是以栈的形式存在,即,login 刚打开会被压入栈顶,之后打开的页面会压在它上面。
* 退出登录逻辑:
* 退出登录时只保留栈顶 login(入口页面及当前页面的 webview),其他的都页面 close ,如果当前的如果也被 close 的话,
* 那么本页面的 js 就不会执行了,循环就会终端,会出错。这时候只剩下 login 与 currentWebview ,这样还不行,还要等本
* 循环关闭 webview 的 js 代码执行完后再把 currentWebview 关闭,这样小只剩下 login(入口页面)了,自然而然,登录
* 页面就显示出来了。虽然显示出来了,但是只是加载了 html 与 css 的样式,js 并没有加载,所以还要做其他处理,具体看下面的
* 实施方法。
* 具体实施:
* 1、用 plus.webview.all() 方法获取所有窗口的 webview 对象。
* 2、获取当前 webview 对象。
* 3、用 webviewObj.reload()方法重新加载一下 login 页面,这样 js 也有了。
* 4、循环所有窗口对像的数组(这里奇怪了,数组的第1个居然是入口页面....,与栈不符,就是写死了,为了防止
* 以后的变化造成措手不及,还是手动去获取一下“入口页面”的 url 然后再跟数组里每一个窗口对象的 url 进行对比,相等就
* 跳过本次循环,避免入口页面也被关闭掉。)关闭不想干的窗口。
* 5、关闭当前 webview 页面(窗口)
*/
// 获取所有Webview窗口
var all = plus.webview.all();
//获取当前页面
var currentWebview = plus.webview.currentWebview();
//获取入口页面的 url 地址
var entranceWebviewUrl = plus.webview.getWebviewById(plus.runtime.appid).getURL();
//重新加载 login 窗口
all[0].reload(true);
for(var i = 0; i < all.length; i++) {
if(entranceWebviewUrl == all[i].getURL()){
continue
}
if(currentWebview.getURL() != all[i].getURL()) {
all[i].close('none')
}
}
currentWebview.close('none')
})
啥也不说直上代码,可能有逻辑不严谨的地方,如果有懂的朋友希望给指出。
$('#goOut')[0].addEventListener('tap', function(e) {
//清除用户数据
localStorage.setItem('$user', '{}');
//清除是否长登录
localStorage.setItem('$userLogin', '{}');
/**
* 关闭除了 login 外的所有窗口
* 因为原生 activity 活动(窗口)是以栈的形式存在,即,login 刚打开会被压入栈顶,之后打开的页面会压在它上面。
* 退出登录逻辑:
* 退出登录时只保留栈顶 login(入口页面及当前页面的 webview),其他的都页面 close ,如果当前的如果也被 close 的话,
* 那么本页面的 js 就不会执行了,循环就会终端,会出错。这时候只剩下 login 与 currentWebview ,这样还不行,还要等本
* 循环关闭 webview 的 js 代码执行完后再把 currentWebview 关闭,这样小只剩下 login(入口页面)了,自然而然,登录
* 页面就显示出来了。虽然显示出来了,但是只是加载了 html 与 css 的样式,js 并没有加载,所以还要做其他处理,具体看下面的
* 实施方法。
* 具体实施:
* 1、用 plus.webview.all() 方法获取所有窗口的 webview 对象。
* 2、获取当前 webview 对象。
* 3、用 webviewObj.reload()方法重新加载一下 login 页面,这样 js 也有了。
* 4、循环所有窗口对像的数组(这里奇怪了,数组的第1个居然是入口页面....,与栈不符,就是写死了,为了防止
* 以后的变化造成措手不及,还是手动去获取一下“入口页面”的 url 然后再跟数组里每一个窗口对象的 url 进行对比,相等就
* 跳过本次循环,避免入口页面也被关闭掉。)关闭不想干的窗口。
* 5、关闭当前 webview 页面(窗口)
*/
// 获取所有Webview窗口
var all = plus.webview.all();
//获取当前页面
var currentWebview = plus.webview.currentWebview();
//获取入口页面的 url 地址
var entranceWebviewUrl = plus.webview.getWebviewById(plus.runtime.appid).getURL();
//重新加载 login 窗口
all[0].reload(true);
for(var i = 0; i < all.length; i++) {
if(entranceWebviewUrl == all[i].getURL()){
continue
}
if(currentWebview.getURL() != all[i].getURL()) {
all[i].close('none')
}
}
currentWebview.close('none')
})
收起阅读 »

mui关闭页面出现卡白屏或闪页面的情况
从a跳到b 如果想close a窗口首先在打开b的时候 creat:true一下然后在b页面获取所有窗口对象再判断如果是a窗口就close
这样做可能会出现闪屏现象,因此先隐藏a然后再关闭它。代码如下希望大家少跳坑
var all = plus.webview.all();
var current = plus.webview.currentWebview().id;
for(var i=0,len=all.length;i<len;i++){
if(all[i].id ==a.id){
all[i].hide();
all[i].close();
}
}
从a跳到b 如果想close a窗口首先在打开b的时候 creat:true一下然后在b页面获取所有窗口对象再判断如果是a窗口就close
这样做可能会出现闪屏现象,因此先隐藏a然后再关闭它。代码如下希望大家少跳坑
var all = plus.webview.all();
var current = plus.webview.currentWebview().id;
for(var i=0,len=all.length;i<len;i++){
if(all[i].id ==a.id){
all[i].hide();
all[i].close();
}
}

Native.JS监听手机锁屏,解锁,开屏
var receiver;
mui.plusReady(function() {
main = plus.android.runtimeMainActivity(); //获取activity
// 广播接收
var ALARM_RECEIVER = "alarm_receiver";
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: function(context, intent) { //实现onReceiver回调函数
var Intent = plus.android.importClass('android.content.Intent');
console.log(intent.getAction());
//action = intent.getAction();
if(intent.getAction() == Intent.ACTION_SCREEN_ON) {
console.log('开屏')
} else if(intent.getAction() == Intent.ACTION_SCREEN_OFF) {
console.log('锁屏')
} else if(intent.getAction() == Intent.ACTION_USER_PRESENT) {
console.log('解锁')
}
result.textContent += '\nAction :' + intent.getAction();
main.unregisterReceiver(receiver);
}
});
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var Intent = plus.android.importClass('android.content.Intent');
var filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
main.registerReceiver(receiver, filter); //注册监听
})
代码已测试过了ctrl+c直接使用
var receiver;
mui.plusReady(function() {
main = plus.android.runtimeMainActivity(); //获取activity
// 广播接收
var ALARM_RECEIVER = "alarm_receiver";
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: function(context, intent) { //实现onReceiver回调函数
var Intent = plus.android.importClass('android.content.Intent');
console.log(intent.getAction());
//action = intent.getAction();
if(intent.getAction() == Intent.ACTION_SCREEN_ON) {
console.log('开屏')
} else if(intent.getAction() == Intent.ACTION_SCREEN_OFF) {
console.log('锁屏')
} else if(intent.getAction() == Intent.ACTION_USER_PRESENT) {
console.log('解锁')
}
result.textContent += '\nAction :' + intent.getAction();
main.unregisterReceiver(receiver);
}
});
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var Intent = plus.android.importClass('android.content.Intent');
var filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
main.registerReceiver(receiver, filter); //注册监听
})
代码已测试过了ctrl+c直接使用
收起阅读 »
webpack构建h5plus多页面移动app
fast-h5plus
https://github.com/CC4J/fast-h5plus
说明
- 使用webpack构建多页面移动APP开发的快速框架
- 使用scss预处理器提高app样式开发效率
- 使用h5plus库调用移动端底层接口
- 使用vue提高开发效率,远离dom操作的繁琐
- 使用移动端布局终极解决方案hotcss让移动端布局开发更加容易
- 框架默认使用750px的设计稿,开发过程中在样式文件里直接书写像素px单位,webpack编译后会自动转换成对应的rem值
- 支持es6,es7语法,打包编译自动转es5,让你感受丝滑一般的开发畅快
使用
获取fast-h5plus
git clone git@github.com:CC4J/fast-h5plus.git
安装依赖
npm install
若安装缓慢可切换淘宝源
npm install --registry=https://registry.npm.taobao.org
开发
新建页面
新建一个页面我们需要做两步操作。
第一步是在 src/pages/ 目录下新建每个页面的入口js文件以及入口vue文件,如我们新建一个登陆页,我们需要在src/pages/下新建src/pages/login/login.js与src/pages/login/login.vue。
第二步需要在根目录下的config目录中修改page.config.js文件,如:
exports.pageSet = [
{title: '登陆页', filename: 'login'}
]
页面调试
新建完页面之后,我们需要在手机或pc浏览器中调试页面,需要进行三步操作。
第一步:修改根目录下的config目录中修改page.config.js文件,如:
exports.devPage = 'login';
在这里大家要注意,调试哪一个页面,就需要将devPage的值修改成对应页面的文件名。
第二步:修改src/config/ 目录下的api.js文件,如
var devMode = true;
将devMode的值改为true,作用有两处,一是开发阶段将使用webpack-dev-server的反向代理功能进行跨域请求。二是启动vconsole模块,方便在手机端调试时查看控制台的输出信息。这一步操作在整个开发过程中只进行一次。
第三步:在命令行运行npm start指令,启动webpack-dev-server服务。控制台会打印当前服务器的ip地址与端口后,我们只需要在Hbuilder中修改manifest中的入口为此ip地址与端口号则可启动进行真机调试。
注意:每次新建一个页面之后需要先停掉webpack-dev-server服务,按上面步骤操作之后再重新运行npm start命令即可。Hbuilder启动一次之后不需要再重新启动,你甚至可以停掉Hbuilder项目,手机中的调试基座仍会进行自动刷新。
打包
整个开发结束之后,我们需要对项目进行打包成apk或者ipk。打包之前需要进行以下操作:
第一步:修改src/config/ 目录下的api.js文件,如
var devMode = false;
将devMode的值改为false将关闭页面vconsole控制台,关闭webpack-dev-server反向代理进行跨域功能。
第二步:修改Hbuilder中manifest.json文件的入口,如我们app的入口页是登陆页面,则入口修改为dist/login.html.
第三步:使用Hbuilder打包时需要将除dist以外的文件或目录添加到un'pa'ckage非打包清单中,减少我们app的体积。
结束
求个star,嘿嘿
fast-h5plus
https://github.com/CC4J/fast-h5plus
说明
- 使用webpack构建多页面移动APP开发的快速框架
- 使用scss预处理器提高app样式开发效率
- 使用h5plus库调用移动端底层接口
- 使用vue提高开发效率,远离dom操作的繁琐
- 使用移动端布局终极解决方案hotcss让移动端布局开发更加容易
- 框架默认使用750px的设计稿,开发过程中在样式文件里直接书写像素px单位,webpack编译后会自动转换成对应的rem值
- 支持es6,es7语法,打包编译自动转es5,让你感受丝滑一般的开发畅快
使用
获取fast-h5plus
git clone git@github.com:CC4J/fast-h5plus.git
安装依赖
npm install
若安装缓慢可切换淘宝源
npm install --registry=https://registry.npm.taobao.org
开发
新建页面
新建一个页面我们需要做两步操作。
第一步是在 src/pages/ 目录下新建每个页面的入口js文件以及入口vue文件,如我们新建一个登陆页,我们需要在src/pages/下新建src/pages/login/login.js与src/pages/login/login.vue。
第二步需要在根目录下的config目录中修改page.config.js文件,如:
exports.pageSet = [
{title: '登陆页', filename: 'login'}
]
页面调试
新建完页面之后,我们需要在手机或pc浏览器中调试页面,需要进行三步操作。
第一步:修改根目录下的config目录中修改page.config.js文件,如:
exports.devPage = 'login';
在这里大家要注意,调试哪一个页面,就需要将devPage的值修改成对应页面的文件名。
第二步:修改src/config/ 目录下的api.js文件,如
var devMode = true;
将devMode的值改为true,作用有两处,一是开发阶段将使用webpack-dev-server的反向代理功能进行跨域请求。二是启动vconsole模块,方便在手机端调试时查看控制台的输出信息。这一步操作在整个开发过程中只进行一次。
第三步:在命令行运行npm start指令,启动webpack-dev-server服务。控制台会打印当前服务器的ip地址与端口后,我们只需要在Hbuilder中修改manifest中的入口为此ip地址与端口号则可启动进行真机调试。
注意:每次新建一个页面之后需要先停掉webpack-dev-server服务,按上面步骤操作之后再重新运行npm start命令即可。Hbuilder启动一次之后不需要再重新启动,你甚至可以停掉Hbuilder项目,手机中的调试基座仍会进行自动刷新。
打包
整个开发结束之后,我们需要对项目进行打包成apk或者ipk。打包之前需要进行以下操作:
第一步:修改src/config/ 目录下的api.js文件,如
var devMode = false;
将devMode的值改为false将关闭页面vconsole控制台,关闭webpack-dev-server反向代理进行跨域功能。
第二步:修改Hbuilder中manifest.json文件的入口,如我们app的入口页是登陆页面,则入口修改为dist/login.html.
第三步:使用Hbuilder打包时需要将除dist以外的文件或目录添加到un'pa'ckage非打包清单中,减少我们app的体积。
结束
求个star,嘿嘿
收起阅读 »