fridgemagnets/src/fridge-tile.ts

173 lines
6.0 KiB
TypeScript

import { LitElement, html, css } from "lit";
import { customElement } from "lit/decorators/custom-element.js";
import { property } from "lit/decorators/property.js";
import { styleMap } from "lit/directives/style-map.js";
import { ref, createRef, Ref } from "lit/directives/ref.js";
import { LitDraggable } from "./lit-draggable.js";
import { LitDragEvent } from "./types.js";
import { LitDragStart, LitDragEnd } from "./lit-events.js";
@customElement("fridge-tile")
export class FridgeTile extends LitElement {
@property({ type: String })
word = "";
dragHandle: LitDraggable;
transform = {
rotate: Math.random() * 30 - 15,
scale: 1.0,
};
handle: Ref<HTMLDivElement> = createRef();
static get styles() {
return css`
:host {
display: block;
position: absolute;
}
:host([data-dragging="idle"]) {
cursor: grab;
}
:host([data-dragging="dragging"]) {
cursor: grabbing;
}
.word {
font-family: Georgia, Palatino, "Palatino Linotype", Times, "Times New Roman", serif;
box-shadow: 0 0 0.375rem 0.125rem #aaa;
text-align: center;
border-radius: 10%;
user-select: none;
cursor: pointer;
color: #444;
font-size: 0.9375rem;
padding: 0.1875rem 0.25rem 0.25rem 0.25rem;
position: relative;
background: white;
z-index: 100;
transition-property: transform;
transition-duration: 200ms;
transition-timing-function: ease-in-out; //other options are ease
}
.word.dragging {
font-size: 1.1875rem;
}
`;
}
constructor() {
super();
this.dragHandle = new LitDraggable(this);
this.onDragEnd = this.onDragEnd.bind(this);
this.onDragStart = this.onDragStart.bind(this);
this.addEventListener(LitDragEnd.eventName, this.onDragEnd);
this.addEventListener(LitDragStart.eventName, this.onDragStart);
}
onDragEnd(ev: LitDragEvent) {
this.transform = { scale: 1.0, rotate: Math.random() * 30 - 15 };
this.handle.value!.style.setProperty(
"transform",
`scale(${+this.transform.scale}) rotate(${+this.transform.rotate}deg)`
);
this.style.setProperty("top", `${+ev.offsetY}px`);
this.style.setProperty("left", `${+ev.offsetX}px`);
}
onDragStart(_ev: LitDragEvent) {
this.transform = { scale: 1.3, rotate: Math.random() * 30 - 15 };
this.handle.value!.style.setProperty(
"transform",
`scale(${+this.transform.scale}) rotate(${+this.transform.rotate}deg)`
);
}
render() {
const styles = {
width: `${this.word.length * 1.2}ch`,
transform: `rotate(${this.transform.rotate}deg)`,
};
return html`<div part="word ${ref(this.handle)} " style="${styleMap(styles)}" class="word">${this.word}</div>`;
}
}
//
// base_style:
// 'font-size': "15px"
//
// drag_style:
// 'font-size': "19px"
//
// visible: false
//
// # Initial tilt.
// rotation: (Math.random() * 30) - 15
//
// constructor: (@word, @board, @master) ->
// super()
// @el = $('<div class="word">' + @word.w + '</div>')
// @el.css @base_style
// @board.append(@el)
// @rotation = (Math.random() * 30) - 15
//
// @el.draggable
// helper: "original"
// refreshPositions: false
// revertDuration: 1
//
// start: (event) =>
// mod = (Math.random() * 16) - 8
// @rotation = if Math.abs(@rotation + mod) > 15 then @rotation - mod else @rotation + mod
// style = clone(@drag_style)
// style.rotate = @rotation
// @el.animate(style, 200, () => @new_width = @el.width())
// true
//
// stop: (event) =>
// # Drop the thing dead center, at least on the x-axis,
// # and animate its return to the new font size.
// mod = (Math.random() * 16) - 8
// @rotation = if Math.abs(@rotation + mod) > 15 then @rotation - mod else @rotation + mod
// style = clone(@base_style)
// style.rotate = @rotation
// style['left'] = parseInt(@el.position().left + (0.5 * (@new_width - @width())))
// @el.animate style, 200, 'easeOutQuad', () =>
// @reset_dims()
// explode_hearts(@board, @)
// @master.poemed(@)
// true
//
// fadeOut: -> $.Deferred((d) => @el.fadeOut('fast', (() => @unset_dims(); @visible = false; d.resolve()))).promise()
//
// # Shape for deteriming poemed collision
// fuzzyshape: -> shape @left() - WIDTH_FUZZ, @top() - HEIGHT_FUZZ, @width() + (2 * WIDTH_FUZZ), @height() + (2 * HEIGHT_FUZZ)
//
// get_new_pos: ->
// bh = => parseInt(Math.random() * (@board.height() - @height()) * 0.985)
// bw = => parseInt(Math.random() * (@board.width() - @width()) * 0.98)
// [top, left] = [bh(), bw()]
// [top, left] = [bh(), bw()] until @master.unoccupied(left, top, @width(), @height())
// [top, left]
//
// flyIn: ->
// fd = (mod) ->
// m = parseInt(40 * Math.random())
// if (Math.random() < 0.5) then mod + m else -1 * m
// @el.css
// left: fd(@board.width())
// top: fd(@board.height())
// dfd = $.Deferred()
// x = Math.random()
// [top, left] = @get_new_pos()
// @el.fadeIn().animate {top: top, left: left, rotate: @rotation}, 1500, 'easeOutQuint', () =>
// @visible = true
// dfd.resolve()
// dfd.promise()
//
//