-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: introducing `Text` * chore: update readme * chore: remove dep to peer dependency --------- Co-authored-by: VishaL <119810373+vis-prime@users.noreply.github.com>
- Loading branch information
1 parent
60726e1
commit 7858fb0
Showing
7 changed files
with
359 additions
and
2 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import { Setup } from '../Setup' | ||
import { Meta } from '@storybook/html' | ||
import { OrbitControls } from 'three-stdlib' | ||
import { GUI } from 'lil-gui' | ||
import { Text, TextProps, TextType } from '../../src/core/Text' | ||
|
||
export default { | ||
title: 'Abstractions/Text', | ||
} as Meta | ||
|
||
let gui: GUI | ||
|
||
let textGlobal: TextType | ||
let runtimeParams = { | ||
animate: false, | ||
} | ||
|
||
const textParams: TextProps = { | ||
color: '#ff0000', | ||
text: ` | ||
LOREM IPSUM DOLOR SIT AMET, CONSECTETUR ADIPISCING ELIT, | ||
SED DO EIUSMOD TEMPOR INCIDIDUNT UT LABORE ET DOLORE MAGNA ALIQUA. | ||
UT ENIM AD MINIM VENIAM, QUIS NOSTRUD EXERCITATION ULLAMCO LABORIS | ||
NISI UT ALIQUIP EX EA COMMODO CONSEQUAT. DUIS AUTE IRURE DOLOR IN | ||
REPREHENDERIT IN VOLUPTATE VELIT ESSE CILLUM DOLORE EU FUGIAT NULLA PARIATUR. | ||
EXCEPTEUR SINT OCCAECAT CUPIDATAT NON PROIDENT, | ||
SUNT IN CULPA QUI OFFICIA DESERUNT MOLLIT ANIM ID EST LABORUM.`, | ||
fontSize: 2, | ||
maxWidth: 40, | ||
lineHeight: 1, | ||
outlineWidth: 0.2, | ||
outlineColor: '#ffffff', | ||
outlineBlur: 0, | ||
strokeWidth: 0, | ||
strokeColor: '#0000ff', | ||
} | ||
|
||
const setupText = () => { | ||
const text = (textGlobal = Text(textParams)) | ||
|
||
const mesh = text.mesh | ||
|
||
return mesh | ||
} | ||
|
||
export const TextStory = async () => { | ||
gui = new GUI({ title: 'Text Story', closeFolders: true }) | ||
const { renderer, scene, camera, render } = Setup() | ||
renderer.shadowMap.enabled = true | ||
camera.position.set(0, 0, 70) | ||
const controls = new OrbitControls(camera, renderer.domElement) | ||
controls.target.set(0, 0, 0) | ||
controls.update() | ||
|
||
const textMesh = setupText() | ||
scene.add(textMesh) | ||
|
||
render(() => { | ||
if (runtimeParams.animate) textMesh.rotation.y += 0.01 | ||
}) | ||
|
||
addOutlineGui() | ||
} | ||
|
||
TextStory.storyName = 'Default' | ||
|
||
const addOutlineGui = () => { | ||
const params = Object.assign({}, textParams) | ||
const folder = gui.addFolder('T E X T') | ||
folder.open().onChange(() => { | ||
textGlobal.updateProps(params) | ||
}) | ||
folder.add(runtimeParams, 'animate') | ||
folder.addColor(params, 'color') | ||
folder.add(params, 'fontSize', 0, 4, 0.1) | ||
folder.add(params, 'maxWidth', 0, 100, 1) | ||
folder.add(params, 'outlineWidth', 0, 10, 0.1) | ||
folder.addColor(params, 'outlineColor') | ||
folder.add(params, 'strokeWidth', 0, 10, 0.1) | ||
folder.addColor(params, 'strokeColor') | ||
folder.add(params, 'outlineBlur', 0, 4, 0.1) | ||
} | ||
|
||
const preloadParams: TextProps = { | ||
color: '#ff0000', | ||
text: ` | ||
LOREM IPSUM DOLOR SIT AMET, CONSECTETUR ADIPISCING ELIT, | ||
SED DO EIUSMOD TEMPOR INCIDIDUNT UT LABORE ET DOLORE MAGNA ALIQUA. | ||
UT ENIM AD MINIM VENIAM, QUIS NOSTRUD EXERCITATION ULLAMCO LABORIS | ||
NISI UT ALIQUIP EX EA COMMODO CONSEQUAT. DUIS AUTE IRURE DOLOR IN | ||
REPREHENDERIT IN VOLUPTATE VELIT ESSE CILLUM DOLORE EU FUGIAT NULLA PARIATUR. | ||
EXCEPTEUR SINT OCCAECAT CUPIDATAT NON PROIDENT, | ||
SUNT IN CULPA QUI OFFICIA DESERUNT MOLLIT ANIM ID EST LABORUM.`, | ||
fontSize: 2, | ||
maxWidth: 40, | ||
lineHeight: 1, | ||
font: '/font/Kalam-Regular.ttf', | ||
characters: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!?.,:;\'"()[]{}<>|/@\\^$-%+=#_&~*', | ||
onPreloadEnd: () => { | ||
console.log('loaded') | ||
}, | ||
} | ||
|
||
export const TextPreloadFontStory = () => { | ||
const { renderer, scene, camera, render } = Setup() | ||
renderer.shadowMap.enabled = true | ||
camera.position.set(0, 0, 70) | ||
const controls = new OrbitControls(camera, renderer.domElement) | ||
controls.target.set(0, 0, 0) | ||
controls.update() | ||
|
||
const text = Text(preloadParams) | ||
|
||
const mesh = text.mesh | ||
|
||
scene.add(mesh) | ||
} | ||
|
||
TextPreloadFontStory.storyName = 'PreloadFont' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// @ts-ignore | ||
import { Text as TextMeshImpl, preloadFont } from 'troika-three-text' | ||
|
||
export type TextProps = { | ||
/** The content of text */ | ||
text: string | ||
characters?: string | ||
color?: number | string | ||
/** Font size, default: 1 */ | ||
fontSize?: number | ||
maxWidth?: number | ||
lineHeight?: number | ||
letterSpacing?: number | ||
textAlign?: 'left' | 'right' | 'center' | 'justify' | ||
font?: string | ||
anchorX?: number | 'left' | 'center' | 'right' | ||
anchorY?: number | 'top' | 'top-baseline' | 'middle' | 'bottom-baseline' | 'bottom' | ||
clipRect?: [number, number, number, number] | ||
depthOffset?: number | ||
direction?: 'auto' | 'ltr' | 'rtl' | ||
overflowWrap?: 'normal' | 'break-word' | ||
whiteSpace?: 'normal' | 'overflowWrap' | 'nowrap' | ||
outlineWidth?: number | string | ||
outlineOffsetX?: number | string | ||
outlineOffsetY?: number | string | ||
outlineBlur?: number | string | ||
outlineColor?: number | string | ||
outlineOpacity?: number | ||
strokeWidth?: number | string | ||
strokeColor?: number | string | ||
strokeOpacity?: number | ||
fillOpacity?: number | ||
sdfGlyphSize?: number | ||
debugSDF?: boolean | ||
onSync?: (troika: any) => void | ||
onPreloadEnd?: () => void | ||
} | ||
|
||
const externalProps = ['onSync', 'onPreloadEnd', 'characters'] | ||
|
||
function removeExternalProps(props: Partial<TextProps>) { | ||
return Object.keys(props).reduce((result, key) => { | ||
if (externalProps.indexOf(key) === -1) { | ||
result[key] = props[key] | ||
} | ||
return result | ||
}, {} as Partial<TextProps>) | ||
} | ||
|
||
export type TextType = { | ||
mesh: THREE.Mesh | ||
updateProps: (newProps: Partial<TextProps>) => void | ||
dispose: () => void | ||
} | ||
|
||
export const Text = ({ | ||
sdfGlyphSize = 64, | ||
anchorX = 'center', | ||
anchorY = 'middle', | ||
fontSize = 1, | ||
...restProps | ||
}: TextProps): TextType => { | ||
const props: TextProps = { | ||
sdfGlyphSize, | ||
anchorX, | ||
anchorY, | ||
fontSize, | ||
...restProps, | ||
} | ||
const troikaMesh = new TextMeshImpl() | ||
|
||
Object.assign(troikaMesh, removeExternalProps(props)) | ||
|
||
if (props.font && props.characters) { | ||
preloadFont( | ||
{ | ||
font: props.font, | ||
characters: props.characters, | ||
}, | ||
() => { | ||
props.onPreloadEnd && props.onPreloadEnd() | ||
} | ||
) | ||
} | ||
|
||
return { | ||
mesh: troikaMesh, | ||
updateProps(newProps) { | ||
Object.assign(troikaMesh, removeExternalProps(newProps)) | ||
troikaMesh.sync(() => { | ||
props.onSync && props.onSync(troikaMesh) | ||
}) | ||
}, | ||
dispose() { | ||
troikaMesh.dispose() | ||
}, | ||
} | ||
} |
Oops, something went wrong.