【MUI】5+ 预截原动画 打开webview案例

码途觅雪鹤
• 阅读 6659

讲几句

每次官方的案例不是太多,包括有段时间出世的plus.nativeObj.View
可以先看看官方的文章
plus.nativeObj.View解析
HTML5+ 官方 API

不说别的,咱们来看看官方人员的这一段解释

【MUI】5+ 预截原动画 打开webview案例

看起来很高大上啊!来来来,趁着晚上的时间折腾一下。

WebView截图

新建一个bitmap类型的变量(其实是原生的一种映射变量)

var bitmap = new plus.nativeObj.Bitmap('nwbitmap');//nwbitmap为bitmap的id

然后将webview内容绘制到Bitmap对象中

    var ws = plus.webview.currentWebview();
    ws.draw(bitmap,function(){
        console.log('截屏绘制图片成功');
    },function(e){
        console.log('截屏绘制图片失败:'+JSON.stringify(e));
    });

为了能获取到每一个webview的截图,我们封装一下

        //webview截图
        var drawWebView = function(webview, bitmap, callback) {
            bitmap = bitmap || new plus.nativeObj.Bitmap('defultBitMap');
            webview.draw(bitmap, function() {
                callback && callback(bitmap);
            }, function(err) {
                callback && callback();
                console.log('截图错误:' + JSON.stringify(err))
            });
        }

原生动画

原生动画这块的资料太多,我这里不做多解释,大家可以查阅资料5+开始原生动画

        //开始原生动画
        var startAnimation = function(type, bitmap, callback) {
            plus.nativeObj.View.startAnimation({
                type: type || 'pop-in'//pop-in从右到左划入 pop-out从右到左划出
            }, {}, {
                bitmap: bitmap
            }, function() {
                console.log('动画结束');
                callback && callback();
                //关闭原生动画 在这里我注释,选择在回调函数callback内处理
                //plus.nativeObj.View.clearAnimation();
            });
        }

对比

直接上干货吧
app.js

var App = (function($) {
    var app = {};
    
    app.openWindow = function(url, id, op, data) {

        var nw = plus.webview.create(url, id, op, data),
            bitmap = new plus.nativeObj.Bitmap('nwbitmap');

        //开始原生动画
        var startAnimation = function(type, bitmap, callback) {
            plus.nativeObj.View.startAnimation({
                type: type || 'pop-in'//默认
            }, {}, {
                bitmap: bitmap
            }, function() {
                console.log('动画结束');
                callback && callback();
                //关闭原生动画 
                //plus.nativeObj.View.clearAnimation();
            });
        }

        //webview截图
        var drawWebView = function(webview, bitmap, callback) {
            bitmap = bitmap || new plus.nativeObj.Bitmap('defultBitMap');
            webview.draw(bitmap, function() {
                callback && callback(bitmap);
            }, function(err) {
                callback && callback();
                console.log('截图错误:' + JSON.stringify(err))
            });
        }

        //webview onloaded事件
        nw.onloaded = function(e) {
            //开始截图open
            drawWebView(nw, bitmap, function(bitmap) {
                if(!bitmap) {
                    nw.show('pop-in', 300);
                    return;
                }
                //播放页面打开的动画
                startAnimation('pop-in', bitmap, function() {
                    //动画播放完毕后
                    //显示webview
                    nw.show('none', 0, function() {
                        //当webview关闭时
                        nw.onclose = function() {
                                //播放页面关闭动画
                                startAnimation('pop-out', bitmap, function() {
                                    //关闭页面原生动画 
                                    plus.nativeObj.View.clearAnimation();
                                });
                            }
                            //关闭页面原生动画 
                        plus.nativeObj.View.clearAnimation();
                    })
                });

            });
        }
    }

    return app;
}(mui))

main.html

<!doctype html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <link href="css/mui.min.css" rel="stylesheet" />
    </head>

    <body>
        <script src="js/mui.min.js"></script>
        <script src="js/app.js" ></script>
        <script>
            mui.init();
            mui.ready(function(){
                var url = 'feedback.html';
                document.querySelectorAll("button")[0].addEventListener('tap',function(){
                    App.openWindow(url,'hehe');    
                });
                document.querySelectorAll("button")[1].addEventListener('tap',function(){
                    mui.openWindow(url,url,{
                         show:{
                            duration:300
                        },
                        waiting:{
                            autoShow:false
                        }
                    });
                });
            });
        </script>
        <button type="button" class="mui-btn mui-btn-blue mui-btn-block">截图方式 打开页面</button>
        <button type="button" class="mui-btn mui-btn-blue mui-btn-block">MUI默认 打开页面</button>
    </body>

    <script>
    </script>

</html>

看看效果

【MUI】5+ 预截原动画 打开webview案例

可能动态图不是很清晰,在这里我总结一下
用预截图做动画打开webview 的方式 我简称 预截原动画
用默认webview的位移、渐变的效果打开webview 的方式 我简称 渐变帧动画

预截原动画
预截原动画是通过先把要打开的webview创建,然后监听onloaded事件,截一张webview的bitmap图 给 原生动画 调用
无疑这种方式的渲染打开是很稳的,然而可能是我代码逻辑问题,也可能是受webview默认的打开动画影响,在关闭时会瞬间闪屏。我也不多做解释。
预截原动画,真的很稳,打开新的页面,可以看得出,不掉帧,mui默认渐变帧动画的方式会稍微掉帧,如果页面dom js 复杂可能效果差异更大

