173 lines
6.0 KiB
TypeScript
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()
|
|
//
|
|
//
|