Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions src/renderview.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,29 @@ div.renderview-wrapper .renderview-top {
align-items: center;
}

div.renderview-wrapper .renderview-top span {
div.renderview-wrapper .renderview-title {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-left: 0.5em;
margin-left: 0.5em;
flex: 1;
}

div.renderview-wrapper .renderview-button {
display: none;
flex: 0;
padding: 0 0.3em;
border-radius: 5px;
cursor: pointer;
}

div.renderview-wrapper .renderview-button:hover {
background: var(--line-color);
}

div.renderview-wrapper .renderview-button:last-child {
margin-right: 0.2em;
}

div.renderview-wrapper .renderview-resizer {
Expand Down Expand Up @@ -79,4 +96,17 @@ div.renderview-wrapper.has-titlebar .renderview-top {

div.renderview-wrapper.is-resizable .renderview-resizer {
display: block;
}

div.renderview-wrapper.is-minimizable .renderview-minimize-button {
display: inline-block;
}

div.renderview-wrapper.is-minimized {
height: 0 !important;
min-height: 0 !important;
}

div.renderview-wrapper.is-closable .renderview-close-button {
display: inline-block;
}
76 changes: 62 additions & 14 deletions src/renderview.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class BaseRenderView {
this._lsize = null // cached logical size
this._wheelThrottle = 20 // to avoid flooding wheel events
this._moveThrottle = 20 // to avoid flooding move events
this._isVisible = false // set by intersection observer
this._isVisible = 0 // bitmask: 1->intersected, 2->nonzerosize

this._focusElement = null
this._abortController = new AbortController()
Expand Down Expand Up @@ -173,8 +173,12 @@ class BaseRenderView {
this.viewElement = null
this.sizeElement = null
this.titleElement = null
this.butCloseElement = null
if (this.wrapperElement) {
this.wrapperElement.innerHTML = ''
this.wrapperElement.classList.remove('renderview-wrapper')
this.wrapperElement.style.width = ''
this.wrapperElement.style.height = ''
this.wrapperElement = null
}
const event = {
Expand Down Expand Up @@ -289,6 +293,25 @@ class BaseRenderView {
*/
onEvent (event) { }

/**
* Internal method to handle visibility.
*/
_updateVisibleBitmask (i, bitValue) {
const wasVisible = this._isVisible === 3
if (bitValue) { this._isVisible |= i } else { this._isVisible &= (~i) }
const nowVisible = this._isVisible === 3
if (nowVisible !== wasVisible) {
if (!nowVisible) {
this._focusElement.blur()
}
const event = {
type: nowVisible ? 'show' : 'hide',
timestamp: getTimestamp()
}
this.onEvent(event)
}
}

/**
* Internal method to initialize the view's helper elements.
*/
Expand Down Expand Up @@ -343,10 +366,18 @@ class BaseRenderView {
// Create title bar
const topElement = document.createElement('div')
topElement.classList.add('renderview-top')
const titleElement = document.createElement('span')
this.titleElement = titleElement
titleElement.innerText = 'RenderView'
topElement.appendChild(titleElement)
this.titleElement = document.createElement('span')
this.titleElement.innerText = 'RenderView'
this.titleElement.classList.add('renderview-title')
this.butMinimizeElement = document.createElement('span')
this.butMinimizeElement.innerText = '_'
this.butMinimizeElement.classList.add('renderview-button', 'renderview-minimize-button')
this.butCloseElement = document.createElement('span')
this.butCloseElement.innerText = '×'
this.butCloseElement.classList.add('renderview-button', 'renderview-close-button')
topElement.appendChild(this.titleElement)
topElement.appendChild(this.butMinimizeElement)
topElement.appendChild(this.butCloseElement)
wrapperElement.appendChild(topElement)

// Enable resizing
Expand Down Expand Up @@ -389,7 +420,7 @@ class BaseRenderView {
const viewElement = this.viewElement
const signal = this._abortController.signal // to unregister/abort stuff

// ----- visibility and focus ---------------
// ----- visibility and focus and closing ---------------

this._intersectionObserver = new IntersectionObserver((entries, observer) => {
// This gets called when one of the observed elements becomes visible/invisible.
Expand All @@ -398,14 +429,7 @@ class BaseRenderView {
for (const entry of entries) {
isVisible = isVisible || entry.isIntersecting
}
if (isVisible !== this._isVisible) {
this._isVisible = isVisible
const event = {
type: isVisible ? 'show' : 'hide',
timestamp: getTimestamp()
}
this.onEvent(event)
}
this._updateVisibleBitmask(1, isVisible) // 1 for intersection bit
})
this._intersectionObserver.observe(viewElement)

Expand All @@ -426,6 +450,22 @@ class BaseRenderView {
{ signal }
)

if (this.butMinimizeElement) {
this.butMinimizeElement.addEventListener('click', (ev) => {
this.wrapperElement.classList.toggle('is-minimized')
},
{ signal }
)
}

if (this.butCloseElement) {
this.butCloseElement.addEventListener('click', (ev) => {
this.close()
},
{ signal }
)
}

// ----- resize ---------------

this._resizeObserver = new ResizeObserver((entries) => {
Expand Down Expand Up @@ -462,6 +502,14 @@ class BaseRenderView {
physicalHeight = Math.floor(lsize[1] * ratio)
}

// Handle visibility. If zero-size we assume we're minimized or otherwise hidden; zero size is not valid.
if (!physicalHeight || !physicalWidth) {
this._updateVisibleBitmask(2, false) // 2 for non-zero-size bit
return
} else {
this._updateVisibleBitmask(2, true)
}

// If the container element does not have its size set via its style, we set it to the logical size.
const logicalWidth = physicalWidth / ratio
const logicalHeight = physicalHeight / ratio
Expand Down
3 changes: 2 additions & 1 deletion src/tester.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@

draw() {
this._drawRequested = false
if (!this.viewElement) { return } // closed

const ctx = this.viewElement.getContext('2d') // CanvasRenderingContext2D
ctx.fillStyle = '#abc'
Expand Down Expand Up @@ -121,7 +122,7 @@ <h2>Plain canvas</h2>
<canvas id='canvas1' style='width: 100%; height: 480px; background: #aaa;'></canvas>

<h2>Canvas with wrapper</h2>
<div id='canvas2' class='renderview-wrapper has-titlebar is-resizable'
<div id='canvas2' class='renderview-wrapper has-titlebar is-resizable is-minimizable is-closable'
style='width: 800px; height: 480px; background: #aaa'>
Loading ...
</div>
Expand Down
Loading