Created
July 31, 2017 08:48
-
-
Save fuunnx/ee3f914c7d8fac1fd65773aa74f6e04b to your computer and use it in GitHub Desktop.
flexible-canvas-component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {addResizeListener} from './resizeListener' | |
import canvasPixelRatio from './pixelRatio' | |
export class FlexibleCanvas extends HTMLDivElement { | |
static get observedAttributes() {return ['width', 'height', 'pixelRatio'] } | |
createdCallback () { | |
this.canvas = this.appendChild(document.createElement('canvas')) //eslint-disable-line | |
this.canvas.setAttribute('style', ` | |
display: block;\ | |
position: absolute;\ | |
top: 0;\ | |
left: 0;\ | |
width: 100%;\ | |
height: 100%;\ | |
overflow: hidden;\ | |
`) | |
this.resizeCb() | |
this.style.overflow = 'hidden' | |
//https://github.com/WebReflection/document-register-element#common-issues--caveat | |
this.disposeResizeListener = addResizeListener( | |
this, | |
this.resizeCb.bind(this), | |
) | |
} | |
disconnectedCallback () { | |
this.disposeResizeListener() | |
} | |
attributeChangedCallback () { | |
this.resizeCb() | |
} | |
disposeResizeListener () {} | |
resizeCb () { | |
const pixelRatio = | |
parseFloat(this.dataset['pixelRatio']) | |
|| canvasPixelRatio | |
this.canvas.getContext('2d').scale(pixelRatio, pixelRatio) | |
this.canvas.width = (this.clientWidth * pixelRatio || this.width) | |
this.canvas.height = (this.clientHeight * pixelRatio || this.height) | |
} | |
} | |
export default FlexibleCanvas |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('document-register-element') | |
const FlexibleCanvas = require('./component').default | |
document.registerElement( | |
'flexible-canvas', | |
FlexibleCanvas, | |
{extends: 'div'}, | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const canvas = document.createElement('canvas') | |
const context = canvas.getContext('2d') | |
// http://www.html5rocks.com/en/tutorials/canvas/hidpi/?redirect_from_locale=fr | |
const devicePixelRatio = window.devicePixelRatio || 1 | |
const backingStoreRatio = context.webkitBackingStorePixelRatio | |
|| context.mozBackingStorePixelRatio | |
|| context.msBackingStorePixelRatio | |
|| context.oBackingStorePixelRatio | |
|| context.backingStorePixelRatio | |
|| 1 | |
const ratio = devicePixelRatio / backingStoreRatio | |
export default ratio |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import insertionQ from 'insertion-query' | |
export const addResizeListener = function (element, onResize) { | |
const resizeEvent = new CustomEvent('resize', {bubbles: true}) | |
const resizeHandler = () => element.dispatchEvent(resizeEvent) | |
const objID = `fnx-resizelistener-${Date.now()}-${randomInt(1000)}` | |
const iframe = document.createElement('iframe') | |
iframe.setAttribute('type', 'text/html') | |
iframe.setAttribute('id', objID) | |
iframe.setAttribute('style', `\ | |
display: block;\ | |
position: absolute;\ | |
top: 0;\ | |
left: 0;\ | |
width: 100%;\ | |
height: 100%;\ | |
overflow: hidden;\ | |
pointer-events: none;\ | |
z-index: -1;\ | |
opacity: 0;\ | |
`) | |
insertionQ.config({strictlyNew: false, timeout: 0}) | |
insertionQ('#' + objID).every(onInsertion) | |
function onInsertion () { | |
const {position, display} = getComputedStyle(element) | |
if (position === 'static') { element.style.position = 'relative' } | |
if (display === 'inline') { element.style.display = 'block' } | |
const contentDocument = iframe.contentDocument | |
? iframe.contentDocument | |
: iframe.contentWindow.document | |
contentDocument.defaultView.addEventListener('resize', resizeHandler) | |
element.addEventListener('resize', onResize) | |
resizeHandler() | |
} | |
setImmediate(() => element.appendChild(iframe)) | |
return function dispose () { | |
const contentDocument = iframe.contentDocument | |
? iframe.contentDocument | |
: iframe.contentWindow.document | |
contentDocument.defaultView.removeEventListener('resize', resizeHandler) | |
element.removeEventListener('resize', onResize) | |
element.removeChild(iframe) | |
} | |
} | |
function randomInt (max) { | |
return Math.round(Math.random() * max) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment