Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
mhmo91 committed Jan 12, 2025
1 parent fde43a9 commit 32e123c
Show file tree
Hide file tree
Showing 28 changed files with 3,494 additions and 1,345 deletions.
3,615 changes: 2,895 additions & 720 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mhmo91/schmancy",
"version": "0.0.283",
"version": "0.0.284",
"description": "UI library build with web components",
"main": "./dist/index.js",
"repository": {
Expand Down Expand Up @@ -31,8 +31,6 @@
"build": "tsc && vite build --config vite.config.ts",
"preview": "vite preview",
"batch": "npm version patch",
"prepare": "husky install",
"build:components": "wca ./src --format json --outFile ./hummingbird/src/toolkit/components.json",
"watch": "npm-watch build:components"
},
"author": "@mhmo91",
Expand All @@ -53,8 +51,9 @@
"@types/cleave.js": "^1.4.12",
"cleave.js": "^1.6.0",
"fastest-levenshtein": "^1.0.16",
"lit": "^3.2.1",
"lit": "^3.2.0",
"moment": "^2.30.1",
"playground-elements": "^0.19.1",
"rxjs": "latest",
"tippy.js": "^6.3.7",
"ts-is-present": "^1.2.2",
Expand All @@ -71,7 +70,6 @@
"autoprefixer": "^10.4.20",
"deepmerge": "^4.3.1",
"eslint": "^9.17.0",
"husky": "^9.1.7",
"postcss": "^8.4.49",
"prettier": "^3.4.2",
"rollup-plugin-copy": "^3.5.0",
Expand Down
2 changes: 0 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ Below is a table linking to each component’s documentation on the GitHub Wiki:

