Hello!
We have embedded our PlayCanvas app to iframe in page.
Because of iPhone fullscreen incompatibility, we made pseudo-fullscreen. We just resize canvas to fill the page and vice versa.
Our solution works perfectly on:
- Desktop
- Android
- iOS 13 and earlier
Except iOS 14: it enables and disable pseudo-fullscreen for the first time, but when you click fullscreen button again, Safari refreshes the page.
Demo video
fullscreen-button.js:
var FullscreenButton = pc.createScript('fullscreenButton');
// Properties
FullscreenButton.attributes.add("debug", { type: 'boolean', default: false });
FullscreenButton.attributes.add("eventName", { type: 'string', default: "click" });
FullscreenButton.attributes.add("htmlIDs", { type: 'string', array: true });
FullscreenButton.prototype.fullscreen = false;
FullscreenButton.prototype.parentFrame = null;
FullscreenButton.prototype.defaultStyle = null;
// initialize code called once per entity
FullscreenButton.prototype.postInitialize = function() {
DebugHelper.printDebugMessage(this, "postInitialize");
this.setupEvents();
};
// Event handlers initialization
FullscreenButton.prototype.setupEvents = function() {
DebugHelper.printDebugMessage(this, "setupEvents");
if (this.entity.script.htmlRedirector) {
this.entity.script.htmlRedirector.setupEventListeners(this, this.eventName, this.htmlIDs, this.onPress);
} else {
this.entity.element.on(eventName, this.onPress, this);
}
this.app.graphicsDevice.on("resizecanvas", this.onResizeCanvas, this);
// TODO Move to another method
this.parentFrame = window.parent.document.getElementsByTagName("iframe")[0];
if (this.parentFrame) {
this.defaultStyle = this.parentFrame.style.cssText;
}
};
// Event handlers destroying
FullscreenButton.prototype.clearEvents = function() {
DebugHelper.printDebugMessage(this, "clearEvents");
if (this.entity.script.htmlRedirector) {
this.entity.script.htmlRedirector.removeEventListeners(this, this.eventName, this.htmlIDs, this.onPress);
} else {
this.entity.element.on(eventName, this.onPress, this);
}
this.app.graphicsDevice.off("resizecanvas", this.onResizeCanvas, this);
};
// Event handlers
FullscreenButton.prototype.onPress = function() {
DebugHelper.printDebugMessage(this, "onPress");
if (!this.fullscreen) {
if (this.parentFrame) {
this.parentFrame.style.cssText = "position: absolute; width: 100%; height: 100%; margin: 0px; top: 0px; right: 0px; left: 0px; bottom: 0px;";
} else if (!pc.platform.ios) {
document.documentElement.requestFullscreen();
}
} else {
if (this.parentFrame) {
this.parentFrame.style.cssText = this.defaultStyle;
} else if (!pc.platform.ios) {
document.exitFullscreen();
}
}
this.fullscreen = !this.fullscreen;
};
FullscreenButton.prototype.onResizeCanvas = function(width, height) {
DebugHelper.printDebugMessage(this, "onResizeCanvas");
document.getElementById("application-canvas").width = document.body.clientWidth;
document.getElementById("application-canvas").height = document.body.clientHeight;
DebugHelper.printDebugMessage(this, "onResizeCanvas: ", document.getElementById("application-canvas").width, document.getElementById("application-canvas").height, width, height);
};
// Hot reloading
FullscreenButton.prototype.swap = function(old) {
DebugHelper.printDebugMessage(this, "hot reloading");
this.setupEvents();
old.clearEvents();
};
index.html:
<!DOCTYPE html>
<html>
<head> </head>
<body>
<iframe
src="app.html"
frameborder="0"
style="width: 590px; height: 520px; right: 20%;"
></iframe>
</body>
</html>
app.html:
<!doctype html>
<html>
<head>
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no' />
<meta charset='utf-8'>
<link rel="stylesheet" type="text/css" href="styles.css">
<link rel="manifest" href="manifest.json">
<style></style>
<title>apartment_127</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="playcanvas-stable.min.js"></script>
<script src="__settings__.js"></script>
</head>
<body>
<iframe src="splash.html" id="splash-container" frameborder="0"></iframe>
<script src="__modules__.js"></script>
<script src="__start__.js"></script>
<script src="__loading__.js"></script>
</body>
</html>
What’s the problem?