HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

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

希望审核大大看到后,帮忙审核通过下

小弟在此万分感谢

客户催的比较急

地图经纬度转换工具

uniapp 高德地图

实际在开发 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;
收起阅读 »

【分享】视频录制限制拍摄时长

录制视频 HBuilder X

安卓代码摘自论坛 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方式集成方法同理

iPhone iOS iOS打包 App离线打包 离线打包 iphonex

近期在负责公司的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关于引用微信小程序自定义组件像素单位的问题

upx Debug

经测试,在引用微信小程序自定义组件时,发生的一些问题:

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技术团队的无私奉献,让我们有这么好的一款国产跨平台开发编译平台

收起阅读 »

iOS离线打包配置

Xcode升级后,官方文档中有些配置需要变更,琢磨了大半天,整理了下文资料,完成离线打包配置。
iOS离线打包配置

Xcode升级后,官方文档中有些配置需要变更,琢磨了大半天,整理了下文资料,完成离线打包配置。
iOS离线打包配置

使用plus.gallery.pick打开本地相册

plus.gallery

使用plus.gallery.pick打开本地相册,必须在manifest.json里配置竖屏权限,不然打包后在ios里无法打开本地相册,会卡死,闪退

使用plus.gallery.pick打开本地相册,必须在manifest.json里配置竖屏权限,不然打包后在ios里无法打开本地相册,会卡死,闪退

hbuider plus app 用户退出登录逻辑-做贡献

退出 plus HTML5+ HBuilder

啥也不说直上代码,可能有逻辑不严谨的地方,如果有懂的朋友希望给指出。

$('#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监听手机锁屏,解锁,开屏

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

h5+ mui Vue

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,嘿嘿

收起阅读 »