| Component | Description | Documentation |
| ------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------- |
| `schmancy-animate` | Animation component | [Wiki - schmancy-animate](https://github.com/mhmo91/schmancy/wiki/schmancy-animate) |
| `schmancy-animated-text` | Animated text component | [Wiki - schmancy-animated-text](https://github.com/mhmo91/schmancy/wiki/schmancy-animated-text) |
| `schmancy-area` | Area component | [Wiki - schmancy-area](https://github.com/mhmo91/schmancy/wiki/schmancy-area) |
| `schmancy-autocomplete` | Autocomplete field | [Wiki - schmancy-autocomplete](https://github.com/mhmo91/schmancy/wiki/schmancy-autocomplete) |
| `schmancy-busy` | Loading/busy indicator | [Wiki - schmancy-busy](https://github.com/mhmo91/schmancy/wiki/schmancy-busy) |
Expand Down
55 changes: 0 additions & 55 deletions src/animate/animate.component.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/animate/index.ts

This file was deleted.

79 changes: 0 additions & 79 deletions src/animate/readme.md

This file was deleted.

104 changes: 67 additions & 37 deletions src/animated-text/animated-text.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createTimeline, stagger } from '@packages/anime-beta-master'
// Removed: import { createTimeline, stagger } from '@packages/anime-beta-master'
import { $LitElement } from '@mixins/index'
import { css, html } from 'lit'
import { customElement, property, query, queryAssignedNodes } from 'lit/decorators.js'
Expand All @@ -14,11 +14,11 @@ import {
tap,
throttleTime,
} from 'rxjs'

/**
* @element schmancy-animated-text
* Inspired by https://tobiasahlin.com/moving-letters/#1
*/

@customElement('schmancy-animated-text')
export default class SchmancyAnimatedText extends $LitElement(css`
:host {
Expand All @@ -40,14 +40,14 @@ export default class SchmancyAnimatedText extends $LitElement(css`
opacity: 0;
}
`) {
@property({ type: String }) ease = 'outExpo'
@property({ type: String }) ease = 'outExpo' // not a built-in string for Web Animations
@property({ type: Number }) delay = 0
@property({ type: Number }) stagger = 50
@property({ type: Number }) duration = 750
@property({ type: Array }) scale = [0, 1]
@property({ type: Array }) opacity = [0, 1]
@property({ type: Array }) translateX = ['0.55em', 0]
@property({ type: Array }) translateY = ['1.1em', 0]
@property({ type: Array }) translateX = ['0.55em', '0em']
@property({ type: Array }) translateY = ['1.1em', '0em']
@property({ type: Array }) translateZ = [0, 0]
@property({ type: Array }) rotateZ = [180, 0]
@property({ type: Boolean }) resetOnScroll = true
Expand All @@ -57,7 +57,7 @@ export default class SchmancyAnimatedText extends $LitElement(css`
@query('.ml7') ml7!: HTMLElement

// Function to check if an element is in the viewport
isInViewport(element) {
isInViewport(element: HTMLElement) {
const rect = element.getBoundingClientRect()
return (
rect.top >= 0 &&
Expand All @@ -68,9 +68,12 @@ export default class SchmancyAnimatedText extends $LitElement(css`
}

async firstUpdated() {
this.letters.innerHTML = this.defaultSlot[0].textContent.replace(/\S/g, "<span class='letter'>$&</span>")
// Split the text into <span class="letter"> ... </span> elements
this.letters.innerHTML = this.defaultSlot[0].textContent!.replace(/\S/g, `<span class="letter">$&</span>`)

// Observe viewport + initial readiness
concat(
// 1) Wait until the element is rendered (width/height > 0)
interval(10).pipe(
startWith(true),
filter(() => {
Expand All @@ -79,52 +82,79 @@ export default class SchmancyAnimatedText extends $LitElement(css`
}),
take(1),
),
// 2) Then handle scroll events, throttled
fromEvent(window, 'scroll').pipe(
// pipe to only emit when the element has getBoundingClientRect() in viewport
throttleTime(0, undefined, {
leading: true,
trailing: true,
}), // Throttle the events to improve performance
startWith(true), // Emit an event on subscription
map(() => this.isInViewport(this)), // Filter events where the element is in viewport
distinctUntilChanged(), // Only emit when the value has changed
tap(inViewPort => {
if (!inViewPort)
Array.from(this.letters.children).forEach((letter: HTMLElement) => (letter.style.opacity = '0'))
}),
startWith(true),
map(() => this.isInViewport(this)),
distinctUntilChanged(),
tap(inViewport => {
// If leaving viewport and `resetOnScroll` is true, reset letters to opacity 0
if (!inViewport && this.resetOnScroll) {
Array.from(this.letters.children).forEach((letter: HTMLElement) => {
letter.style.opacity = '0'
})
}
}),
filter(isInViewport => isInViewport),
this.resetOnScroll ? tap(() => {}) : take(1),

// If resetOnScroll = false, animate only the first time inView. If true, repeat.
this.resetOnScroll ? tap() : take(1),
tap({
next: () => {
// Wrap every letter in a span
createTimeline().add(
this.shadowRoot.querySelectorAll('.ml7 .letter'),
{
translateY: this.translateY,
translateX: this.translateX,
opacity: this.opacity,
translateZ: this.translateZ,
rotateZ: this.rotateZ,
// Animate letters with the native Web Animations API
const letters = this.shadowRoot!.querySelectorAll<HTMLElement>('.ml7 .letter')

letters.forEach((letter, i) => {
// Combine all transforms into one CSS transform string
// From
const fromTransform = `
translate3d(${this.translateX[0]}, ${this.translateY[0]}, ${this.translateZ[0]}px)
rotateZ(${this.rotateZ[0]}deg)
scale(${this.scale[0]})
`
// To
const toTransform = `
translate3d(${this.translateX[1]}, ${this.translateY[1]}, ${this.translateZ[1]}px)
rotateZ(${this.rotateZ[1]}deg)
scale(${this.scale[1]})
`
// Approximate `outExpo` or pick a standard easing (like 'ease-out'):
// outExpo often approximated by cubic-bezier(0.19, 1, 0.22, 1)
const easingMap: Record<string, string> = {
outExpo: 'cubic-bezier(0.19, 1, 0.22, 1)',
// add more if you want
}
const keyframes: Keyframe[] = [
{ transform: fromTransform, opacity: String(this.opacity[0]) },
{ transform: toTransform, opacity: String(this.opacity[1]) },
]

letter.animate(keyframes, {
duration: this.duration,
delay: this.delay,
onBegin: () => {},
},
stagger(this.stagger),
)
easing: easingMap[this.ease] || 'ease-out',
delay: this.delay + i * this.stagger, // staggered start
fill: 'forwards', // so the letters remain visible
})
})
},
}),
),
).subscribe({})
).subscribe()
}

render() {
return html`<span class="ml7">
<span class="text-wrapper">
<span class="letters">
<slot></slot>
return html`
<span class="ml7">
<span class="text-wrapper">
<span class="letters">
<slot></slot>
</span>
</span>
</span>
</span> `
`
}
}

Expand Down
Loading

0 comments on commit 32e123c

Please sign in to comment.