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