@ev-ry/fx 0.1.0-rc.1 → 0.1.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QUICKSTART.fa.md +99 -87
- package/README.md +120 -116
- package/build-report.json +48 -43
- package/docs/GUIDE.md +122 -112
- package/docs/RELEASE-NOTES.md +74 -39
- package/examples/evry-website.md +58 -0
- package/package.json +1 -1
- package/src/dom-attachment.d.ts +1 -1
- package/src/dom-free.d.ts +14 -14
- package/src/dom-free.js +61 -38
- package/src/dom-image-raster.js +14 -0
- package/src/dom-image-surface.js +150 -103
- package/src/dom-image-swap.js +5 -2
- package/src/dom-once.js +39 -34
- package/src/dom-reveal.js +83 -73
- package/src/dom-rich-text.js +133 -116
- package/src/dom-surface-font.js +4 -4
- package/src/dom-svg-surface.js +41 -39
- package/src/dom-text-fingerprint.js +27 -27
- package/src/dom-text-paint-mask.js +24 -0
- package/src/dom-text-surface.js +280 -236
- package/src/font-rasterizer.js +18 -7
- package/src/image-surface.js +161 -156
- package/src/render-owner.js +17 -12
- package/src/text-motion-primitives.js +7 -0
- package/src/text-scene.js +41 -39
- package/src/triangle-effect.js +2 -1
- package/src/viewport-render-owner.js +322 -316
package/QUICKSTART.fa.md
CHANGED
|
@@ -1,94 +1,106 @@
|
|
|
1
|
-
# EV-RY FX Free 0.1.0-rc.
|
|
2
|
-
|
|
3
|
-
این نسخهٔ آزمایشی عمومی با مجوز MIT ارائه میشود. نام بسته در npm برابر @ev-ry/fx است.
|
|
4
|
-
|
|
5
|
-
## روش script
|
|
6
|
-
|
|
7
|
-
آرشیو را استخراج کنید و پوشه package را کامل در مسیر عمومی `/thd/` سایت قرار دهید. این خط را اضافه کنید:
|
|
8
|
-
|
|
9
|
-
```html
|
|
10
|
-
<script src="/thd/src/dom-free-script.js" data-thd-auto defer></script>
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
H1/H2 خودکار انتخاب میشوند. برای تصویر `data-thd-image` و برای متن دیگر `data-thd-text` بگذارید. برای استثناکردن یک بخش، `data-thd-ignore` روی آن یا والدش قرار دهید. فایل examples/script.html نمونهٔ آماده است؛ آن را از HTTP باز کنید، نه file://.
|
|
14
|
-
|
|
15
|
-
### جلوگیری از چشمک در اولین نمایش صفحه
|
|
16
|
-
|
|
17
|
-
این اسکریپت کوچک را در `head`، پیش از محتوای صفحه و **بدون defer یا async** قرار دهید:
|
|
18
|
-
|
|
19
|
-
```html
|
|
20
|
-
<script src="/thd/src/dom-reveal-boot.js"></script>
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
روی آیتمی که منتظر افکت ورود است `data-thd-pending` بگذارید؛ این نشانگر جایگزین انتخابگر اتصال نیست:
|
|
24
|
-
|
|
25
|
-
```html
|
|
26
|
-
<img data-thd-image data-thd-pending src="photo.jpg" width="640" height="400" alt="Photo">
|
|
27
|
-
<h1 data-thd-pending>Hello</h1>
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
فضا حفظ میشود و ماسک اولیه در همان لحظهٔ اتصال به ماسک افکت تحویل داده میشود. اگر موتور بارگیری نشود، ماسک اولیه حداکثر پس از ۸ ثانیه برداشته میشود؛ بدون JavaScript محتوا بومی و قابل مشاهده است. آمادهسازی افکت پس از اتصال، مراقبت خطای مستقل خود را دارد. برای تصویر ابعاد یا aspect-ratio تعیین کنید تا بارگیری آن چیدمان را جابهجا نکند.
|
|
31
|
-
|
|
32
|
-
نشانگر `data-thd-pending` فقط برای مخفیسازی اولیه است و روی آیتمهای خارج از انتخابگر یا مستثناشده نگذارید. ویژگی `data-thd-reveal` متعلق به موتور است؛ آن را دستی تغییر ندهید. مهلت ۸ ثانیه از اجرای اسکریپت اولیه محاسبه میشود و تأخیر افکت نیست. اگر موتور پس از این مهلت آماده شود، جلوگیری از چشمک تضمین نمیشود. در سایت دارای CSP محدود، اجرای اسکریپت و style تزریقشده باید مجاز باشد.
|
|
33
|
-
|
|
34
|
-
## نصب با npm
|
|
35
|
-
|
|
36
|
-
```sh
|
|
37
|
-
npm install
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
برای import از `@ev-ry/fx`، namespace سازگار THREE را خودتان ارائه کنید؛ نسخهٔ همراه script همان r158 است. راهنمای کامل API در docs/GUIDE.md قرار دارد.
|
|
41
|
-
|
|
42
|
-
برای شروع صریح از داخل ماژول نیز میتوانید از loader استفاده کنید:
|
|
43
|
-
|
|
44
|
-
```js
|
|
45
|
-
import * as THREE from 'three';
|
|
46
|
-
import {loadFree} from '@ev-ry/fx/script';
|
|
47
|
-
const api = await loadFree({THREE, auto: true});
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
خود import روی صفحه اثری ندارد و هنگام رندر سمت سرور هم قابل import است؛ `loadFree()` را فقط در مرورگر و پس از وجود صفحه اجرا کنید. نسخهٔ آزمایششدهٔ Three.js همان r158 است. در صورت ندادن THREE، loader از نسخهٔ موجود در window یا فایل همراه استفاده میکند؛ مسیر فایل همراه باید پس از بستهبندی قابل دسترس بماند. اولین فراخوانی حالت خودکار را تعیین میکند و فراخوانیهای بعدی همان آمادهسازی را به اشتراک میگذارند. برای مدیریت دستی از `auto:false` و سپس `api.create()` استفاده کنید.
|
|
51
|
-
|
|
52
|
-
آدرس قبلی `src/dom-free-script.js` برای تگ script معمولی حفظ شده است. روی آن `type="module"` نگذارید. مسیر `@ev-ry/fx/classic-script` فقط برای یافتن فایل script معمولی است؛ ورودی import همان `@ev-ry/fx/script` و تابع `loadFree` است.
|
|
53
|
-
|
|
54
|
-
## React
|
|
55
|
-
|
|
56
|
-
مثال `examples/AnimatedTitle.jsx` عمداً از همان script استفاده میکند تا نیازی به تنظیم بستهبندی فایلهای همراه موتور نباشد. script را بدون data-thd-auto پیش از اجرای React بارگیری کنید و سپس AnimatedTitle را در برنامه استفاده کنید. روی همان عنصر اتصال خودکار و دستی را همزمان فعال نکنید.
|
|
57
|
-
|
|
58
|
-
این مثال cleanup دارد و در StrictMode و تغییر متن باید اتصال قبلی را آزاد کند. children در این مثال یک رشته است؛ این یک پک کامپوننت React مستقل نیست.
|
|
59
|
-
|
|
60
|
-
## رفتار و محدودیتها
|
|
61
|
-
|
|
62
|
-
### ورود به دید و تکرار
|
|
63
|
-
|
|
64
|
-
پیشفرض `once:true` یعنی تنها اولین ورود. با `once:false`، خروج کامل آیتم آن را فوراً مخفی و برای ورود مجدد آماده میکند؛ این خروج افکت محو اجرا نمیکند. حرکت کوچک داخل محدوده نباید افکت را تکرار کند. ورود مجدد در حین افکت ناتمام، همان زمانبندی را ادامه میدهد؛ پس از پایان، ورود جدید افکت تازه میسازد. `play('enter')` درخواست بازپخش صریح و `play('exit')` درخواست محو متحرک است.
|
|
65
|
-
|
|
1
|
+
# EV-RY FX Free 0.1.0-rc.3 — نصب آزمایشی
|
|
2
|
+
|
|
3
|
+
این نسخهٔ آزمایشی عمومی با مجوز MIT ارائه میشود. نام بسته در npm برابر @ev-ry/fx است.
|
|
4
|
+
|
|
5
|
+
## روش script
|
|
6
|
+
|
|
7
|
+
آرشیو را استخراج کنید و پوشه package را کامل در مسیر عمومی `/thd/` سایت قرار دهید. این خط را اضافه کنید:
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<script src="/thd/src/dom-free-script.js" data-thd-auto defer></script>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
H1/H2 خودکار انتخاب میشوند. برای تصویر `data-thd-image` و برای متن دیگر `data-thd-text` بگذارید. برای استثناکردن یک بخش، `data-thd-ignore` روی آن یا والدش قرار دهید. فایل examples/script.html نمونهٔ آماده است؛ آن را از HTTP باز کنید، نه file://.
|
|
14
|
+
|
|
15
|
+
### جلوگیری از چشمک در اولین نمایش صفحه
|
|
16
|
+
|
|
17
|
+
این اسکریپت کوچک را در `head`، پیش از محتوای صفحه و **بدون defer یا async** قرار دهید:
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<script src="/thd/src/dom-reveal-boot.js"></script>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
روی آیتمی که منتظر افکت ورود است `data-thd-pending` بگذارید؛ این نشانگر جایگزین انتخابگر اتصال نیست:
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<img data-thd-image data-thd-pending src="photo.jpg" width="640" height="400" alt="Photo">
|
|
27
|
+
<h1 data-thd-pending>Hello</h1>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
فضا حفظ میشود و ماسک اولیه در همان لحظهٔ اتصال به ماسک افکت تحویل داده میشود. اگر موتور بارگیری نشود، ماسک اولیه حداکثر پس از ۸ ثانیه برداشته میشود؛ بدون JavaScript محتوا بومی و قابل مشاهده است. آمادهسازی افکت پس از اتصال، مراقبت خطای مستقل خود را دارد. برای تصویر ابعاد یا aspect-ratio تعیین کنید تا بارگیری آن چیدمان را جابهجا نکند.
|
|
31
|
+
|
|
32
|
+
نشانگر `data-thd-pending` فقط برای مخفیسازی اولیه است و روی آیتمهای خارج از انتخابگر یا مستثناشده نگذارید. ویژگی `data-thd-reveal` متعلق به موتور است؛ آن را دستی تغییر ندهید. مهلت ۸ ثانیه از اجرای اسکریپت اولیه محاسبه میشود و تأخیر افکت نیست. اگر موتور پس از این مهلت آماده شود، جلوگیری از چشمک تضمین نمیشود. در سایت دارای CSP محدود، اجرای اسکریپت و style تزریقشده باید مجاز باشد.
|
|
33
|
+
|
|
34
|
+
## نصب با npm
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
npm install ./thd-free-0.1.0-rc.3.tgz
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
برای import از `@ev-ry/fx`، namespace سازگار THREE را خودتان ارائه کنید؛ نسخهٔ همراه script همان r158 است. راهنمای کامل API در docs/GUIDE.md قرار دارد.
|
|
41
|
+
|
|
42
|
+
برای شروع صریح از داخل ماژول نیز میتوانید از loader استفاده کنید:
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import * as THREE from 'three';
|
|
46
|
+
import {loadFree} from '@ev-ry/fx/script';
|
|
47
|
+
const api = await loadFree({THREE, auto: true});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
خود import روی صفحه اثری ندارد و هنگام رندر سمت سرور هم قابل import است؛ `loadFree()` را فقط در مرورگر و پس از وجود صفحه اجرا کنید. نسخهٔ آزمایششدهٔ Three.js همان r158 است. در صورت ندادن THREE، loader از نسخهٔ موجود در window یا فایل همراه استفاده میکند؛ مسیر فایل همراه باید پس از بستهبندی قابل دسترس بماند. اولین فراخوانی حالت خودکار را تعیین میکند و فراخوانیهای بعدی همان آمادهسازی را به اشتراک میگذارند. برای مدیریت دستی از `auto:false` و سپس `api.create()` استفاده کنید.
|
|
51
|
+
|
|
52
|
+
آدرس قبلی `src/dom-free-script.js` برای تگ script معمولی حفظ شده است. روی آن `type="module"` نگذارید. مسیر `@ev-ry/fx/classic-script` فقط برای یافتن فایل script معمولی است؛ ورودی import همان `@ev-ry/fx/script` و تابع `loadFree` است.
|
|
53
|
+
|
|
54
|
+
## React
|
|
55
|
+
|
|
56
|
+
مثال `examples/AnimatedTitle.jsx` عمداً از همان script استفاده میکند تا نیازی به تنظیم بستهبندی فایلهای همراه موتور نباشد. script را بدون data-thd-auto پیش از اجرای React بارگیری کنید و سپس AnimatedTitle را در برنامه استفاده کنید. روی همان عنصر اتصال خودکار و دستی را همزمان فعال نکنید.
|
|
57
|
+
|
|
58
|
+
این مثال cleanup دارد و در StrictMode و تغییر متن باید اتصال قبلی را آزاد کند. children در این مثال یک رشته است؛ این یک پک کامپوننت React مستقل نیست.
|
|
59
|
+
|
|
60
|
+
## رفتار و محدودیتها
|
|
61
|
+
|
|
62
|
+
### ورود به دید و تکرار
|
|
63
|
+
|
|
64
|
+
پیشفرض `once:true` یعنی تنها اولین ورود. با `once:false`، خروج کامل آیتم آن را فوراً مخفی و برای ورود مجدد آماده میکند؛ این خروج افکت محو اجرا نمیکند. حرکت کوچک داخل محدوده نباید افکت را تکرار کند. ورود مجدد در حین افکت ناتمام، همان زمانبندی را ادامه میدهد؛ پس از پایان، ورود جدید افکت تازه میسازد. `play('enter')` درخواست بازپخش صریح و `play('exit')` درخواست محو متحرک است.
|
|
65
|
+
|
|
66
66
|
`threshold` نسبت مساحت قابل مشاهده است: صفر برای اولین تقاطع مثبت، `0.5` برای نصف و `1` برای تمام آیتم. آیتم بزرگتر از محدودهٔ دید ممکن است هرگز به مقدار یک نرسد.
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
68
|
+
اگر بعد از اتصال دارای `revealOnView`، صریحاً `play()` را فراخوانی کنید، زمانبندی دستی جای ورود خودکار را میگیرد؛ ماسک اولیه تا اولین فریم حفظ میشود، اما ورود به دید دیگر افکت را از نو شروع نمیکند. برای متن اسلایدر که باید همزمان با اسلاید شروع شود، همین روش مناسب است. متن خارج از دید فقط زمان شروع را نگه میدارد و رسم و محاسبات ذرات متوقف میشوند؛ با برگشت، وضعیت متناسب با زمان سپریشده نمایش داده میشود. اگر زمان تمام شده باشد، افکت دوباره اجرا نمیشود.
|
|
69
|
+
|
|
70
|
+
برای پایان افکت از `await surface.whenFinished()` استفاده کنید؛ پایان گذار به متن بومی را هم در نظر میگیرد و خارج از دید نیز تکمیل میشود. نتیجه یکی از وضعیتهای `completed`، `cancelled` و `unsupported` است. برای تشخیص پایان، تایمر ثابت یا آمار رندر را در کد سایت بررسی نکنید. لغو یا تخریب اتصال، انتظار جاری را با وضعیت `cancelled` آزاد میکند.
|
|
71
|
+
|
|
72
|
+
اگر `play('exit')` را خارج از دید فراخوانی کنید، نمایش بومی همان لحظه مخفی میشود؛ اندازه، جای عنصر و محتوای DOM حذف نمیشوند. اگر حذف در حال اجرا از دید خارج شود نیز نمایش بومی مخفی میماند. هنگام برگشت، فقط ذرات متناسب با زمان سپریشده رسم میشوند و اگر حذف تمام شده باشد، آیتم مخفی میماند. `play('enter')` آن را دوباره تشکیل میدهد؛ `cancel()` یا `destroy()` نمایش و سبکهای بومی را بازمیگردانند. این رفتار در خود موتور برای متن، تصویر و SVG اعمال میشود.
|
|
73
|
+
|
|
74
|
+
### محل canvas و لایهها
|
|
75
|
+
|
|
76
|
+
پیشفرض `auto` با `documentCanvas:true` است؛ canvas مشترک همراه سند حرکت میکند. محدودههای خاص ممکن است به حالت محلی بروند. برای اجبار به حالت محلی از `presentation:'local'` استفاده کنید. canvas مشترک تمام ترکیبهای لایهبندی CSS را بازسازی نمیکند؛ برای تداخل با هدر، zIndex و حالت نمایش را بررسی کنید.
|
|
77
|
+
|
|
78
|
+
### اتصال و پاکسازی
|
|
79
|
+
|
|
80
|
+
عنصرِ خالی که دستی متصل شده، پس از دریافت متن میتواند افکت ورود را اجرا کند. اما عنصر خالیای که اسکن خودکار آن را انتخاب نکرده، برای کشفشدن به `free.refresh()` نیاز دارد. اگر سبک پشتیبانینشده را اصلاح کردید، refresh امکان اجرای اولین ورود را بازمیگرداند؛ ورودِ یکبارهای که قبلاً کامل شده تکرار نمیشود. فاصلههای معمولی HTML طبق CSS جمع میشوند؛ فاصلهٔ نشکن و فاصلههای پیشقالببندیشده حذف سراسری نمیشوند.
|
|
81
|
+
|
|
82
|
+
اتصال خودکار و دستی را روی یک آیتم همزمان انجام ندهید. اسکن تغییرات DOM خودکار و دائمی نیست؛ پس از افزودن یا حذف آیتمها `free.refresh()` را اجرا کنید. هنگام unmount، اتصال یا مالک آن را `destroy()` کنید. تصویر خارجی بدون مجوز CORS یا CSS/SVG پشتیبانینشده ممکن است بومی باقی بماند؛ نبود افکت همیشه خطای بارگذاری موتور نیست.
|
|
83
|
+
|
|
84
|
+
loader خودکار هنگام رفتن صفحه به حافظهٔ Back/Forward مرورگر، اتصال را نگه میدارد و هنگام بازگشت موقعیتش را تازه میکند؛ ورودهای یکباره دوباره ساخته نمیشوند. خروج واقعی صفحه منابع را آزاد میکند. اگر اتصال را خودتان با `api.create()` یا `createFree()` ساختهاید، مدیریت عمر آن هم با شماست: روی `pagehide` فقط در صورت `event.persisted === false` آن را آزاد کنید؛ در بازگشتِ persisted، `refresh()` کافی است. اتصال عمداً destroyشده خودکار زنده نمیشود. پاکسازی هنگام unmount واقعی همچنان لازم است.
|
|
85
|
+
|
|
80
86
|
### آمادهسازی و مصرف پردازش
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
`surface.ready` نتیجهٔ آمادهسازی است، نه پایان نصب موتور؛ برای متن یا SVG پایین صفحه ممکن است تا نزدیکشدن به دید منتظر بماند. فعالشدن دکمههای کل صفحه را به `ready` همهٔ آیتمها وابسته نکنید. پس از ساخت اتصال میتوانید `play()` را صدا بزنید و پایان اجرای درخواستشده را با `whenFinished()` بگیرید.
|
|
89
|
+
|
|
90
|
+
برای تصویر خارج از دید یا با اندازهٔ صفر، `ready` ممکن است با وضعیت موقت بومی و دلیل `Image not visible` تمام شود؛ این به معنی آمادهبودن مش روی GPU نیست. آمادهسازی تصویر از نزدیکی صفحه، حدود نصف ارتفاع viewport جلوتر، آغاز میشود. بارگیری شبکهٔ خود `img` همچنان تابع مرورگر است. هنگام resize سریع، مش قبلی برای مدت کوتاه با کادر حرکت میکند و برش و گوشههای نهایی پس از تجمیع تغییرات بازسازی میشوند؛ ساعت افکت از ابتدا شروع نمیشود.
|
|
91
|
+
|
|
92
|
+
متن ثابت از چیدمان معتبر و پیکسلهای کششده استفاده میکند. سقف کش مشترک پیکسلها ۱۶MiB است؛ این سقف کل حافظهٔ صفحه یا GPU نیست. بارگیری فونت کش مرتبط را تازه میکند. متن پشتیبانینشده بومی نمایش داده میشود و موتور روی همان خطای معلوم مدام تلاش نمیکند؛ پس از اصلاح سبک، `refresh()` امکان تلاش مجدد را میدهد.
|
|
93
|
+
|
|
86
94
|
### مشخصات نسخه
|
|
87
95
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
96
|
+
برای پایان افکت از `await surface.whenFinished()` استفاده کنید؛ نتیجه `completed`، `cancelled` یا `unsupported` است و پایان تبدیل مش به نمایش بومی را هم لحاظ میکند. چند فراخوانی همزمان یک انتظار مشترک دارند. اجرای جدید، انتظار اجرای قبلی را لغو میکند؛ `cancel()`، `destroy()` و جداشدن عنصر از سند نیز انتظار را آزاد میکنند. انتظار ورود خودکار تا اولین intersection محدود به زمان آمادهسازی نیست.
|
|
97
|
+
|
|
98
|
+
متن، تصویر و SVG خارج دید ساعت افکت را با پردازش کم حفظ میکنند؛ ورود مجدد افکت را از ابتدا شروع نمیکند. هنگام درخواست محو خارج دید، نمایش بومی همان لحظه مخفی میشود. در اسلایدر، متن و تصویر بعدی را تنها پس از موفقیت تعویض نهایی کنید. برای متن بعدی عنصر تازه بسازید؛ عنصر متصل به موتور ممکن است سبک یا ویژگی موقت داشته باشد و نباید همان حالت زنده را clone کرد.
|
|
99
|
+
|
|
100
|
+
- متن: ورود باد، خروج دود. تصویر/SVG: ورود برف، خروج ذوب.
|
|
101
|
+
- مدت۲ ثانیه، ذرات مثلثی، سکون بومی، شکلگیری دیرتر برای نمایشدهندهها.
|
|
102
|
+
- canvas متصل به سند پیشفرض است؛ حالت خودکار برای بعضی محدودهها محلی میشود.
|
|
103
|
+
- قبل از جداکردن بخش صفحه owner.destroy() را صدا بزنید. برای اسکن عناصر جدید owner.refresh().
|
|
104
|
+
- چهار افکت ثابت؛ ویرایشگر، افکت سفارشی و پشتیبانی تمام CSS/SVG در این بسته نیستند.
|
|
105
|
+
- یک script با فایلهای همراه است، نه یک فایل یکپارچه. ساختار پوشهها را حفظ کنید.
|
|
94
106
|
- تستهای واقعی آیفون و Android توسط کاربر موفق گزارش شدهاند؛ این تضمین تمام دستگاهها و سایتها نیست.
|
package/README.md
CHANGED
|
@@ -1,116 +1,120 @@
|
|
|
1
|
-
<p align="center"><img src="https://raw.githubusercontent.com/kbaghini/evry-fx/main/docs/assets/cover.svg" alt="EV-RY FX — Motion for the text and images already on your page." width="100%"></p>
|
|
2
|
-
|
|
3
|
-
<h1 align="center">EV-RY FX</h1>
|
|
4
|
-
|
|
5
|
-
<p align="center"><strong>Your HTML. Four particle effects. Native when still.</strong></p>
|
|
6
|
-
|
|
7
|
-
<p align="center">Free edition · 0.1.0-rc.
|
|
8
|
-
|
|
9
|
-
<p align="center">
|
|
10
|
-
<a href="#quick-start">Quick start</a> ·
|
|
11
|
-
<a href="https://kbaghini.github.io/evry-fx/docs/">Live demo</a> ·
|
|
12
|
-
<a href="https://github.com/kbaghini/evry-fx/blob/main/docs/GUIDE.md">Guide</a> ·
|
|
13
|
-
<a href="https://github.com/kbaghini/evry-fx/blob/main/QUICKSTART.fa.md">راهنمای فارسی</a>
|
|
14
|
-
</p>
|
|
15
|
-
|
|
16
|
-
Add WebGL particle motion to existing headings, display text, images and supported SVG icons. EV-RY FX borrows their content and placement from the page, animates textured particles, then returns to native browser rendering.
|
|
17
|
-
|
|
18
|
-
Start with automatic scroll reveals, or attach selected elements through a small API. Keep your existing layout and components.
|
|
19
|
-
|
|
20
|
-
## See it move
|
|
21
|
-
|
|
22
|
-

|
|
23
|
-
|
|
24
|
-
The README shows an animated preview. Open the [live interactive demo](https://kbaghini.github.io/evry-fx/docs/) to try entry and exit effects on real text and images.
|
|
25
|
-
|
|
26
|
-
## What you get
|
|
27
|
-
|
|
28
|
-
| Content | Entry | Exit |
|
|
29
|
-
| --- | --- | --- |
|
|
30
|
-
| Text | Dust wind | Smoke |
|
|
31
|
-
| Images and supported SVG | Drifting snow | Melt |
|
|
32
|
-
|
|
33
|
-
- **A small automatic setup.** Reveal `h1`, `h2`, `[data-thd-text]` and `img[data-thd-image]` on intersection. Mark exclusions with `data-thd-ignore`.
|
|
34
|
-
- **Manual control when needed.** Attach display text, images or supported static SVG; replay, cancel, refresh and destroy individual attachments. Simple image replacement is included.
|
|
35
|
-
- **Your page keeps ownership.** Native DOM elements retain their content and semantics. Native rendering resumes when entry motion settles.
|
|
36
|
-
- **One visual engine.** Text and media use textured triangular particles, four fixed presets and a 2000ms effect timeline. Individual particles can finish earlier within that timeline.
|
|
37
|
-
- **A practical integration boundary.** Framework-independent JavaScript, typed APIs, a classic script entry and an explicit ES-module loader. A React integration example is included.
|
|
38
|
-
|
|
39
|
-
## Quick start
|
|
40
|
-
|
|
41
|
-
**Public preview: 0.1.0-rc.
|
|
42
|
-
|
|
43
|
-
Install from your project folder:
|
|
44
|
-
|
|
45
|
-
```sh
|
|
46
|
-
npm install @ev-ry/fx
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Add a script
|
|
50
|
-
|
|
51
|
-
Serve the complete installed `node_modules/@ev-ry/fx` directory at `/thd/`. Preserve its modules and asset folders; this is not a single-file bundle.
|
|
52
|
-
|
|
53
|
-
```html
|
|
54
|
-
<head>
|
|
55
|
-
<!-- Early mask: load before body content, without async or defer. -->
|
|
56
|
-
<script src="/thd/src/dom-reveal-boot.js"></script>
|
|
57
|
-
<script src="/thd/src/dom-free-script.js" data-thd-auto defer></script>
|
|
58
|
-
</head>
|
|
59
|
-
<body>
|
|
60
|
-
<h1 data-thd-pending>Small details. A better feeling.</h1>
|
|
61
|
-
<p data-thd-text data-thd-pending>Made for your existing page.</p>
|
|
62
|
-
<img data-thd-image data-thd-pending src="photo.jpg"
|
|
63
|
-
width="640" height="400" alt="Describe your photograph">
|
|
64
|
-
</body>
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
`data-thd-pending` prevents initial native paint before the entry effect; it does **not** select an element for attachment. Use it only on selected targets. The mask preserves space, is absent without JavaScript, and has a failure fallback. [First-paint setup, CSP and troubleshooting →](https://github.com/kbaghini/evry-fx/blob/main/docs/GUIDE.md#first-paint-setup-avoid-an-initial-flash)
|
|
68
|
-
|
|
69
|
-
The classic loader uses an existing `window.THREE` or loads the bundled Three.js r158 asset. Serve examples over HTTP, not `file://`. Existing `THDFree`, `data-thd-*` and `src/dom-*` API/file names are retained in this release.
|
|
70
|
-
|
|
71
|
-
### Use a module
|
|
72
|
-
|
|
73
|
-
Provide a compatible Three.js namespace; r158 is the tested version. Call the loader in the browser after the host elements exist:
|
|
74
|
-
|
|
75
|
-
```js
|
|
76
|
-
import * as THREE from 'three';
|
|
77
|
-
import { loadFree } from '@ev-ry/fx/script';
|
|
78
|
-
|
|
79
|
-
const api = await loadFree({ THREE, auto: false });
|
|
80
|
-
const free = api.create(document, { auto: false });
|
|
81
|
-
|
|
82
|
-
const title = free.attachText(document.querySelector('.title'), {
|
|
83
|
-
revealOnView: { threshold: 0.5, once: false }
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// Later, on an explicit user action:
|
|
87
|
-
// title.play('exit');
|
|
88
|
-
// title.cancel();
|
|
89
|
-
|
|
90
|
-
// On component unmount: free.destroy();
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Importing the loader does not initialize the page. Its first call chooses automatic initialization; repeated calls share that initialization. Use `auto:true` for automatic scanning, or `auto:false` with `api.create()` for manual ownership. Do not attach the same element both ways.
|
|
94
|
-
|
|
95
|
-
For direct ownership with injected Three.js, `createFree` is also exported from `@ev-ry/fx`. See the [API and lifecycle guide](https://github.com/kbaghini/evry-fx/blob/main/docs/GUIDE.md).
|
|
96
|
-
|
|
97
|
-
## Examples and guide
|
|
98
|
-
|
|
99
|
-
| Start here | What it demonstrates |
|
|
100
|
-
| --- | --- |
|
|
101
|
-
| [Script example](https://github.com/kbaghini/evry-fx/blob/main/examples/script.html) | Automatic heading entry, including the early mask |
|
|
102
|
-
| [Navigation example](https://github.com/kbaghini/evry-fx/blob/main/examples/navigation.html) | Back/forward navigation and page lifecycle |
|
|
103
|
-
| [React example](https://github.com/kbaghini/evry-fx/blob/main/examples/AnimatedTitle.jsx) | A string title with effect cleanup and StrictMode handling |
|
|
104
|
-
| [Detailed guide](https://github.com/kbaghini/evry-fx/blob/main/docs/GUIDE.md) | SVG, image swaps, selectors, thresholds, canvas routing and troubleshooting |
|
|
105
|
-
| [Persian quickstart](https://github.com/kbaghini/evry-fx/blob/main/QUICKSTART.fa.md) | Installation and integration notes in Persian |
|
|
106
|
-
| [Release notes](https://github.com/kbaghini/evry-fx/blob/main/docs/RELEASE-NOTES.md) | Changes, tested scope and remaining limits |
|
|
107
|
-
|
|
108
|
-
## A few useful boundaries
|
|
109
|
-
|
|
110
|
-
- Repeated scroll reveals hide and rearm after a **complete exit**. Scroll exit does not run the smoke/melt effect; use `play('exit')` for animated disappearance.
|
|
111
|
-
- After adding or removing automatic targets, call `refresh()`. Destroy owned attachments on component unmount; see the guide for back/forward-cache handling.
|
|
112
|
-
- Ordinary page content uses a shared document-connected canvas. Special layouts can route to a local canvas. Arbitrary CSS stacking, clipping and typography are not fully reproduced.
|
|
113
|
-
- SVG support is a static shape/path subset. Unsupported SVG/CSS and images blocked by canvas CORS restrictions can remain native.
|
|
114
|
-
- This Free build does not include editable inputs, arbitrary effect customization or a dedicated React/Vue component pack.
|
|
115
|
-
|
|
116
|
-
EV-RY FX Free is [MIT licensed](https://github.com/kbaghini/evry-fx/blob/main/LICENSE). Bundled dependencies retain their own licenses and [notices](https://github.com/kbaghini/evry-fx/blob/main/NOTICE.md). This license covers the Free distribution; other editions are separate.
|
|
1
|
+
<p align="center"><img src="https://raw.githubusercontent.com/kbaghini/evry-fx/main/docs/assets/cover.svg" alt="EV-RY FX — Motion for the text and images already on your page." width="100%"></p>
|
|
2
|
+
|
|
3
|
+
<h1 align="center">EV-RY FX</h1>
|
|
4
|
+
|
|
5
|
+
<p align="center"><strong>Your HTML. Four particle effects. Native when still.</strong></p>
|
|
6
|
+
|
|
7
|
+
<p align="center">Free edition · 0.1.0-rc.3 preview · <a href="https://github.com/kbaghini/evry-fx/blob/main/LICENSE">MIT licensed</a> · JavaScript + TypeScript declarations</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="#quick-start">Quick start</a> ·
|
|
11
|
+
<a href="https://kbaghini.github.io/evry-fx/docs/">Live demo</a> ·
|
|
12
|
+
<a href="https://github.com/kbaghini/evry-fx/blob/main/docs/GUIDE.md">Guide</a> ·
|
|
13
|
+
<a href="https://github.com/kbaghini/evry-fx/blob/main/QUICKSTART.fa.md">راهنمای فارسی</a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
Add WebGL particle motion to existing headings, display text, images and supported SVG icons. EV-RY FX borrows their content and placement from the page, animates textured particles, then returns to native browser rendering.
|
|
17
|
+
|
|
18
|
+
Start with automatic scroll reveals, or attach selected elements through a small API. Keep your existing layout and components.
|
|
19
|
+
|
|
20
|
+
## See it move
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
The README shows an animated preview. Open the [live interactive demo](https://kbaghini.github.io/evry-fx/docs/) to try entry and exit effects on real text and images.
|
|
25
|
+
|
|
26
|
+
## What you get
|
|
27
|
+
|
|
28
|
+
| Content | Entry | Exit |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| Text | Dust wind | Smoke |
|
|
31
|
+
| Images and supported SVG | Drifting snow | Melt |
|
|
32
|
+
|
|
33
|
+
- **A small automatic setup.** Reveal `h1`, `h2`, `[data-thd-text]` and `img[data-thd-image]` on intersection. Mark exclusions with `data-thd-ignore`.
|
|
34
|
+
- **Manual control when needed.** Attach display text, images or supported static SVG; replay, cancel, refresh and destroy individual attachments. Simple image replacement is included.
|
|
35
|
+
- **Your page keeps ownership.** Native DOM elements retain their content and semantics. Native rendering resumes when entry motion settles.
|
|
36
|
+
- **One visual engine.** Text and media use textured triangular particles, four fixed presets and a 2000ms effect timeline. Individual particles can finish earlier within that timeline.
|
|
37
|
+
- **A practical integration boundary.** Framework-independent JavaScript, typed APIs, a classic script entry and an explicit ES-module loader. A React integration example is included.
|
|
38
|
+
|
|
39
|
+
## Quick start
|
|
40
|
+
|
|
41
|
+
**Public preview: 0.1.0-rc.3.** Validate the supported content and layouts in your project before production use.
|
|
42
|
+
|
|
43
|
+
Install from your project folder:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
npm install @ev-ry/fx
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Add a script
|
|
50
|
+
|
|
51
|
+
Serve the complete installed `node_modules/@ev-ry/fx` directory at `/thd/`. Preserve its modules and asset folders; this is not a single-file bundle.
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<head>
|
|
55
|
+
<!-- Early mask: load before body content, without async or defer. -->
|
|
56
|
+
<script src="/thd/src/dom-reveal-boot.js"></script>
|
|
57
|
+
<script src="/thd/src/dom-free-script.js" data-thd-auto defer></script>
|
|
58
|
+
</head>
|
|
59
|
+
<body>
|
|
60
|
+
<h1 data-thd-pending>Small details. A better feeling.</h1>
|
|
61
|
+
<p data-thd-text data-thd-pending>Made for your existing page.</p>
|
|
62
|
+
<img data-thd-image data-thd-pending src="photo.jpg"
|
|
63
|
+
width="640" height="400" alt="Describe your photograph">
|
|
64
|
+
</body>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`data-thd-pending` prevents initial native paint before the entry effect; it does **not** select an element for attachment. Use it only on selected targets. The mask preserves space, is absent without JavaScript, and has a failure fallback. [First-paint setup, CSP and troubleshooting →](https://github.com/kbaghini/evry-fx/blob/main/docs/GUIDE.md#first-paint-setup-avoid-an-initial-flash)
|
|
68
|
+
|
|
69
|
+
The classic loader uses an existing `window.THREE` or loads the bundled Three.js r158 asset. Serve examples over HTTP, not `file://`. Existing `THDFree`, `data-thd-*` and `src/dom-*` API/file names are retained in this release.
|
|
70
|
+
|
|
71
|
+
### Use a module
|
|
72
|
+
|
|
73
|
+
Provide a compatible Three.js namespace; r158 is the tested version. Call the loader in the browser after the host elements exist:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
import * as THREE from 'three';
|
|
77
|
+
import { loadFree } from '@ev-ry/fx/script';
|
|
78
|
+
|
|
79
|
+
const api = await loadFree({ THREE, auto: false });
|
|
80
|
+
const free = api.create(document, { auto: false });
|
|
81
|
+
|
|
82
|
+
const title = free.attachText(document.querySelector('.title'), {
|
|
83
|
+
revealOnView: { threshold: 0.5, once: false }
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Later, on an explicit user action:
|
|
87
|
+
// title.play('exit');
|
|
88
|
+
// title.cancel();
|
|
89
|
+
|
|
90
|
+
// On component unmount: free.destroy();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Importing the loader does not initialize the page. Its first call chooses automatic initialization; repeated calls share that initialization. Use `auto:true` for automatic scanning, or `auto:false` with `api.create()` for manual ownership. Do not attach the same element both ways.
|
|
94
|
+
|
|
95
|
+
For direct ownership with injected Three.js, `createFree` is also exported from `@ev-ry/fx`. See the [API and lifecycle guide](https://github.com/kbaghini/evry-fx/blob/main/docs/GUIDE.md).
|
|
96
|
+
|
|
97
|
+
## Examples and guide
|
|
98
|
+
|
|
99
|
+
| Start here | What it demonstrates |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| [Script example](https://github.com/kbaghini/evry-fx/blob/main/examples/script.html) | Automatic heading entry, including the early mask |
|
|
102
|
+
| [Navigation example](https://github.com/kbaghini/evry-fx/blob/main/examples/navigation.html) | Back/forward navigation and page lifecycle |
|
|
103
|
+
| [React example](https://github.com/kbaghini/evry-fx/blob/main/examples/AnimatedTitle.jsx) | A string title with effect cleanup and StrictMode handling |
|
|
104
|
+
| [Detailed guide](https://github.com/kbaghini/evry-fx/blob/main/docs/GUIDE.md) | SVG, image swaps, selectors, thresholds, canvas routing and troubleshooting |
|
|
105
|
+
| [Persian quickstart](https://github.com/kbaghini/evry-fx/blob/main/QUICKSTART.fa.md) | Installation and integration notes in Persian |
|
|
106
|
+
| [Release notes](https://github.com/kbaghini/evry-fx/blob/main/docs/RELEASE-NOTES.md) | Changes, tested scope and remaining limits |
|
|
107
|
+
|
|
108
|
+
## A few useful boundaries
|
|
109
|
+
|
|
110
|
+
- Repeated scroll reveals hide and rearm after a **complete exit**. Scroll exit does not run the smoke/melt effect; use `play('exit')` for animated disappearance.
|
|
111
|
+
- After adding or removing automatic targets, call `refresh()`. Destroy owned attachments on component unmount; see the guide for back/forward-cache handling.
|
|
112
|
+
- Ordinary page content uses a shared document-connected canvas. Special layouts can route to a local canvas. Arbitrary CSS stacking, clipping and typography are not fully reproduced.
|
|
113
|
+
- SVG support is a static shape/path subset. Unsupported SVG/CSS and images blocked by canvas CORS restrictions can remain native.
|
|
114
|
+
- This Free build does not include editable inputs, arbitrary effect customization or a dedicated React/Vue component pack.
|
|
115
|
+
|
|
116
|
+
EV-RY FX Free is [MIT licensed](https://github.com/kbaghini/evry-fx/blob/main/LICENSE). Bundled dependencies retain their own licenses and [notices](https://github.com/kbaghini/evry-fx/blob/main/NOTICE.md). This license covers the Free distribution; other editions are separate.
|
|
117
|
+
|
|
118
|
+
## Real integration: EV-RY website
|
|
119
|
+
|
|
120
|
+
[See the EV-RY product-showcase integration](examples/evry-website.md): alternating snow/melt image transitions, animated captions and persistent-engine navigation. Includes initial-reveal and lifecycle guidance; the full website is currently a local integration.
|