mirror of
https://github.com/nunocoracao/blowfish.git
synced 2026-10-25 05:02:55 +00:00
✨ TypeIt integration
This commit is contained in:
1 parent
5d6dca74dc
commit
09a5be7077
7 files changed
+164
-19
No files matched your search
@@ -38,6 +38,7 @@ Blowfish is designed to be a powerful, lightweight theme for [Hugo](https://gohu
|
||||
- Client-side site search powered by Fuse.js
|
||||
- Diagrams and visualisations using Mermaid
|
||||
- Charts using Chart.js
|
||||
- TypeIt integration
|
||||
- Mathematical notation using KaTeX
|
||||
- SVG icons from FontAwesome 6
|
||||
- Automatic image resizing using Hugo Pipes
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// TypeIt by Alex MacArthur - https://typeitjs.com
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TypeIt=t()}(this,(function(){"use strict";const e=e=>Array.isArray(e),t=t=>e(t)?t:[t];const n=e=>Array.from(e),r=e=>document.createTextNode(e);let i=e=>([...e.childNodes].forEach((e=>{if(e.nodeValue)return[...e.nodeValue].forEach((t=>{e.parentNode.insertBefore(r(t),e)})),void e.remove();i(e)})),e);const a=e=>{let t=document.implementation.createHTMLDocument();return t.body.innerHTML=e,i(t.body)},o="data-typeit-id",s="ti-cursor",l={started:!1,completed:!1,frozen:!1,destroyed:!1},u={breakLines:!0,cursor:{autoPause:!0,autoPauseDelay:500,animation:{frames:[0,0,1].map((e=>({opacity:e}))),options:{iterations:1/0,easing:"steps(2, start)",fill:"forwards"}}},cursorChar:"|",cursorSpeed:1e3,deleteSpeed:null,html:!0,lifeLike:!0,loop:!1,loopDelay:750,nextStringDelay:750,speed:100,startDelay:250,startDelete:!1,strings:[],waitUntilVisible:!1,beforeString:()=>{},afterString:()=>{},beforeStep:()=>{},afterStep:()=>{},afterComplete:()=>{}},c=`[${o}]:before {content: '.'; display: inline-block; width: 0; visibility: hidden;}`;function d(e,t=!1,n=!1){let r,i=e.querySelector(`.${s}`),a=document.createTreeWalker(e,NodeFilter.SHOW_ALL,{acceptNode:e=>{if(i&&n){if(e.classList?.contains(s))return NodeFilter.FILTER_ACCEPT;if(i.contains(e))return NodeFilter.FILTER_REJECT}return e.classList?.contains(s)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),o=[];for(;r=a.nextNode();)r.originalParent||(r.originalParent=r.parentNode),o.push(r);return t?o.reverse():o}function f(e,t=!0){return t?d(a(e)):n(e).map(r)}const h=e=>document.createElement(e),y=(e,t="")=>{let n=h("style");n.id=t,n.appendChild(r(e)),document.head.appendChild(n)},p=t=>(e(t)||(t=[t/2,t/2]),t),m=(e,t)=>Math.abs(Math.random()*(e+t-(e-t))+(e-t));let g=e=>e/2;const b=e=>"value"in e;let w=e=>"function"==typeof e?e():e;const T=e=>Number.isInteger(e);let v=(e,t=document,n=!1)=>t["querySelector"+(n?"All":"")](e);const E=(e,t)=>Object.assign({},e,t);let P={"font-family":"","font-weight":"","font-size":"","font-style":"","line-height":"",color:"",transform:"translateX(-.125em)"};const S=(e,t)=>new Array(t).fill(e),N=({queueItems:e,selector:t,cursorPosition:n,to:r})=>{if(T(t))return-1*t;let i=new RegExp("END","i").test(r),a=t?[...e].reverse().findIndex((({char:e})=>{let n=e.parentElement,r=n.matches(t);return!(!i||!r)||r&&n.firstChild.isSameNode(e)})):-1;return a<0&&(a=i?0:e.length-1),a-n+(i?0:1)};let L=e=>new Promise((t=>{requestAnimationFrame((async()=>{t(await e())}))})),C=e=>e?.getAnimations().find((t=>t.id===e.dataset.tiAnimationId)),D=({cursor:e,frames:t,options:n})=>{let r=e.animate(t,n);return r.pause(),r.id=e.dataset.tiAnimationId,L((()=>{L((()=>{r.play()}))})),r},I=e=>e.func?.call(null),M=async({index:e,queueItems:t,wait:n,cursor:r,cursorOptions:i})=>{let a=t[e][1],o=[],s=e,l=a,u=()=>l&&!l.delay,c=a.shouldPauseCursor()&&i.autoPause;for(;u();)o.push(l),u()&&s++,l=t[s]?t[s][1]:null;if(o.length)return await L((async()=>{for(let e of o)await I(e)})),s-1;let d,f=C(r);return f&&(d={...f.effect.getComputedTiming(),delay:c?i.autoPauseDelay:0}),await n((async()=>{f&&c&&f.cancel(),await L((()=>{I(a)}))}),a.delay),await(({cursor:e,options:t,cursorOptions:n})=>{if(!e||!n)return;let r,i=C(e);i&&(t.delay=i.effect.getComputedTiming().delay,r=i.currentTime,i.cancel());let a=D({cursor:e,frames:n.animation.frames,options:t});return r&&(a.currentTime=r),a})({cursor:r,options:d,cursorOptions:i}),e};return function(e,r={}){let L=async(e,t,n=!1)=>{K.frozen&&await new Promise((e=>{this.unfreeze=()=>{K.frozen=!1,e()}})),n||await Y.beforeStep(this),await((e,t,n)=>new Promise((r=>{n.push(setTimeout((async()=>{await e(),r()}),t||0))})))(e,t,W),n||await Y.afterStep(this)},C=(e,t)=>M({index:e,queueItems:t,wait:L,cursor:ne,cursorOptions:Y.cursor}),I=e=>((e,t)=>{if(!e)return;let n=e.parentNode;(n.childNodes.length>1||n.isSameNode(t)?e:n).remove()})(e,J),x=()=>b(J),A=(e=0)=>function(e){let{speed:t,deleteSpeed:n,lifeLike:r}=e;return n=null!==n?n:t/3,r?[m(t,g(t)),m(n,g(n))]:[t,n]}(Y)[e],$=()=>(e=>b(e)?n(e.value):d(e,!0).filter((e=>!(e.childNodes.length>0))))(J),H=(e,t)=>(ee.add(e),((e={})=>{let t=e.delay;t&&ee.add({delay:t})})(t),this),O=()=>G??X,F=(e={})=>[{func:()=>j(e)},{func:()=>j(Y)}],k=e=>{let t=Y.nextStringDelay;ee.add([{delay:t[0]},...e,{delay:t[1]}])},R=async()=>{if(!x()&&ne&&J.appendChild(ne),te){((e,t)=>{let n=`[${o}='${e}'] .${s}`,r=getComputedStyle(t),i=Object.entries(P).reduce(((e,[t,n])=>`${e} ${t}: var(--ti-cursor-${t}, ${n||r[t]});`),"");y(`${n} { display: inline-block; width: 0; ${i} }`,e)})(Z,J),ne.dataset.tiAnimationId=Z;let{animation:e}=Y.cursor,{frames:t,options:n}=e;D({frames:t,cursor:ne,options:{duration:Y.cursorSpeed,...n}})}},q=()=>{let e=Y.strings.filter((e=>!!e));e.forEach(((t,n)=>{if(this.type(t),n+1===e.length)return;let r=Y.breakLines?[{func:()=>_(h("BR")),typeable:!0}]:S({func:Q,delay:ALine truncated
|
||||
@@ -43,9 +43,9 @@ Don't forget to [follow me](https://twitter.com/nunocoracao) on Twitter.
|
||||
`Article` will embed a single article into a markdown file. The `link` to the file should be the `.RelPermalink` of the file to be embedded. Note that the shortcode will not display anything if it's referencing it's parent. *Note: if you are running your website in a subfolder like Blowfish (i.e. /blowfish/) please include that path in the link.*
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
|Parameter|Description|
|
||||
|---|---|
|
||||
|`link`| **Required.** the `.RelPermalink` to the target article.|
|
||||
| Parameter | Description |
|
||||
| --------- | -------------------------------------------------------- |
|
||||
| `link` | **Required.** the `.RelPermalink` to the target article. |
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
**Example:**
|
||||
@@ -135,14 +135,14 @@ When a provided image is a page resource, it will be optimised using Hugo Pipes
|
||||
The `figure` shortcode accepts six parameters:
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
|Parameter|Description|
|
||||
|---|---|
|
||||
|`src`| **Required.** The local path/filename or URL of the image. When providing a path and filename, the theme will attempt to locate the image using the following lookup order: Firstly, as a [page resource](https://gohugo.io/content-management/page-resources/) bundled with the page; then an asset in the `assets/` directory; then finally, a static image in the `static/` directory.|
|
||||
|`alt`|[Alternative text description](https://moz.com/learn/seo/alt-text) for the image.|
|
||||
|`caption`|Markdown for the image caption, which will be displayed below the image.|
|
||||
|`class`|Additional CSS classes to apply to the image.|
|
||||
|`href`|URL that the image should be linked to.|
|
||||
|`default`|Special parameter to revert to default Hugo `figure` behaviour. Simply provide `default=true` and then use normal [Hugo shortcode syntax](https://gohugo.io/content-management/shortcodes/#figure).|
|
||||
| Parameter | Description |
|
||||
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `src` | **Required.** The local path/filename or URL of the image. When providing a path and filename, the theme will attempt to locate the image using the following lookup order: Firstly, as a [page resource](https://gohugo.io/content-management/page-resources/) bundled with the page; then an asset in the `assets/` directory; then finally, a static image in the `static/` directory. |
|
||||
| `alt` | [Alternative text description](https://moz.com/learn/seo/alt-text) for the image. |
|
||||
| `caption` | Markdown for the image caption, which will be displayed below the image. |
|
||||
| `class` | Additional CSS classes to apply to the image. |
|
||||
| `href` | URL that the image should be linked to. |
|
||||
| `default` | Special parameter to revert to default Hugo `figure` behaviour. Simply provide `default=true` and then use normal [Hugo shortcode syntax](https://gohugo.io/content-management/shortcodes/#figure). |
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
Blowfish also supports automatic conversion of images included using standard Markdown syntax. Simply use the following format and the theme will handle the rest:
|
||||
@@ -189,11 +189,11 @@ Icons can also be used in partials by calling the [icon partial]({{< ref "partia
|
||||
`List` will display a list of recent articles. This shortcode requires a limit value to constraint the list. Additionally, it supports a `where` and a `value` in order to filter articles by their parameters. Note that this shortcode will not display its parent page but it will count for the limit value.
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
|Parameter|Description|
|
||||
|---|---|
|
||||
|`limit`| **Required.** the number of recent articles to display.|
|
||||
|`where`| the number of recent articles to display.|
|
||||
|`value`| the number of recent articles to display.|
|
||||
| Parameter | Description |
|
||||
| --------- | ------------------------------------------------------- |
|
||||
| `limit` | **Required.** the number of recent articles to display. |
|
||||
| `where` | the number of recent articles to display. |
|
||||
| `value` | the number of recent articles to display. |
|
||||
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
@@ -285,3 +285,83 @@ B-->C[Profit]
|
||||
{{< /mermaid >}}
|
||||
|
||||
You can see some additional Mermaid examples on the [diagrams and flowcharts samples]({{< ref "diagrams-flowcharts" >}}) page.
|
||||
|
||||
## TypeIt
|
||||
|
||||
[TypeIt](https://www.typeitjs.com) is the most versatile JavaScript tool for creating typewriter effects on the planet. With a straightforward configuration, it allows you to type single or multiple strings that break lines, delete & replace each other, and it even handles strings that contain complex HTML.
|
||||
|
||||
Blowfish implements a sub-set of TypeIt features using a `shortcode`. Write your text within the `typeit` shortcode and use the following parameters to configure the behavior you want.
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| Parameter | Description |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `tag` | [String] `html` tag that will be used to render the strings. |
|
||||
| `classList` | [String] List of `css` classes to apply to the `html` element. |
|
||||
| `initialString` | [String] Initial string that will appear written and will be replaced. |
|
||||
| `speed` | [number] Typing speed, measured in milliseconds between each step. |
|
||||
| `lifeLike` | [boolean] Makes the typing pace irregular, as if a real person is doing it. |
|
||||
| `startDelay` | [number] The amount of time before the plugin begins typing after being initialized. |
|
||||
| `breakLines` | [boolean] Whether multiple strings are printed on top of each other (true), or if they're deleted and replaced by each other (false). |
|
||||
| `waitUntilVisible` | [boolean] Determines if the instance will begin when loaded or only when the target element becomes visible in the viewport. The default is `true` |
|
||||
| `loop` | [boolean] Whether your strings will continuously loop after completing |
|
||||
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```md
|
||||
{{</* typeit */>}}
|
||||
Lorem ipsum dolor sit amet
|
||||
{{</* /typeit */>}}
|
||||
```
|
||||
|
||||
{{< typeit >}}
|
||||
Lorem ipsum dolor sit amet
|
||||
{{< /typeit >}}
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```md
|
||||
{{</* typeit
|
||||
tag=h1
|
||||
lifeLike=true
|
||||
*/>}}
|
||||
Lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing elit.
|
||||
{{</* /typeit */>}}
|
||||
```
|
||||
|
||||
{{< typeit
|
||||
tag=h1
|
||||
lifeLike=true
|
||||
>}}
|
||||
Lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing elit.
|
||||
{{< /typeit >}}
|
||||
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```md
|
||||
{{</* typeit
|
||||
tag=h3
|
||||
speed=50
|
||||
breakLines=false
|
||||
loop=true
|
||||
*/>}}
|
||||
Lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing elit.
|
||||
{{</* /typeit */>}}
|
||||
```
|
||||
{{< typeit
|
||||
tag=h3
|
||||
speed=50
|
||||
breakLines=false
|
||||
loop=true
|
||||
>}}
|
||||
"Frankly, my dear, I don't give a damn." Gone with the Wind (1939)
|
||||
"I'm gonna make him an offer he can't refuse." The Godfather (1972)
|
||||
"Toto, I've a feeling we're not in Kansas anymore." The Wizard of Oz (1939)
|
||||
{{< /typeit >}}
|
||||
@@ -33,4 +33,9 @@
|
||||
{{ range $katexFonts }}
|
||||
<!-- {{ .RelPermalink }} -->
|
||||
{{ end }}
|
||||
{{/* TypeIt */}}
|
||||
{{ if .Page.HasShortcode "typeit" }}
|
||||
{{ $typeitLib := resources.Get "lib/typeit/typeit.umd.js" }}
|
||||
<script defer type="text/javascript" src="{{ $typeitLib.RelPermalink }}" integrity="{{ $typeitLib.Data.Integrity }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,38 @@
|
||||
{{- $content := split .Inner "\n" -}}
|
||||
{{- $initialString := .Get "initialString" | default "" -}}
|
||||
{{- $speed := .Get "speed" | default 100 -}}
|
||||
{{- $lifeLike := .Get "lifeLike" | default false -}}
|
||||
{{- $startDelay := .Get "startDelay" | default 0 -}}
|
||||
{{- $breakLines := .Get "breakLines" | default true -}}
|
||||
{{- $waitUntilVisible := .Get "waitUntilVisible" | default true -}}
|
||||
{{- $loop := .Get "loop" | default false -}}
|
||||
|
||||
{{- $classList := slice -}}
|
||||
{{- with .Get "class" -}}
|
||||
{{- $classList = $classList | append . -}}
|
||||
{{- end -}}
|
||||
{{- $tag := .Get "tag" | default "div" -}}
|
||||
|
||||
{{ $time := now.UnixNano }}
|
||||
{{ $id := delimit (slice "typeit" $time) "-" }}
|
||||
|
||||
{{- $attrs := printf `id="%v"` $id -}}
|
||||
{{- with $classList -}}
|
||||
{{- $attrs = delimit $classList " " | printf `%v class="%v"` $attrs -}}
|
||||
{{- end -}}
|
||||
|
||||
{{ printf `<%v %v>%s</%v>` $tag $attrs $initialString $tag | safeHTML }}
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
new TypeIt("#{{ $id }}", {
|
||||
strings: {{ $content }},
|
||||
speed: {{ $speed }},
|
||||
lifeLike: {{ $lifeLike }},
|
||||
startDelay: {{ $startDelay }},
|
||||
breakLines: {{ $breakLines }},
|
||||
waitUntilVisible: {{ $waitUntilVisible }},
|
||||
loop: {{ $loop }}
|
||||
}).go();
|
||||
});
|
||||
</script>
|
||||
Generated
+16
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "hugo-blowfish-theme",
|
||||
"version": "2.19.1",
|
||||
"version": "2.21.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "hugo-blowfish-theme",
|
||||
"version": "2.19.1",
|
||||
"version": "2.21.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -26,6 +26,7 @@
|
||||
"prettier-plugin-tailwindcss": "^0.2.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"tailwindcss": "^3.2.4",
|
||||
"typeit": "^8.7.1",
|
||||
"vendor-copy": "^3.0.1"
|
||||
}
|
||||
},
|
||||
@@ -1607,6 +1608,13 @@
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/typeit": {
|
||||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/typeit/-/typeit-8.7.1.tgz",
|
||||
"integrity": "sha512-Bx/O4NMz10NWh9FWYtVwV4XwGHF9UDJfpCZPJRtw2/oUcahFAStU8J0t19aroPfTV6s1UlS5ICoqilOqmEnh2Q==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true
|
||||
},
|
||||
"node_modules/ulid": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ulid/-/ulid-2.3.0.tgz",
|
||||
@@ -2799,6 +2807,12 @@
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"typeit": {
|
||||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/typeit/-/typeit-8.7.1.tgz",
|
||||
"integrity": "sha512-Bx/O4NMz10NWh9FWYtVwV4XwGHF9UDJfpCZPJRtw2/oUcahFAStU8J0t19aroPfTV6s1UlS5ICoqilOqmEnh2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"ulid": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ulid/-/ulid-2.3.0.tgz",
|
||||
|
||||
+6
-1
@@ -8,7 +8,7 @@
|
||||
"postinstall": "vendor-copy",
|
||||
"assets": "rimraf assets/vendor && vendor-copy",
|
||||
"dev": "NODE_ENV=development ./node_modules/tailwindcss/lib/cli.js -i ./assets/css/main.css -o ./assets/css/compiled/main.css --jit -w",
|
||||
"build": "NODE_ENV=production ./node_modules/tailwindcss/lib/cli.js -i ./assets/css/main.css -o ./assets/css/compiled/main.css --jit",
|
||||
"build": "NODE_ENV=production ./node_modules/tailwindcss/lib/cli.js -i ./assets/css/main.css -o ./assets/css/compiled/main.css --jit",
|
||||
"build-hugo": "hugo --minify -s exampleSite --themesDir ../.. -d ../docs --baseURL https://nunocoracao.github.io/blowfish/",
|
||||
"example": "hugo server -E -F --minify --source exampleSite --themesDir ../.. --buildDrafts -b http://localhost/ -p 1313",
|
||||
"lighthouse": "lhci autorun"
|
||||
@@ -44,6 +44,7 @@
|
||||
"prettier-plugin-tailwindcss": "^0.2.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"tailwindcss": "^3.2.4",
|
||||
"typeit": "^8.7.1",
|
||||
"vendor-copy": "^3.0.1"
|
||||
},
|
||||
"vendorCopy": [],
|
||||
@@ -75,6 +76,10 @@
|
||||
{
|
||||
"from": "node_modules/fuse.js/dist/fuse.min.js",
|
||||
"to": "assets/lib/fuse/fuse.min.js"
|
||||
},
|
||||
{
|
||||
"from": "node_modules/typeit/dist/index.umd.js",
|
||||
"to": "assets/lib/typeit/typeit.umd.js"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
|
||||
Reference in new issue
Block a user