渐变帧动画
渐变帧动画是给webview的位置以及样式作出调整,从而达到一个动画的目的,但是当你的页面dom复杂,js加载量大,尤其是图片加载较多的话,那么在这种方式的Webview动画就会掉帧啦

不过可以尝试截图原动画的方式去处理较复杂页面,否则,我们用了这么久的渐变帧动画完全够用了啦。

晚安,我要睡了,卧槽,这么晚了

返回动画修复

前面说过了,动态图也看到了,用预截原动画打开的页面,返回,也就是关闭的时候会闪屏一下,现在有新的解决方案,虽然马虎点

1)使用mui的预加载 新页面

2)截图新页面
截图成功就监听

loaded事件:为播放打开动画
show事件:为关闭动画
hide事件:再次截图新页面
![图片上传中...]
,并播放关闭动画,且播放完毕后,关闭页面,关闭动画

截图失败 就使用 渐变帧动画 打开新页面

js改动如下

var App = (function($) {
    var app = {};

    //开始原生动画
    function startAnimation(type, bitmap, callback) {
        plus.nativeObj.View.startAnimation({
            type: type || 'pop-in' //默认
        }, {}, {
            bitmap: bitmap
        }, function() {
            callback && callback(plus.nativeObj.View.clearAnimation);
        });
    }

    //webview截图
    function drawWebView(webview, bitmap, callback) {

        bitmap = bitmap || new plus.nativeObj.Bitmap('defultBitMap');
        webview.draw(bitmap, function() {
            callback && callback(bitmap);
        }, function(err) {
            callback && callback();
            console.log('截图错误:' + JSON.stringify(err))
        });
    }

    app.openWindow = function(op) {
        if(op.id && plus.webview.getWebviewById(op.id)) {
            return;
        }
        var nw = $.preload(op),
            bitmap = new plus.nativeObj.Bitmap('nwbitmap');
        //webview onloaded事件
        nw.onloaded = function(e) {
            //开始截图open
            drawWebView(nw, bitmap, function(bitmap) {
                if(!bitmap) {
                    //截图失败就降级用默认打开
                    nw.show('pop-in');
                    return;
                }
                nw.addEventListener('show', function() {
                    plus.nativeObj.View.clearAnimation();
                })
                nw.addEventListener('hide', function() {
                    
                    drawWebView(nw, bitmap, function(bitmap) {
                        if(!bitmap) {
                            //截图失败就降级用默认打开
                            nw.close('pop-out');
                            return;
                        }
                        //播放页面关闭动画
                        startAnimation('pop-out', bitmap, function(close) {
                            nw.close();
                            //关闭页面原生动画 
                            close(); 
                        });
                        bitmap.clear();
                        bitmap = null;
                    });
                    
                })

                //播放页面打开的动画
                startAnimation('pop-in', bitmap, function(close) {
                    //动画播放完毕后
                    //显示webview
                    nw.show('none');
                    //close();
                });

            });

        }

    }

    return app;
}(mui))

html页面多增加了几个图片,更好的对比渲染情况

<!doctype html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <link href="css/mui.min.css" rel="stylesheet" />
    </head>

    <body>
        <script src="js/mui.min.js"></script>
        <script src="js/app.js" ></script>
        <script>
            mui.init();
            mui.ready(function(){
                var url = 'feedback.html';
                document.querySelectorAll("button")[0].addEventListener('tap',function(){
                    App.openWindow({
                        url:url,
                        id:'hehe'
                    });
                });
                document.querySelectorAll("button")[1].addEventListener('tap',function(){
                    mui.openWindow(url,url,{
                        waiting:{
                            autoShow:false
                        }
                    });
                });
            });
            
        </script>
        <button type="button" class="mui-btn mui-btn-blue mui-btn-block">截图方式 打开页面</button>
        <button type="button" class="mui-btn mui-btn-blue mui-btn-block">MUI默认 打开页面</button>
    </body>

    <script>
    </script>

</html>

效果图

效果图2.5m被吃了,尼玛 动态图

本文源码5+ 预截原动画

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
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
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Python Challenge Level 18
初学Python,挑战一下流行的PythonChallenge,很不幸,卡在了18关~~被字符字节码之间的转换搞得焦头烂额,不过终于搞定了还是很happy的~~~主要的问题就是16进制形式的字符如何转成字节码(注意:不是encoding)如:\'89','50','4e','47','0d','0a','1a','0a','00
Stella981 Stella981
3年前
AssemblyScript 入门指南[每日前端夜话0xEB]
每日前端夜话0xEB每日前端夜话,陪你聊前端。每天晚上18:00准时推送。正文共:2459 字预计阅读时间:10分钟作者:DannyGuo翻译:疯狂的技术宅来源:logrocket!(https://oscimg.oschina.net/oscnet/b880277c594152a503
Stella981 Stella981
3年前
Node.js 12中的ES模块[每日前端夜话0x9E]
每日前端夜话0x9E每日前端夜话,陪你聊前端。每天晚上18:00准时推送。正文共:2552字预计阅读时间:10 分钟作者:BrianDeSousa翻译:疯狂的技术宅来源:logrocket!(https://oscimg.oschina.net/oscnet/2ccaf94cecd3
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
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这