import { html, css } from 'lit'; import { Styles } from '../types/types'; import OlComponent from './OlComponent' import { INNER_RADIUS } from './../constants'; import { dispatchUpdate } from './../state/store'; import { STYLES } from './../styles'; const SCROLL_THRESHOLD = 25; export default class FontFamilyComponent extends OlComponent { onClick: (value: Styles[K]) => void; activeIndex = 0; style: keyof typeof STYLES; styleString = ""; valueMap: any = {}; offset = 50; constructor(style: keyof typeof STYLES, onClick: (value: Styles[K]) => void, styleString = "", valueMap = {}, offset = 50) { super(); this.onClick = onClick; this.offset = offset; this.style = style; this.styleString = styleString; this.valueMap = valueMap; } override styles = css` @keyframes slideOut { 0% { transform: scale(1) translateY(-50%) translateX(calc(-50%)); width: ${INNER_RADIUS * 2}px } 100% { } } .semi-buttons { position: absolute; transform: translateY(-50%) translateX(calc(-${this.offset / 2}px + -50%)); background: white; display: flex; flex-direction: column; box-shadow: 0 0 2px 2px rgba(0,0,0, .2); border-radius: 25px; z-index: -1; height: ${INNER_RADIUS * 2}px; width: ${INNER_RADIUS * 2 + this.offset}px; border-radius: ${INNER_RADIUS}px; align-items: flex-start; justify-content: center; animation-delay: .3s; animation: .3s ease-in-out 0s 1 slideOut; overflow: hidden; } .semi-buttons button { background: transparent; width: ${this.offset}px; max-width: ${this.offset}px; overflow: hidden; border-radius: 0; white-space: nowrap; position: absolute; text-align: center; left: 0; font-size: 12px; transition: all .1s ease-in-out; text-shadow: 1px 1px 1px rgba(0,0,0, .2); } .semi-buttons button:hover { opacity: 1; text-shadow: 3px 3px 3px rgba(0,0,0, .2); } ` renderButtons = () => { const { activeIndex } = this; const values = STYLES[this.style]; const angle = 20; const rotations = values.map((_, i) => angle * (activeIndex - i)); const scales = values.map((_, i) => (1 - (Math.abs(activeIndex - i) * .075))); const opacities = values.map((_, i) => (1 - (Math.abs(activeIndex - i) * .2))); const yOffsets = values.map((_, i) => (i - activeIndex) * (INNER_RADIUS * .45)); return html` ${values.map((value, i) => { return html` ` })} ` } totalOffset = 0; handleScroll = (event: Event) => { if ((event.target as HTMLElement)?.tagName != "OL-PROVIDER") return; const offset = (event as WheelEvent).deltaY; if ((this.activeIndex > 0 && offset < 0) || (this.activeIndex < STYLES[this.style].length - 1 && offset > 0)){ this.totalOffset += offset; } dispatchUpdate("scroll_", this.activeIndex); if (this.totalOffset < -1 * SCROLL_THRESHOLD && this.activeIndex > 0) { this.activeIndex--; this.totalOffset = 0; } else if (this.totalOffset > SCROLL_THRESHOLD && this.activeIndex < STYLES[this.style].length - 1) { this.activeIndex++; this.totalOffset = 0; } } override render() { document.addEventListener('mousewheel', this.handleScroll); return ( html`
${this.renderButtons()}
` ) } }