UNPKG

ziko-ui

Version:

262 lines (257 loc) 9.47 kB
import { ZikoUIElement, ZikoUIFlex } from "ziko" class ZikoUIMenu3d extends ZikoUIFlex{ constructor(controller, content){ super("div", "menu3d") this.controller = controller; this.content = content; this.cover = null; Object.assign(this.cache,{ config:{ useTransfo : false, isOpen : false, position : "left", threshold : 40, angle : 70, overlap : 6, width : 300, height : 300, transitionDuration: '0.5s', transitionEasing: 'ease', menuTransformOrigin : null, menuTransformClosed : null, menuTransformOpened : null, contentTransformOrigin : null, contentTransformClosed : null, contentTransformOpened : null, } }) this.append( this.controller, this.content ) this.update(); } get isOpen(){ return this.cache.config.isOpen; } update(){ this.controller.style({ display:"none", padding:"20px", overflow:"auto", background:"darkblue", color: "#eee", webkitboxSizing: "border-box", mozBoxSizing: "border-box", boxSizing:"border-box", }); this.content.style({ padding:"20px 40px", width: "100%", height: "100%", // overflowY:"auto", background:"gold", color: "#eee", webkitboxSizing: "border-box", mozBoxSizing: "border-box", boxSizing:"border-box", webkitOverflowScrolling:"touch", webkitTransformStyle: "preserve-3d" }); this.setupPositions(); this.setupWrapper(); this.setupCover() this.setupMenu(); this.setupContent() } setupPositions() { this.cache.config.menuTransformOpened = ''; this.cache.config.contentTransformClosed = ''; let menuAngle = this.cache.config.angle; let contentAngle = this.cache.config.angle / -2; switch( this.cache.config.position ) { case "top": this.cache.config.menuTransformOrigin = '50% 0%'; this.cache.config.menuTransformClosed = `rotateX(${menuAngle}deg) translateY(-100%) translateY(${this.cache.config.overlap}px)` this.cache.config.contentTransformOrigin = '50% 0'; this.cache.config.contentTransformOpened = `translateY(${this.height/2}px) rotateX(${contentAngle}deg)` break; case "right": this.cache.config.menuTransformOrigin = '100% 50%'; this.cache.config.menuTransformClosed = 'rotateY( ' + menuAngle + 'deg ) translateX( 100% ) translateX( -2px ) scale( 1.01 )'; this.cache.config.contentTransformOrigin = '100% 50%'; this.cache.config.contentTransformOpened = 'translateX( -'+ this.width/2 +'px ) rotateY( ' + contentAngle + 'deg )'; break; case "bottom": this.cache.config.menuTransformOrigin = '50% 100%'; this.cache.config.menuTransformClosed = 'rotateX( ' + -menuAngle + 'deg ) translateY( 100% ) translateY( -'+ this.cache.config.overlap +'px )'; this.cache.config.contentTransformOrigin = '50% 100%'; this.cache.config.contentTransformOpened = 'translateY( -'+ this.height/2 +'px ) rotateX( ' + -contentAngle + 'deg )'; break; default: this.cache.config.menuTransformOrigin = '100% 50%'; this.cache.config.menuTransformClosed = 'translateX( -100% ) translateX( '+ this.cache.config.overlap +'px ) scale( 1.01 ) rotateY( ' + -menuAngle + 'deg )'; this.cache.config.contentTransformOrigin = '0 50%'; this.cache.config.contentTransformOpened = 'translateX( '+ this.width/2 +'px ) rotateY( ' + -contentAngle + 'deg )'; break; } } setupWrapper() { this.style({ perspective : "800px", perspectiveOrigin : this.cache.config.contentTransformOrigin }) } setupCover(){ if( this.cover ) this.cover.element.parentNode.removeChild( this.cover.element ); this.cover=new ZikoUIElement("div","div").style({ position:"absolute", display:"block", width:"100%", height:"100%", left:0, top:0, zIndex:1000, visibility:"hidden", opacity:0, transition: `all ${this.cache.config.transitionDuration} ${this.cache.config.transitionEasing}` }) this.content.element.appendChild( this.cover.element ); } setupMenu() { // var style = dom.menu.style; switch( this.cache.config.position ) { case "top": this.controller.style({ width : "100%", height : `${this.height/2}px` });break; case "right": this.controller.style({ right : 0, width : `${this.width/2}px`, height : "100%" });break; case "bottom": this.controller.style({ bottom : "0", width : "100%", height : `${this.height/2}px` });break; case "left": this.controller.style({ width : `${this.width/2}px`, height : "100%" });break; } this.controller.style({ position : "fixed", display : "block", zIndex : 1, transform : this.cache.config.menuTransformClosed, transformOrigin : this.cache.config.menuTransformOrigin, transition : 'all ' + this.cache.config.transitionDuration +' '+ this.cache.config.transitionEasing }) } setupContent() { this.content.style({ transform : this.cache.config.contentTransformClosed, transformOrigin : this.cache.config.contentTransformOrigin, transition : `all ${this.cache.config.transitionDuration} ${this.cache.config.transitionEasing}` }) } open(){ if(!this.cache.config.isOpen){ this.cache.config.isOpen = true; this.cover.style({ height : this.content.element.scrollHeight + "px", visibility : "visible", opacity : 1, }) if(this.cache.config.useTransfo)this.content.style({ transform : this.cache.config.contentTransformOpened, userSelect : "default" }) this.controller.style({ transform : this.cache.config.menuTransformOpened, useSelect : "none" }); this.emit("opened"); } } close() { if( this.cache.config.isOpen ) { this.cache.config.isOpen = false; this.cover.style({ // height : this.content.element.scrollHeight + "px", visibility : "hidden", opacity : 0, }) this.content.style({ transform : this.cache.config.contentTransformClosed, useSelect : "default" }) this.controller.style({ transform : this.cache.config.menuTransformClosed, userSelect : "none" }) } this.emit("closed"); } onOpen(callback){ this.on("opened", callback.bind(this)); return this; } onClose(callback){ this.on("closed", callback.bind(this)); return this; } #usePosition(position){ if(this.cache.config.position!==position){ this.cache.config.position=position; const isOpen = this.isOpen; this.close(); this.update(); if(isOpen)this.open(); } } useRight(){ this.#usePosition("left"); return this; } useRight(){ this.#usePosition("right"); return this; } useTop(){ this.#usePosition("top"); return this; } useBottom(){ this.#usePosition("bottom"); return this; } } const menu3d = (controller, content) => new ZikoUIMenu3d(controller, content); globalThis.menu3d = menu3d; export{ menu3d, ZikoUIMenu3d } /* a = menu3d(Flex(text("Menu")), Flex(text("Content"))) .size("80vw", "50vh") .style({ userSelect: "none" }); a.onOpen((e) => console.log(e)); a.open(); a.controller.onSwipe(0.05, 1, (e) => { if (e.event.detail.direction.x === "left") a.close(); }); a.content.onSwipe(0.1, 1, (e) => { if (e.event.detail.direction.x === "left") a.close(); if (e.event.detail.direction.x === "right") a.open(); }); */