Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added shuffle feature #11

Merged
merged 9 commits into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions @types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,11 @@ export interface UseTypewriterOptions {
* @default false
*/
finishEmpty: boolean;

/**
* Whether or not to shuffle the words before for each iteration.
* (if true, the words will be shuffled before each iteration)
* @default false
*/
shuffle: boolean;
}
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ interface UseTypewriterOptions {
* @default false
*/
finishEmpty: boolean;

/**
* If we should shuffle once we've reached the end of this itteration.
*
* @default false
*/
shuffle: boolean;
}
```

Expand Down Expand Up @@ -221,6 +228,10 @@ interface UseTypewriterReturns {
* Whether or not the typewriter is set to pause once the last letter has been typed out
*/
isPausingAtEnd: Ref<boolean>;
/**
* Whether or not the typewriter will shuffle once the last word in the itteration has been typed out
*/
willShuffle: Ref<boolean>;
/**
* Whether or not the typewriter is to end on an empty string
*/
Expand All @@ -233,6 +244,10 @@ interface UseTypewriterReturns {
* Pause once the current word has been typed out
*/
pauseAtEndOfWord: () => void;
/**
* Shuffle the strings array after the current word has been typed out
*/
shuffle: () => void;
/*
* Resume the typewriter from where it is
* If the typewriter is complete, it will restart
Expand Down
10 changes: 8 additions & 2 deletions demo/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ const {
isAtLastLetter,
isLastIteration,
isPausingAtEnd,
willShuffle,
finishEmpty,
pauseAtEndOfWord,
pause,
play,
safeUpdateStrings,
updateStrings,
shuffle,
} = useTypewriter(strings)
</script>

Expand Down Expand Up @@ -82,10 +84,13 @@ const {
</button>
<button
type="button"
@click="safeUpdateStrings(exampleReplacementStrings)"
@click="updateStrings(exampleReplacementStrings)"
>
Safe Replace
</button>
<button type="button" @click="shuffle()">
Shuffle
</button>
</fieldset>

<fieldset>
Expand Down Expand Up @@ -142,6 +147,7 @@ const {
:is-at-last-letter="isAtLastLetter"
:is-last-iteration="isLastIteration"
:is-pausing-at-end="isPausingAtEnd"
:will-shuffle="willShuffle"
:hold-empty-for="holdEmptyFor"
:finish-empty="finishEmpty"
/>
Expand Down
5 changes: 5 additions & 0 deletions demo/src/components/app/AppDebug.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Props = {
isAtLastLetter: boolean;
isLastIteration: boolean;
isPausingAtEnd: boolean;
willShuffle: boolean;
finishEmpty: boolean;
}

Expand Down Expand Up @@ -91,6 +92,10 @@ defineProps<Props>()
<td>Is pausing at end</td>
<td>{{ isPausingAtEnd }}</td>
</tr>
<tr>
<td>Will shuffle</td>
<td>{{ willShuffle }}</td>
</tr>
</table>
</section>

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@altgen/typer-composable",
"version": "1.1.0",
"version": "1.2.0",
"private": false,
"description": "A vue 3 composable for creating typewriter text",
"keywords": [
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './UseTypewriter'
export * from './useTypewriter'
25 changes: 24 additions & 1 deletion src/UseTypewriter.ts → src/useTypewriter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { reactive, toRefs, ref, computed, onMounted, onUnmounted } from 'vue'
import { MaybeRef } from '@vueuse/shared'
import { UseTypewriterOptions } from '../@types'
import { shuffleArray } from './utils'

const useTypewriterOptionsDefaults: UseTypewriterOptions = {
typeInterval: 100,
Expand All @@ -12,6 +13,7 @@ const useTypewriterOptionsDefaults: UseTypewriterOptions = {
startEmpty: false,
startPaused: false,
finishEmpty: false,
shuffle: false,
}

export enum TypewriterStates {
Expand Down Expand Up @@ -93,6 +95,11 @@ export function useTypewriter (
*/
const isPausingAtEnd = ref(false)

/**
* Whether the typewriter will shuffle the strings at the end of the current iteration.
*/
const willShuffle = ref(options.shuffle ?? useTypewriterOptionsDefaults.shuffle)

/**
* whether the typewriter is currently using the last string
*/
Expand Down Expand Up @@ -223,6 +230,10 @@ export function useTypewriter (
// If we are at the end of the words array, we need to check if we are looping.
if (loop.value) {
// If we have reached the iteration limit, we need to stop typing.
if (willShuffle.value) {
strings.value = shuffleArray(strings.value)
}

if (isLastIteration.value) {
end()
return
Expand Down Expand Up @@ -370,12 +381,21 @@ export function useTypewriter (
* Update the strings array safely by finishing the deletion of the current string.
* Then updating the array.
* @param newStrings Strings to update the current array to
* @deprecated since v1.0.7 use updateStrings instead
* @note Use updateStrings instead
* @deprecated since v1.0.7
*/
function safeUpdateStrings (newStrings: string[]) {
updateStrings(newStrings)
}

/**
* Shuffle the string order after the current word is finished.
*/
function shuffle () {
// Set the strings to the same strings with a random order
updateStrings(shuffleArray(strings.value))
}

/**
* Utility function to replace the current strings array.
*/
Expand Down Expand Up @@ -429,10 +449,13 @@ export function useTypewriter (
isAtLastString,
isLastIteration,
isPausingAtEnd,
willShuffle,
finishEmpty,
pause,
pauseAtEndOfWord,
play,
shuffle,
updateStrings,
safeUpdateStrings,
}
}
Expand Down
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './shuffle'
18 changes: 18 additions & 0 deletions src/utils/shuffle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export function shuffleArray (array: any[]): any[] {
// Fisher-Yates shuffle
const shuffledArray = [...array]

// For each element in the array (from the end to the beginning)
for (let i = array.length - 1; i > 0; i--) {
// Pick a random other element before the current element
const j = Math.floor(Math.random() * (i + 1))

// Swap the elements
const newVal = shuffledArray[i]
shuffledArray[i] = shuffledArray[j]
shuffledArray[j] = newVal
}

// return the resulting array
return shuffledArray
}
35 changes: 3 additions & 32 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -635,11 +635,6 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==

confusing-browser-globals@^1.0.10:
version "1.0.11"
resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81"
integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==

cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
Expand Down Expand Up @@ -918,21 +913,6 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==

eslint-config-airbnb-base@^15.0.0:
version "15.0.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236"
integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==
dependencies:
confusing-browser-globals "^1.0.10"
object.assign "^4.1.2"
object.entries "^1.1.5"
semver "^6.3.0"

eslint-config-prettier@^8.5.0:
version "8.5.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1"
integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==

eslint-config-standard@^17.0.0:
version "17.0.0"
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz#fd5b6cf1dcf6ba8d29f200c461de2e19069888cf"
Expand Down Expand Up @@ -1052,7 +1032,7 @@ eslint-plugin-unicorn@^43.0.2:
semver "^7.3.7"
strip-indent "^3.0.0"

eslint-plugin-vue@^9.4.0, eslint-plugin-vue@^9.5.1:
eslint-plugin-vue@^9.4.0:
version "9.5.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.5.1.tgz#87ce075882cf7d824b95f46c224f91495fafcc54"
integrity sha512-Y0sL2RY7Xc9S8kNih9lbwHIDmewUg9bfas6WSzsOWRgDXhIHKxRBZYNAnVcXBFfE+bMWHUA5GLChl7TcTYUI8w==
Expand Down Expand Up @@ -1836,7 +1816,7 @@ object-keys@^1.1.1:
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==

object.assign@^4.1.2, object.assign@^4.1.4:
object.assign@^4.1.4:
version "4.1.4"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"
integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
Expand All @@ -1846,15 +1826,6 @@ object.assign@^4.1.2, object.assign@^4.1.4:
has-symbols "^1.0.3"
object-keys "^1.1.1"

object.entries@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
es-abstract "^1.19.1"

object.values@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
Expand Down Expand Up @@ -2172,7 +2143,7 @@ sass@^1.54.9:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==

semver@^6.1.0, semver@^6.3.0:
semver@^6.1.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
Expand Down