UNPKG

hengine

Version:

A simple graphic engine for `canvasom`.

119 lines (114 loc) 5.92 kB
import { CanvasNode, CanvasRoot, Schedule, Event } from 'canvasom'; var t;!function(t){t.fill=t=>{const{paddingLeft:i,paddingTop:e}=t;return {width:t.containerWidth-i-t.paddingRight,height:t.containerHeight-e-t.paddingBottom,left:i,top:e,scale:1}},t.fixedWidth=t=>{const{targetWidth:i,paddingLeft:e,paddingTop:n}=t,d=t.containerWidth-e-t.paddingRight;return {width:d,height:t.containerHeight-n-t.paddingBottom,left:e,top:n,scale:d/i}},t.fixedHeight=t=>{const{targetHeight:i,paddingLeft:e,paddingTop:n}=t,d=t.containerWidth-e-t.paddingRight,a=t.containerHeight-n-t.paddingBottom;return {width:d,height:a,left:e,top:n,scale:a/i}},t.semifixed=i=>{const{targetWidth:e,targetHeight:n,paddingLeft:d,paddingTop:a}=i;return (i.containerWidth-d-i.paddingRight)/(i.containerHeight-a-i.paddingBottom)<e/n?t.fixedWidth(i):t.fixedHeight(i)},t.contain=t=>{const{targetWidth:i,targetHeight:e,paddingLeft:n,paddingTop:d}=t,a=t.containerWidth-n-t.paddingRight,h=t.containerHeight-d-t.paddingBottom;if(a/h<i/e){const t=a/i,g=e*t;return {width:a,height:g,left:n,top:(h-g)/2+d,scale:t}}{const t=h/e,g=i*t;return {width:g,height:h,left:(a-g)/2+n,top:d,scale:t}}},t.center=t=>{const{targetWidth:i,targetHeight:e,paddingLeft:n,paddingTop:d}=t;return {width:i,height:e,left:(t.containerWidth-n-t.paddingRight-i)/2+n,top:(t.containerHeight-d-t.paddingBottom-e)/2+d,scale:1}};}(t||(t={}));class Resizer{constructor(i){const e=i?.target||null;this.target=e,this.container=i?.container??(e&&e.parentElement);const n=i?.padding??0;this.paddingTop=i?.paddingTop??n,this.paddingRight=i?.paddingRight??n,this.paddingBottom=i?.paddingBottom??n,this.paddingLeft=i?.paddingLeft??n,this.active=i?.active??!0,this.width=i?.width??0,this.height=i?.height??0,this.sizing=i?.sizing??t.center,this.callback=i?.callback||null,this.updateSync=this.updateSync.bind(this),this.onResize=this.onResize.bind(this),this.update=((t,i)=>{let e=null;const debounceWrapper=(...t)=>{null!==e&&clearTimeout(e),e=setTimeout(i,debounceWrapper.debounceTimeout,...t);};return debounceWrapper.debounceTimeout=t,debounceWrapper})(100,this.updateSync),!1!==i?.autoResize&&(window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize)),this.active&&this.update();}active;target;container;width;height;sizing;paddingTop;paddingRight;paddingBottom;paddingLeft;callback;updateSync(t){const{target:i,container:e}=this;if(!this.active||!i||!e)return;const{style:n}=i,d=e.getBoundingClientRect(),a=this.sizing({containerWidth:d.width,containerHeight:d.height,paddingTop:this.paddingTop,paddingRight:this.paddingRight,paddingBottom:this.paddingBottom,paddingLeft:this.paddingLeft,targetWidth:this.width,targetHeight:this.height});n.width=a.width+"px",n.height=a.height+"px",n.marginLeft=a.left+"px",n.marginTop=a.top+"px",this.callback?.(a),t?.(a);}update;onResize(){this.update();}} /** dts2md break */ /** * Class of scene nodes. */ class SceneNode extends CanvasNode { /** dts2md break */ /** * Constructor of {@link SceneNode}. */ constructor(options) { super({ stretch: 1, penetrable: true, ...options, }); } } /** dts2md break */ /** * Class of canvas engines. */ class CanvasEngine extends CanvasRoot { /** dts2md break */ /** * Constructor of {@link CanvasEngine}. */ constructor(options) { super(options); this.onResize = this.onResize.bind(this); const resizerOptions = { width: this.renderer.width, height: this.renderer.height, target: this.renderer.canvas, sizing: t.contain, callback: this.onResize, }; if (options?.resizerOptions) { Object.assign(resizerOptions, options.resizerOptions); } this.resizer = new Resizer(resizerOptions); this.renderer.autoStyle = false; } /** dts2md break */ /** * The resizer in use. */ resizer; /** dts2md break */ /** * Current scene. */ currentScene = null; /** dts2md break */ /** * Resize callback. * (Remember to invoke this in your implemention * of `resizer.callback` if you have one.) */ onResize(result) { const { scale } = result; this.renderer.resize(result.width / scale, result.height / scale); Schedule.updateAndRender(this); } /** dts2md break */ /** * Enter specific scene. * (Pass `null` to exit current scene * without entering another scene.) * @returns Whether the scene change is successful. */ enter(nextScene) { const { currentScene } = this; if (currentScene) { const exitEvent = new Event({ name: 'exit', stoppable: true, cancelable: true, data: { nextScene, }, }); currentScene.emit(exitEvent); if (exitEvent.canceled) { return false; } } if (nextScene) { const enterEvent = new Event({ name: 'enter', stoppable: true, cancelable: true, data: { currentScene, }, }); nextScene.emit(enterEvent); if (enterEvent.canceled) { return false; } this.appendChild(nextScene); } if (currentScene) { this.removeChild(currentScene); } this.currentScene = nextScene; if (currentScene || nextScene) { Schedule.updateAndRender(this); } return true; } } export { CanvasEngine, Resizer, SceneNode, t as Sizing };