meta-next
Version:
189 lines (147 loc) • 4.13 kB
JavaScript
import Engine from "./Engine"
import Device from "./Device"
import Time from "./Time"
import Resources from "./resources/Resources"
class EngineWindow
{
constructor()
{
this.width = 0
this.height = 0
this.offsetLeft = 0
this.offsetTop = 0
this.ratio = 1
this.scaleX = 1
this.scaleY = 1
this._cursor = "auto"
}
create()
{
const container = document.createElement("div")
container.style.cssText = "position:absolute; width:100%; height:100%; background: #222; display:flex; align-items:center; justify-content:center;"
const canvas = document.createElement("canvas")
const gl = canvas.getContext("webgl", { antialias: Engine.settings.antialias })
if(!gl) {
console.error("Unable to initialize WebGL. Your browser or machine may not support it.")
return
}
container.appendChild(canvas)
document.body.appendChild(container)
Engine.container = container
Engine.canvas = canvas
Engine.gl = gl
this.setupWebGL()
Engine.emit("setup")
if(Engine.app.setup) {
Engine.app.setup()
}
this.updateScreenSize()
Device.on("resize", this.updateScreenSize.bind(this))
this.readyFunc = this.ready.bind(this)
this.updateFunc = this.update.bind(this)
this.renderFunc = this.render.bind(this)
Resources.on("ready", this.readyFunc)
if(!Resources.loading) {
this.ready()
}
}
setupWebGL()
{
const gl = Engine.gl
gl.clearColor(0.0, 0.0, 0.0, 1.0)
gl.clearDepth(1.0)
gl.enable(gl.DEPTH_TEST)
gl.depthFunc(gl.LEQUAL)
gl.enable(gl.BLEND)
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
}
updateScreenSize()
{
const settings = Engine.settings
const container = Engine.container
const canvas = Engine.canvas
const targetWidth = settings.width ? settings.width : window.innerWidth
const targetHeight = settings.height ? settings.height : window.innerHeight
const widthRatio = window.innerWidth / targetWidth
const heightRatio = window.innerHeight / targetHeight
const currRatio = (widthRatio < heightRatio) ? widthRatio : heightRatio
let ratio
if(settings.upscale) {
ratio = currRatio
}
else {
ratio = (currRatio > 1.0) ? 1.0 : currRatio
}
this.width = targetWidth
this.height = targetHeight
canvas.width = targetWidth
canvas.height = targetHeight
canvas.style.width = `${targetWidth * ratio}px`
canvas.style.height = `${targetHeight * ratio}px`
Engine.gl.viewport(0, 0, targetWidth, targetHeight)
this.updateOffset()
Engine.camera.updateProjectionTransform()
}
updateOffset()
{
this.offsetLeft = 0
this.offsetTop = 0
let element = Engine.container
if(element.offsetParent)
{
do {
this.offsetLeft += element.offsetLeft
this.offsetTop += element.offsetTop
} while(element = element.offsetParent);
}
let rect = Engine.container.getBoundingClientRect()
this.offsetLeft += rect.left
this.offsetTop += rect.top
rect = Engine.canvas.getBoundingClientRect()
this.offsetLeft += rect.left
this.offsetTop += rect.top
}
ready()
{
Resources.off("ready", this.readyFunc)
if(Engine.app.ready) {
Engine.app.ready()
}
this.render()
setInterval(this.updateFunc, 1.0 / 60.0)
}
update()
{
Time.start()
if(Engine.app.update) {
Engine.app.update(Time.deltaF)
}
Time.end()
}
render()
{
const gl = Engine.gl
Time.startRender()
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
if(Engine.app.render) {
Engine.app.render()
}
Time.endRender()
requestAnimationFrame(this.renderFunc)
}
background(r, g, b) {
const weight = 1 / 255
Engine.gl.clearColor(r * weight, g * weight, b * weight, 1.0)
}
set cursor(type)
{
if(this._cursor === type) { return }
this._cursor = type
document.body.style.cursor = type
}
get cursor() {
return this._cursor
}
}
export default EngineWindow