全屏并在Dart中按名称检索属性

时间:2016-09-02 20:46:58

标签: html canvas properties dart

我正在使用Dart制作全屏HTML5画布。遗憾的是,每个浏览器都有Fullscreen API的另一个前缀版本,Dart没有跟踪它。因此大多数时候Dart提供的方法都不起作用。 我发现这个“黑客”进入全屏工作非常好:

JsObject canvasElement = new JsObject.fromBrowserObject(_canvas);

List<String> methods = ["requestFullscreen", "mozRequestFullScreen", "webkitRequestFullscreen", "msRequestFullscreen"];
for(String method in methods){
  if(canvasElement.hasProperty(method)){
    canvasElement.callMethod(method);
    _canvas.width = window.screen.width;
    _canvas.height = window.screen.height;
    return;
  }
}

我的问题如下: 按“Escape”或“F11”时,全屏将关闭,但画布不会调整大小恢复正常大小。我尝试手动覆盖此键的KeyDown事件,但似乎我的浏览器(Google Chrome / Dartium)在这种特殊情况下无法识别事件...

显然,我需要知道浏览器是否处于全屏模式,以便相应地调整画布大小。有没有办法像Fullscreen API docs那样以类似于我可以访问方法document.fullscreenElement, document.webkitFullscreenElement, document.msFullscreenElement的方式检索javascript属性document.requestFullscreen, document.webkitRequestFullscreen etc.

非常感谢你的帮助......

1 个答案:

答案 0 :(得分:2)

我现在就开始工作吧。我将在这里写一个答案,因此有类似问题的人可能会找到解决方案:

您可以像this answer中所述,在dart中访问全屏API的大多数供应商特定方法。确实有一种方法可以访问属性,如果它们存在,你可以在上面提到的答案中提供的最低代码方法中看到...

在按F11或Esc切换全屏模式时,我对浏览器没有抛出keydown事件是对的。我了解到这可以通过调用event.preventDefault()然后手动切换全屏来防止。我的全屏管理的完整源代码如下所示:

void init(){
    ....

    // initiate variables needed for fullscreen management
    _fullscreenTimer = new DateTime.now().millisecondsSinceEpoch;
    _fullscreen = false;

    // setup event handler, thus pressing F11 toggles fullscreen
    window.onKeyDown.listen((KeyEvent e) {
        if (e.keyCode == KeyCode.F11) {
        // prevent going fullscreen without noticing
        e.preventDefault();

        // get current time
        int now = new DateTime.now().millisecondsSinceEpoch;

        // only toggle fullscreen when last toggle was at least 500ms before
        if ((now - _fullscreenTimer) >= 500) {
            // toggle fullscreen
            if (!_fullscreen) {
                _requestFullscreen();
            } else {
                _exitFullscreen();
            }

            // reset timer to current time
            _fullscreenTimer = now;
            }
        }
    });
}

void resize() {
    // the element currently in fullscreen mode
    var fullscreenElement = _getFullscreenElement();

    // check whether there was a change to or from fullscreen
    if (!_fullscreen && fullscreenElement != null) {
        _fullscreen = true;

        _canvas.width = window.screen.width;
        _canvas.height = window.screen.height;
    } else if (_fullscreen && fullscreenElement == null) {
        _fullscreen = false;

        _canvas.width = _originalWidth;
        _canvas.height = _originalHeight;
    }
}

/// requests fullscreen by calling the corresponding methods of each vendor
void _requestFullscreen() {
    _callMethods(_canvas, ['requestFullscreen', 'webkitRequestFullscreen', 'mozRequestFullScreen', 'msRequestFullscreen', 'oRequestFullscreen']);
}

/// exits fullscreen by calling the corresponding methods of each vendor
void _exitFullscreen() {
    _callMethods(document, ['exitFullscreen', 'webkitExitFullscreen', 'mozCancelFullScreen', 'msExitFullscreen', 'oExitFullscreen']);
}

/// checks whether fullscreen is active by getting the corresponding property of each vendor
dynamic _getFullscreenElement() {
    return _getProperty(document, ['fullscreenElement', 'webkitFullscreenElement', 'mozFullScreenElement', 'msFullscreenElement', 'oFullscreenElement']);
}

/// calls the first matching method of a browser object
dynamic _callMethods(dynamic browserObject, List<String> methods) {
    JsObject js = new JsObject.fromBrowserObject(browserObject);

    for (String method in methods) {
      if (js.hasProperty(method)) {
        return js.callMethod(method);
      }
    }

    return null;
}

/// retrieves the first matching property of a browser object
dynamic _getProperty(dynamic browserObject, List<String> properties) {
    JsObject js = new JsObject.fromBrowserObject(browserObject);

    for (String property in properties) {
        if (js.hasProperty(property)) {
            return js[property];
        }
    }

    return null;
}