svelte-typewriter
Advanced tools
Comparing version 3.0.0-alpha.12 to 3.0.0-alpha.13
@@ -12,3 +12,3 @@ { | ||
}, | ||
"version": "3.0.0-alpha.12", | ||
"version": "3.0.0-alpha.13", | ||
"main": "src/Typewriter.svelte", | ||
@@ -25,16 +25,15 @@ "svelte": "src/Typewriter.svelte", | ||
"scripts": { | ||
"example:dev": "vite example", | ||
"example:build": "vite build example", | ||
"example:preview": "vite preview example", | ||
"example:deploy": "pnpm example:build && gh-pages -f -d example/dist -m \"Deploy example application\"", | ||
"prerelease": "DOCKER_BUILDKIT=1 docker build --build-arg HOST_USER_UID=\"$(id -u)\" -t release .", | ||
"release": "docker run --rm -t -v $PWD:/repo -e GIT_NAME=\"$(git config user.name)\" -e GIT_EMAIL=\"$(git config user.email)\" release ./bump-package-json", | ||
"prepare": "husky install", | ||
"prettier": "prettier --write \"./src/**/*.js\"", | ||
"vitebook:dev": "vitebook dev", | ||
"vitebook:build": "vitebook build", | ||
"vitebook:preview": "vitebook preview" | ||
"prettier": "prettier --write \"./src/**/*.js\"" | ||
}, | ||
"devDependencies": { | ||
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.36", | ||
"@sveltejs/vite-plugin-svelte": "1.0.0-next.36", | ||
"@tsconfig/svelte": "^3.0.0", | ||
"@vitebook/client": "^0.23.4", | ||
"@vitebook/core": "^0.23.4", | ||
"@vitebook/theme-default": "^0.23.4", | ||
"gh-pages": "^4.0.0", | ||
"husky": "^7.0.4", | ||
@@ -44,3 +43,3 @@ "prettier": "^2.5.1", | ||
"svelte": "^3.43.1", | ||
"vite": "^2.7.0" | ||
"vite": "2.8.6" | ||
}, | ||
@@ -47,0 +46,0 @@ "peerDependencies": { |
102
README.md
@@ -14,3 +14,2 @@ # svelte-typewriter | ||
- [Summary](#summary) | ||
- [Installation](#installation) | ||
@@ -20,8 +19,10 @@ - [Usage](#usage) | ||
- [Settings](#settings) | ||
- [Modes](#modes) | ||
- [Modes](#modes) | ||
- [Event listeners](#event-listeners) | ||
- [Child attributes](#child-attributes) | ||
- [CSS variables](#css-variables) | ||
- [Used by](#used-by) | ||
- [FAQs](#faqs) | ||
- [UMD and IIFE output formats are not supported for code-splitting builds](#umd-and-iife-output-formats-are-not-supported-for-code-splitting-builds) | ||
- [Test suite failed to run: SyntaxError: Unexpected token '<'](#test-suite-failed-to-run-syntaxerror-unexpected-token-) | ||
- [Contributing](#contributing) | ||
@@ -32,12 +33,11 @@ | ||
```bash | ||
# yarn | ||
yarn add -D svelte-typewriter | ||
# npm | ||
npm i -D svelte-typewriter | ||
pnpm i -D svelte-typewriter | ||
``` | ||
> `pnpm` is used here just as an example, you can use your package of choice | ||
## Usage | ||
You need to import the Svelte component, and wrap your elements with the `<Typewriter>` component | ||
You need to import the Svelte component, and wrap your elements with the | ||
`<Typewriter>` component | ||
@@ -51,4 +51,2 @@ ```svelte | ||
<h1>Testing the typewriter effect</h1> | ||
<h2>The typewriter effect cascades by default</h2> | ||
<p>Lorem ipsum dolor sit amet consectetur</p> | ||
</Typewriter> | ||
@@ -60,6 +58,7 @@ | ||
The `<Typewriter>` component can receive props that allows to manipulate the behavior of the resulting animation, these props are divided into 5 groups | ||
The `<Typewriter>` component can receive props that allows to manipulate the | ||
behavior of the resulting animation, these props are divided into the following | ||
groups | ||
- **Settings:** general animation properties | ||
- **Modes:** different styles of animation | ||
- **Event listeners:** functions executed based on the condition of a trigger | ||
@@ -71,32 +70,36 @@ - **Child attributes:** child elements animation properties | ||
| Prop | Type | Description | Default | | | ||
| --------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------- | | ||
| `interval` | `number` or `array` | The interval in milliseconds between each letter, you can also pass a array of distinct intervals to mimic human typing | `30` | [DEMO](https://svelte.dev/repl/eb6caec159cf454b8f2bc98f3444fa8c) | | ||
| `unwriteInterval` | `number` | The interval in milliseconds between each letter unwrite, is valid only on loops. If not defined it uses interval | `false` | TBA | | ||
| `cursor` | `boolean` | Enables/disables the cursor on the Typewriter animation | `true` | [DEMO](https://svelte.dev/repl/6008b5aaff6f46e5909c63e795a19f5a) | | ||
| `delay` | `number` | The interval in milliseconds before the animation starts | `0` | [DEMO](https://svelte.dev/repl/2002ac9fe1e0433a88a687b3b3d4c58b?version=3.29.0) | | ||
| `scrambleSlowdown` | `boolean` | Enables/disables the slowdown effect right before the scramble animation ends (only works in scramble mode) | `true` if on scramble mode, otherwise `false` | TBA | | ||
| Prop | Type | Description | Default | | ||
| - | - | - | - | | ||
| `mode` | `concurrent`, `cascade`, `loop`, `loopRandom` or `scramble` | The animation mode to be used | `concurrent` | | ||
| `interval` | `number` or `array` | The interval (in milliseconds) between each letter, you can also pass a array of distinct intervals to mimic human typing | `30` | | ||
| `cursor` | `boolean` | Enables/disables the cursor on the Typewriter animation | `true` | | ||
| `delay` | `number` | The interval (in milliseconds) before the animation starts | `0` | | ||
| `disabled` | `boolean` | Enables/disables the typewriter animation | `false` | | ||
| `wordInterval` | `number` | **(`loop`/`loopRandom` modes only)** Sets the interval (in milliseconds) between each word | `1500` | | ||
| `unwriteInterval` | `number` | **(`loop`/`loopRandom` modes only)** The interval (in milliseconds) between each letter unwrite, is valid only on loops. If not defined it uses interval | `false` | | ||
| `scrambleDuration` | `number` | **(`scramble` mode only)** Sets the duration (in milliseconds) of the scramble animation | `3000` | | ||
| `scrambleSlowdown` | `boolean` | **(`scramble` mode only)** Enables/disables the slowdown effect right before the scramble animation ends (only works in scramble mode) | `true` if on scramble mode, otherwise `false` | | ||
### Modes | ||
#### Modes | ||
You can control the behavior of the typewriter effect by passing specific props to the `<Typewriter>` component, the table below contains information about all modes: | ||
| Mode | Type | Description | Default | | | ||
| ------------ | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------- | | ||
| `default` | | Apply animation simultaneously on all elements, as opposed to the sequential animation of `cascade` mode | `true` | [DEMO](https://svelte.dev/repl/9dfb73bfa9b34aeea4740fa23f5cde8a) | | ||
| `cascade` | `boolean` | Apply animation on all elements sequentially instead of simultaneously | `false` | [DEMO](https://svelte.dev/repl/9ddb89942e954a2a90b553356952ff46) | | ||
| `loop` | `boolean` or `number` | Cycles the animation between the children elements of the parent `Typewriter` component, the interval (in milliseconds) between each word can be defined by passing a number as the parameter, otherwise defaults to `1500` | `false` | [DEMO](https://svelte.dev/repl/e8b82d83f6c2444b97619238404bcd4d) | | ||
| `loopRandom` | `boolean` or `number` | It's very similar to `loop` mode, but instead of cycling the animation in a linear way, it picks a random child element to animate each time, the interval (in milliseconds) between each word can be defined by passing a number as the parameter, otherwise defaults to `1500` | `false` | [DEMO](https://svelte.dev/repl/d75f38dc86374f7ebd20e1e33d278b09) | | ||
| `scramble` | `boolean` or `number` | Randomize all letters in a element text for a specific amount of time, if a number is passed as argument, it's defined as the duration of the animation (defaults to `3000`) | `false` | [DEMO](https://svelte.dev/repl/1c48ad0ad8d34eb7b6e561d39799ff6e) | | ||
| Mode | Description | | ||
| - | - | | ||
| `concurrent` | Apply animation simultaneously on all elements, as opposed to the sequential animation of `cascade` mode | | ||
| `cascade` | Apply animation on all elements sequentially instead of simultaneously | | ||
| `loop` | Cycles the animation between the children elements of the parent `Typewriter` component | | ||
| `loopRandom` | It's very similar to `loop` mode, but instead of cycling the animation in a linear way, it picks a random child element to animate each time | | ||
| `scramble` | Slowly reveals the a word by continuously randomizing all of it's letters for a specific amount of time | | ||
### Event listeners | ||
| Event | Trigger | | | ||
| --------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | ||
| `on:done` | Is executed at the end of the animation, if used with `loop` mode, this event will be fired at the end of each loop | [DEMO](https://svelte.dev/repl/145cbf66c396497aa5338846077d53e0) | | ||
| Event | Trigger | | ||
| - | - | | ||
| `on:done` | Is executed at the end of the animation, if used with `loop` mode, this event will be fired at the end of each loop | | ||
### Child attributes | ||
| Attribute | Description | | ||
| ------------- | ---------------------------------------------------------------------------------------------------- | | ||
| Attribute | Description | | ||
| - | - | | ||
| `data-static` | Marks an element as static, excluding it from receiving animations from the `<Typewriter>` component | | ||
@@ -106,6 +109,6 @@ | ||
| Variable | Description | | ||
| ---------------- | ---------------------------------------------------------------------------------- | | ||
| Variable | Description | | ||
| - | - | | ||
| `--cursor-color` | Sets the cursor color (accepts any valid color name, hex code and rgb/rgba values) | | ||
| `--cursor-width` | Sets the cursor width | | ||
| `--cursor-width` | Sets the cursor width | | ||
@@ -115,8 +118,11 @@ ## Used by | ||
<div align="center"> | ||
<a target="_blank" href="https://github.com/GeopJr/SveltePress" style="margin:0 12px"> | ||
<a href="https://github.com/GeopJr/SveltePress"> | ||
<img src="sveltepress-logo.png" width="128" alt="SveltePress logo"> | ||
</a> | ||
<a target="_blank" href="https://github.com/ThatConference/that.us" style="margin:0 12px"> | ||
<a href="https://github.com/ThatConference/that.us"> | ||
<img src="that-us-logo.svg" width="256" height="128" alt="That.us logo"> | ||
</a> | ||
<a href="https://github.com/Fronvo/site"> | ||
<img src="fronvo-logo.svg" width="256" height="128" alt="Fronvo logo"> | ||
</a> | ||
</div> | ||
@@ -128,7 +134,15 @@ | ||
From version 2.1.17 onwards, this library makes use of dynamic imports, if your Rollup configuration `output.format` is set to `iife` or `umd`, consider setting `inlineDynamicImports` to `true`, otherwise, change `output.format` to something else, like `esm` (for more details, consider checking [#21](https://github.com/henriquehbr/svelte-typewriter/issues/21)) | ||
From version 2.1.17 onwards, this library makes use of dynamic imports, if your | ||
Rollup configuration `output.format` is set to `iife` or `umd`, consider | ||
setting `inlineDynamicImports` to `true`, otherwise, change `output.format` to | ||
something else, like `esm` (for more details, consider checking [#21](https://github.com/henriquehbr/svelte-typewriter/issues/21)) | ||
#### Test suite failed to run: SyntaxError: Unexpected token '<' | ||
This happens because Jest cannot parse Svelte syntax right away, it needs to be transformed by `svelte-jester` first, therefore, we must tell Jest to **NOT** ignore `svelte-typewriter`, as by default, everything inside `node_modules` is ignored and parsed as-is without any kind of pre-processing, this can be done by setting the `transformIgnorePatterns` property on your Jest configuration, example below: | ||
This happens because Jest cannot parse Svelte syntax right away, it needs to be | ||
transformed by `svelte-jester` first, therefore, we must tell Jest to **NOT** | ||
ignore `svelte-typewriter`, as by default, everything inside `node_modules` is | ||
ignored and parsed as-is without any kind of pre-processing, this can be done | ||
by setting the `transformIgnorePatterns` property on your Jest configuration, | ||
example below: | ||
@@ -146,7 +160,7 @@ ```js | ||
1. Fork it! | ||
1. Fork it | ||
2. Create your feature branch: `git checkout -b fix/my-new-bug-fix` | ||
3. Preview your changes with `yarn dev` (or `npm run dev`) | ||
4. Commit your changes: `git commit -am 'fix: Fix some bug'` | ||
5. Push to the branch: `git push origin fix/my-new-bug-fix` | ||
6. Submit a pull request :D | ||
3. Preview your changes by running the `dev` script on `package.json` | ||
4. Commit your changes: `git commit -am 'fix: solve some issue'` | ||
5. Push to the branch: `git push --set-upstream origin fix/my-new-bug-fix` | ||
6. Submit a pull request |
@@ -6,3 +6,3 @@ /** @type {import(types').OnAnimationEnd} */ | ||
const elementAttributeChanged = mutation.type === 'attributes' | ||
const elementFinishedTyping = mutation.target.classList.contains('typing') | ||
const elementFinishedTyping = mutation.target.classList.contains('finished-typing') | ||
if (elementAttributeChanged && elementFinishedTyping) callback() | ||
@@ -9,0 +9,0 @@ }) |
@@ -5,4 +5,2 @@ import { typingInterval } from './typingInterval' | ||
const unwriteEffect = async (currentNode, options) => { | ||
options.dispatch('done') | ||
await typingInterval(typeof options.loop === 'number' ? options.loop : 1500) | ||
const text = currentNode.innerHTML.replaceAll('&', '&') | ||
@@ -9,0 +7,0 @@ for (let index = text.length - 1; index >= 0; index--) { |
@@ -0,30 +1,14 @@ | ||
import { getLettersTimeout } from '../helpers/getLettersTimeout' | ||
import { getRandomLetter } from '../helpers/getRandomLetter' | ||
import { rng } from '../helpers/rng' | ||
import { sleep } from '../helpers/sleep' | ||
import { runOnEveryParentUntil } from '../helpers/runOnEveryParentUntil' | ||
import { animationSetup } from '../helpers/animationSetup' | ||
const getRandomNumber = (min, max) => Math.floor(Math.random() * (max - min)) + min | ||
/** @type {TypewriterModeFn} */ | ||
const scramble = async (node, props) => { | ||
const { options, elements } = animationSetup(node, props) | ||
const getRandomLetter = () => { | ||
const possibleLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.split( | ||
'' | ||
) | ||
const letterIndexLimit = possibleLetters.length | ||
const randomLetterIndex = getRandomNumber(0, letterIndexLimit) | ||
const randomLetter = possibleLetters[randomLetterIndex] | ||
return randomLetter | ||
} | ||
const timeout = options.scrambleDuration | ||
// returns a array with a timeout (in ms) for each letter of the word | ||
const getLettersTimeout = (textLetters, timeout) => { | ||
const minimumTimeoutPossible = timeout / 3 | ||
// TODO: find a better way to deal with this instead of explicitly reducing the maximum timeout | ||
// otherwise, at the end of the animation, one or two characters remain scrambled | ||
const lettersTimeout = textLetters.map(() => | ||
getRandomNumber(minimumTimeoutPossible, timeout - 100) | ||
) | ||
return lettersTimeout | ||
} | ||
/** @type {TypewriterModeFn} */ | ||
export const mode = async (elements, options) => { | ||
const timeout = typeof options.scramble == 'number' ? options.scramble : 3000 | ||
await new Promise(resolve => { | ||
@@ -41,3 +25,3 @@ elements.forEach(async ({ currentNode, text }) => { | ||
while (Date.now() - startingTime < timeout) { | ||
const randomLetterIndex = getRandomNumber(0, wordLetters.length) | ||
const randomLetterIndex = rng(0, wordLetters.length) | ||
const randomLetterTimeout = lettersTimeout[randomLetterIndex] | ||
@@ -81,1 +65,3 @@ const isRandomLetterWhitespace = wordLetters[randomLetterIndex] === ' ' | ||
} | ||
export default scramble |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8
385
157
27218