[原创]egret的WebView实现(基于egret2.5)

本文详细介绍了如何在 Egret 2.5 中实现 WebView 功能,包括 HtmlInput 的实现方式、WebView 的坐标宽高转换、IOS 系统中的适配问题以及完整的 WebView.ts 代码和使用示例。内容涵盖了 egret HtmlInput 的源码解析、缩放模式对 WebView 影响以及解决 iframe 宽高撑大和滑动问题的方案。
摘要由CSDN通过智能技术生成

egret的WebView实现(基于egret2.5)

标签(空格分隔): egret webview


客户端开发中有一种很常见的场景就是展现web页面,也就是 WebView 。例如 IOS 、 Android ,都为开发者提供了 WebView 组件,而在 egret 中暂时并没有提供 WebView 组件,所以我们只能自己动手实现一个能在 egret 引擎中可用的 WebView 组件。

由于egret运行在浏览器中,所以想要实现一个能展现web页面的组件,第一想法应该是使用iframe。
那么这些问题需要解决:

  • 与 egret 集成,并提供与 egret 组件一致的调用方式
  • 融入 egret 的展现,即 WebView 的坐标、大小需要与 egret 一致

查看 egret 源码,我们不难发现 egret 的 HtmlInput 组件也是使用上面我们所考虑的方式实现在游戏中进行文本输入的。所以,我们可以采用 egret HtmlInput 类似的方式实现 WebView 。因此,我们首先从 egret HtmlInuput 源码入手:

1. Egret中HtmlInput的实现

1.1 HtmlInput实现方式:

在 egret.web.js 中可以很找到 egret.web.HTMLInput 的初始化相关的源码:

    HtmlInput.prototype._initStageDelegateDiv = function (container, canvas) {
   
            this.canvas = canvas;
            var self = this;
            var stageDelegateDiv;
            if (!stageDelegateDiv) {
                stageDelegateDiv = document.createElement("div");
                this.StageDelegateDiv = stageDelegateDiv;
                stageDelegateDiv.id = "StageDelegateDiv";
                container.appendChild(stageDelegateDiv);
                self.initValue(stageDelegateDiv);
                self._inputDIV = document.createElement("div");
                self.initValue(self._inputDIV);
                self._inputDIV.style.width = "0px";
                self._inputDIV.style.height = "0px";
                self._inputDIV.style.left = 0 + "px";
                self._inputDIV.style.top = "-100px";
                self._inputDIV.style[egret.web.getPrefixStyleName("transformOrigin")] = "0% 0% 0px";
                stageDelegateDiv.appendChild(self._inputDIV);
                this.canvas.addEventListener("click", function (e) {
   
                    if (self._needShow) {
                        self._needShow = false;
                        self._stageText._onClickHandler(e);
                        self.show();
                    }
                    else {
                        if (self._inputElement) {
                            self.clearInputElement();
                            self._inputElement.blur();
                            self._inputElement = null;
                        }
                    }
                });
                self.initInputElement(true);
                self.initInputElement(false);
            }
        };
    HtmlInput.prototype.initInputElement = function (multiline) {
   
                    var self = this;
                    //增加1个空的textarea
                    var inputElement;
                    if (multiline) {
                        inputElement = document.createElement("textarea");
                        inputElement.style["resize"] = "none";
                        self._multiElement = inputElement;
                        inputElement.id = "egretTextarea";
                    }
                    else {
                        inputElement = document.createElement("input");
                        self._simpleElement = inputElement;
                        inputElement.id = "egretInput";
                    }
                    inputElement.type = "text";
                    self._inputDIV.appendChild(inputElement);
                    inputElement.setAttribute("tabindex", "-1");
                    inputElement.style.width = "1px";
                    inputElement.style.height = "12px";
                    self.initValue(inputElement);
                    inputElement.style.outline = "thin";
                    inputElement.style.background = "none";
                    inputElement.style.overflow = "hidden";
                    inputElement.style.wordBreak = "break-all";
                    //隐藏输入框
                    inputElement.style.opacity = 0;
                    inputElement.oninput = function () {
   
                        if (self._stageText) {
                            self._stageText._onInput();
                        }
                    };
                };

很明显,是在id为 StageDelegateDiv 的 dom 中嵌入 <input type=”text” ><textarea> ,并在这两个 html 元素上做文章。

1.2 HtmlInput 渲染展现:

那么 text 输入框和 textarea 文本输入域是如何正确展现到 egret 的 canvas 上的呢?
在 egret.web.js 的 egret.web.HTML5StageText 中我们看到如下代码:

             p.$setTextField = function (textfield) {
   
                this.$textfield = textfield;
                return true;
            };
            /**
             * @private
             *
             */
            p.$addToStage = function () {
   
                this.htmlInput = egret.web.$getTextAdapter(this.$textfield);
            };
            /**
             * @private
             *
             */
            p._initElement = function () {
   
                var point = this.$textfield.localToGlobal(0, 0);
                var x = point.x;
                var y = point.y;
                var cX = this.$textfield.$renderMatrix.a;
                var cY = this.$textfield.$renderMatrix.d;
                var scaleX = this.htmlInput.$scaleX;
                var scaleY = this.htmlInput.$scaleY;
                this.inputDiv.style.left = x * scaleX + "px";
                this.inputDiv.style.top = y * scaleY + "px";
                if (this.$textfield.multiline) {
                    this.inputDiv.style.top = (y) * scaleY + "px";
                    this.inputElement.style.top = (-this.$textfield.lineS
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值