@dblatcher/funny-face
Advanced tools
Comparing version 0.1.7 to 0.1.8
@@ -7,3 +7,3 @@ import 'core-js/modules/es.array.iterator.js'; | ||
import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; | ||
import { useState, useRef, useEffect, Component } from 'react'; | ||
import { useState, useRef, useEffect, useCallback, Component } from 'react'; | ||
import 'core-js/modules/es.object.assign.js'; | ||
@@ -197,2 +197,25 @@ | ||
}; | ||
const getBlankExpression = () => ({ | ||
mouth: {}, | ||
rightEye: {}, | ||
leftEye: {} | ||
}); | ||
const cloneExpression = expression => { | ||
if (!expression) { | ||
return getBlankExpression(); | ||
} | ||
return { | ||
mouth: Object.assign({}, expression.mouth), | ||
rightEye: Object.assign({}, expression.rightEye), | ||
leftEye: Object.assign({}, expression.leftEye) | ||
}; | ||
}; | ||
const expressionWithBlink = (blinking, expression) => { | ||
const modifiedExpression = cloneExpression(expression); | ||
if (blinking) { | ||
modifiedExpression.leftEye.open = 0; | ||
modifiedExpression.rightEye.open = 0; | ||
} | ||
return modifiedExpression; | ||
}; | ||
@@ -683,3 +706,3 @@ class IdGen { | ||
direction: direction, | ||
transitionTime: _transitionTime | ||
transitionTime: _transitionTime / 2 | ||
}), jsx(Eye, { | ||
@@ -693,3 +716,3 @@ ident: ident + '-eye-right', | ||
direction: direction, | ||
transitionTime: _transitionTime | ||
transitionTime: _transitionTime / 2 | ||
}), jsx(EyeBrow, { | ||
@@ -823,5 +846,8 @@ x: -eyeX, | ||
accessories = [], | ||
children | ||
children, | ||
blinkPeriod = 20 | ||
}) { | ||
const [talkingMouth, setTalkingMouth] = useState({}); | ||
const [blinkTime, setBlinkTime] = useState(randomInt(blinkPeriod)); | ||
const blinking = blinkPeriod !== 0 && blinkTime <= 1; | ||
const talk = () => { | ||
@@ -846,2 +872,10 @@ setTalkingMouth({ | ||
}, [delay]); | ||
const blinkCountdown = useCallback(() => { | ||
const newBlinkTime = blinkTime <= 0 ? blinkPeriod : blinkTime - 1; | ||
setBlinkTime(newBlinkTime); | ||
}, [setBlinkTime, blinkTime, blinkPeriod]); | ||
useEffect(() => { | ||
const id = setInterval(blinkCountdown, 100); | ||
return () => clearInterval(id); | ||
}, [blinkCountdown]); | ||
const arrangement = talking ? talkingMouth : (expression === null || expression === void 0 ? void 0 : expression.mouth) || {}; | ||
@@ -860,3 +894,3 @@ const chinLevel = getChinLevel(arrangement, profile); | ||
ident: uniqueId.generate('head'), | ||
expression: expression, | ||
expression: expressionWithBlink(blinking, expression), | ||
talking: talking, | ||
@@ -1028,2 +1062,3 @@ followMouse: followMouse, | ||
accessoryKeys: [], | ||
blinkPeriod: 20, | ||
profile: { | ||
@@ -1085,3 +1120,4 @@ width: 1, | ||
accessoryKeys, | ||
profile | ||
profile, | ||
blinkPeriod | ||
} = this.state; | ||
@@ -1107,2 +1143,3 @@ return jsxs("div", { | ||
followMouse: followMouse, | ||
blinkPeriod: blinkPeriod, | ||
profile: profile, | ||
@@ -1144,2 +1181,16 @@ accessories: this.wornAccessories | ||
})] | ||
}), jsx("div", { | ||
children: jsx(NumberInput, { | ||
label: 'blinkPeriod', | ||
value: blinkPeriod, | ||
min: 0, | ||
max: 100, | ||
step: 1, | ||
inputHandler: value => { | ||
this.setState({ | ||
blinkPeriod: value | ||
}); | ||
}, | ||
labelAfter: true | ||
}) | ||
})] | ||
@@ -1146,0 +1197,0 @@ }), jsxs("section", { |
{ | ||
"name": "@dblatcher/funny-face", | ||
"version": "0.1.7", | ||
"version": "0.1.8", | ||
"peerDependencies": { | ||
@@ -5,0 +5,0 @@ "core-js": "3.33.0" |
# funny-face-lib | ||
This library was generated with [Nx](https://nx.dev). | ||
This is a react component library for adding customisable, animated faces to your project. | ||
## Running unit tests | ||
## installation | ||
Run `nx test funny-face-lib` to execute the unit tests via [Jest](https://jestjs.io). | ||
npm: | ||
`npm i @dblatcher/funny-face` | ||
yarn: | ||
`yarn add @dblatcher/funny-face` | ||
## Example usage | ||
```JSX | ||
import { | ||
FunnyFace, | ||
browShapes, | ||
expressions, | ||
} from 'funny-face-lib'; | ||
export const MyComponentWithFaces = () => ( | ||
<div> | ||
<FunnyFace | ||
size={20} | ||
expression={expressions.HAPPY} | ||
profile ={ | ||
eyeColor:"green", | ||
browShape: browShapes.THIN, | ||
} | ||
/> | ||
<FunnyFace | ||
size={24} | ||
talking | ||
profile ={ | ||
eyeColor:"blue", | ||
width: 0.7, | ||
browShape: browShapes.WIDE, | ||
} | ||
/> | ||
</div> | ||
) | ||
``` | ||
<div style="display:flex;"> | ||
<svg x="0" y="0" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"><g><svg x="-50" y="-50" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"><rect x="-50" y="-50" width="100" height="100" stroke="black" fill="lightgreen" rx="25" ry="25" style="height: 100px; transition: height 0.5s ease 0s;"></rect><svg x="-50" y="-50" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"><rect x="-5" y2="-50" width="10" height="10" stroke="black" fill="none" ry="20"></rect></svg><svg x="-27.5" y="-22.5" width="25" height="25" viewBox="-50 -50 100 100" style="overflow: visible;"><mask id="head-392773-eye-left-mask"><rect fill="black" x="-50" y="-50" width="100" height="100"></rect><ellipse fill="white" style="cx: 0px; cy: 0px; rx: 50px; ry: 37.5px; transition: ry 0.25s ease 0s;"></ellipse></mask><ellipse fill="white" style="cx: 0px; cy: 0px; rx: 50px; ry: 37.5px; transition: ry 0.25s ease 0s;"></ellipse><ellipse mask="url(#head-392773-eye-left-mask)" style="fill: brown; cx: 20px; cy: -9.44622px; rx: 30px; transition: rx 0.25s ease 0s, cy 0.25s ease 0s, cx 0.25s ease 0s;"></ellipse><ellipse mask="url(#head-392773-eye-left-mask)" style="fill: black; stroke-width: 2; cx: 20px; cy: -9.44622px; rx: 15px; transition: rx 0.25s ease 0s, cy 0.25s ease 0s, cx 0.25s ease 0s;"></ellipse></svg><svg x="2.5" y="-22.5" width="25" height="25" viewBox="-50 -50 100 100" style="overflow: visible;"><mask id="head-392773-eye-right-mask"><rect fill="black" x="-50" y="-50" width="100" height="100"></rect><ellipse fill="white" style="cx: 0px; cy: 0px; rx: 50px; ry: 37.5px; transition: ry 0.25s ease 0s;"></ellipse></mask><ellipse fill="white" style="cx: 0px; cy: 0px; rx: 50px; ry: 37.5px; transition: ry 0.25s ease 0s;"></ellipse><ellipse mask="url(#head-392773-eye-right-mask)" style="fill: brown; cx: 20px; cy: -9.44622px; rx: 30px; transition: rx 0.25s ease 0s, cy 0.25s ease 0s, cx 0.25s ease 0s;"></ellipse><ellipse mask="url(#head-392773-eye-right-mask)" style="fill: black; stroke-width: 2; cx: 20px; cy: -9.44622px; rx: 15px; transition: rx 0.25s ease 0s, cy 0.25s ease 0s, cx 0.25s ease 0s;"></ellipse></svg><svg x="-30" y="-40" width="30" height="30" viewBox="-50 -50 100 100" style="overflow: visible;"><path d="M -37.5 0 L 30 0 L 37.5 15 L -37.5 0" style="transform: translateY(0%) rotateZ(0deg); transition: transform 0.5s ease 0s; fill: black;"></path></svg><svg x="0" y="-40" width="30" height="30" viewBox="-50 -50 100 100" style="overflow: visible;"><path d="M 37.5 0 L -30 0 L -37.5 15 L 37.5 0" style="transform: translateY(0%) rotateZ(0deg); transition: transform 0.5s ease 0s; fill: black;"></path></svg><svg x="-20" y="0" width="40" height="40" viewBox="-50 -50 100 100" style="overflow: visible;"><mask id="head-392773-mouth-mask"><rect fill="black" x="-50" y="-50" width="100" height="100"></rect><path fill="white" style="d: path("M -50 0 Q 0 0 50 0 Q 0 0 -50 0"); transition: d 0.5s ease 0s;"></path></mask><path style="d: path("M -50 0 Q 0 0 50 0 Q 0 0 -50 0"); transition: d 0.5s ease 0s; stroke: none; fill: black;"></path><g mask="url(#head-392773-mouth-mask)"><path d="M -50 -20 L -50 -3.333333333333332 L -33.33333333333333 -3.333333333333332 L -33.33333333333333 -20" stroke="black" fill="white"></path><path d="M -33.33333333333333 -20 L -31.66666666666666 -3.333333333333332 L -24.999999999999993 0 L -18.33333333333333 -3.333333333333332 L -16.66666666666666 -20" stroke="black" fill="white"></path><path d="M -16.666666666666664 -20 L -16.666666666666664 -0.8333333333333321 L 3.552713678800501e-15 -0.8333333333333321 L 3.552713678800501e-15 -20" stroke="black" fill="white"></path><path d="M 0 -20 L 0 -0.8333333333333321 L 16.666666666666668 -0.8333333333333321 L 16.666666666666668 -20" stroke="black" fill="white"></path><path d="M 16.66666666666667 -20 L 18.33333333333334 -3.333333333333332 L 25.000000000000007 0 L 31.66666666666667 -3.333333333333332 L 33.33333333333334 -20" stroke="black" fill="white"></path><path d="M 33.33333333333334 -20 L 33.33333333333334 -3.333333333333332 L 50.000000000000014 -3.333333333333332 L 50.000000000000014 -20" stroke="black" fill="white"></path></g><path style="d: path("M -50 0 Q 0 0 50 0 Q 0 0 -50 0"); transition: d 0.5s ease 0s; stroke: pink; fill: none; stroke-width: 3; stroke-linejoin: round;"></path><path style="d: path("M 50 0 Q 0 0 -50 0 Q 0 0 50 0"); transition: d 0.5s ease 0s; stroke: pink; fill: none; stroke-width: 3; stroke-linejoin: round;"></path><path style="d: path("M -50 0 Q 0 0 50 0"); transition: d 0.5s ease 0s, opacity 0.5s ease 0s; stroke: black; fill: none; stroke-width: 1; opacity: 1;"></path></svg><svg x="-50" y="-10" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"><rect x="-15" y2="-50" width="30" height="20" stroke="black" fill="lightgreen" rx="10" ry="20" style="transition: transform 0.5s ease 0s; transform: translateY(0px);"></rect></svg></svg><svg x="-50" y="-50" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"></svg></g></svg> | ||
<svg x="20" y="50" width="80" height="80" viewBox="-50 -50 100 100" style="overflow: visible;"><g><svg x="-50" y="-50" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"><rect x="-40" y="-50" width="80" height="100" stroke="black" fill="#999999" rx="30" ry="30" style="height: 109.812px; transition: height 0.5s ease 0s;"></rect><svg x="-50" y="-50" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"><rect x="-10" y2="-50" width="20" height="20" stroke="black" fill="none" ry="20"></rect></svg><svg x="-32.5" y="-22.5" width="25" height="25" viewBox="-50 -50 100 100" style="overflow: visible;"><mask id="head-441079-eye-left-mask"><rect fill="black" x="-50" y="-50" width="100" height="100"></rect><ellipse fill="white" style="cx: 0px; cy: 0px; rx: 50px; ry: 37.5px; transition: ry 0.25s ease 0s;"></ellipse></mask><ellipse fill="white" style="cx: 0px; cy: 0px; rx: 50px; ry: 37.5px; transition: ry 0.25s ease 0s;"></ellipse><ellipse mask="url(#head-441079-eye-left-mask)" style="fill: rgb(0, 153, 153); cx: 20px; cy: -0.0382769px; rx: 30px; transition: rx 0.25s ease 0s, cy 0.25s ease 0s, cx 0.25s ease 0s;"></ellipse><ellipse mask="url(#head-441079-eye-left-mask)" style="fill: black; stroke-width: 2; cx: 20px; cy: -0.0382769px; rx: 15px; transition: rx 0.25s ease 0s, cy 0.25s ease 0s, cx 0.25s ease 0s;"></ellipse></svg><svg x="7.5" y="-22.5" width="25" height="25" viewBox="-50 -50 100 100" style="overflow: visible;"><mask id="head-441079-eye-right-mask"><rect fill="black" x="-50" y="-50" width="100" height="100"></rect><ellipse fill="white" style="cx: 0px; cy: 0px; rx: 50px; ry: 37.5px; transition: ry 0.25s ease 0s;"></ellipse></mask><ellipse fill="white" style="cx: 0px; cy: 0px; rx: 50px; ry: 37.5px; transition: ry 0.25s ease 0s;"></ellipse><ellipse mask="url(#head-441079-eye-right-mask)" style="fill: rgb(0, 153, 153); cx: 20px; cy: -0.0382769px; rx: 30px; transition: rx 0.25s ease 0s, cy 0.25s ease 0s, cx 0.25s ease 0s;"></ellipse><ellipse mask="url(#head-441079-eye-right-mask)" style="fill: black; stroke-width: 2; cx: 20px; cy: -0.0382769px; rx: 15px; transition: rx 0.25s ease 0s, cy 0.25s ease 0s, cx 0.25s ease 0s;"></ellipse></svg><svg x="-35" y="-40" width="30" height="30" viewBox="-50 -50 100 100" style="overflow: visible;"><path d="M -60 -15 L 30 0 L 37.5 15 L 0 3.75 L -37.5 7.5" style="transform: translateY(-10%) rotateZ(0deg); transition: transform 0.5s ease 0s; fill: rgb(99, 69, 69);"></path></svg><svg x="5" y="-40" width="30" height="30" viewBox="-50 -50 100 100" style="overflow: visible;"><path d="M 60 -15 L -30 0 L -37.5 15 L 0 3.75 L 37.5 7.5" style="transform: translateY(-10%) rotateZ(0deg); transition: transform 0.5s ease 0s; fill: rgb(99, 69, 69);"></path></svg><svg x="-25" y="10" width="50" height="50" viewBox="-50 -50 100 100" style="overflow: visible;"><mask id="head-441079-mouth-mask"><rect fill="black" x="-50" y="-50" width="100" height="100"></rect><path fill="white" style="d: path("M -50 -15 Q 0 -16.75 50 -15 Q 0 39.25 -50 -15"); transition: d 0.5s ease 0s;"></path></mask><path style="d: path("M -50 -15 Q 0 -16.75 50 -15 Q 0 39.25 -50 -15"); transition: d 0.5s ease 0s; stroke: none; fill: black;"></path><g mask="url(#head-441079-mouth-mask)"><path d="M -50 -20 L -50 -3.333333333333332 L -33.33333333333333 -3.333333333333332 L -33.33333333333333 -20" stroke="black" fill="white"></path><path d="M -33.33333333333333 -20 L -31.66666666666666 -3.333333333333332 L -24.999999999999993 0 L -18.33333333333333 -3.333333333333332 L -16.66666666666666 -20" stroke="black" fill="white"></path><path d="M -16.666666666666664 -20 L -16.666666666666664 -0.8333333333333321 L 3.552713678800501e-15 -0.8333333333333321 L 3.552713678800501e-15 -20" stroke="black" fill="white"></path><path d="M 0 -20 L 0 -0.8333333333333321 L 16.666666666666668 -0.8333333333333321 L 16.666666666666668 -20" stroke="black" fill="white"></path><path d="M 16.66666666666667 -20 L 18.33333333333334 -3.333333333333332 L 25.000000000000007 0 L 31.66666666666667 -3.333333333333332 L 33.33333333333334 -20" stroke="black" fill="white"></path><path d="M 33.33333333333334 -20 L 33.33333333333334 -3.333333333333332 L 50.000000000000014 -3.333333333333332 L 50.000000000000014 -20" stroke="black" fill="white"></path></g><path style="d: path("M -50 -15 Q 0 -16.75 50 -15 Q 0 39.25 -50 -15"); transition: d 0.5s ease 0s; stroke: rgb(144, 0, 0); fill: none; stroke-width: 3; stroke-linejoin: round;"></path><path style="d: path("M 50 -15 Q 0 -16.75 -50 -15 Q 0 39.25 50 -15"); transition: d 0.5s ease 0s; stroke: rgb(144, 0, 0); fill: none; stroke-width: 3; stroke-linejoin: round;"></path><path style="d: path("M -50 -15 Q 0 11.25 50 -15"); transition: d 0.5s ease 0s, opacity 0.5s ease 0s; stroke: black; fill: none; stroke-width: 1; opacity: 0;"></path></svg><svg x="-50" y="-10" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"><rect x="-15" y2="-50" width="30" height="20" stroke="black" fill="#999999" rx="10" ry="20" style="transition: transform 0.5s ease 0s; transform: translateY(9.8125px);"></rect></svg></svg><svg x="-50" y="-50" width="100" height="100" viewBox="-50 -50 100 100" style="overflow: visible;"></svg></g></svg> | ||
</div> |
@@ -14,4 +14,6 @@ import { ReactNode } from 'react'; | ||
transitionTime?: number; | ||
/** how long between each blink, in units of 100ms. Set to zero to prevent blinking Defaults to 20 (blink every two seconds) */ | ||
blinkPeriod?: number; | ||
} | ||
export declare function FunnyFace({ x, y, size, expression, talking, followMouse, transitionTime, profile, accessories, children, }: Props): import("react/jsx-runtime").JSX.Element; | ||
export declare function FunnyFace({ x, y, size, expression, talking, followMouse, transitionTime, profile, accessories, children, blinkPeriod, }: Props): import("react/jsx-runtime").JSX.Element; | ||
export {}; |
@@ -8,3 +8,3 @@ import { ChangeEventHandler, Component } from 'react'; | ||
} | ||
export declare class UIForFunnyFace extends Component<Props, { | ||
interface State { | ||
expressionKey: string; | ||
@@ -14,4 +14,6 @@ talking: boolean; | ||
accessoryKeys: string[]; | ||
blinkPeriod: number; | ||
profile: FaceProfile; | ||
}> { | ||
} | ||
export declare class UIForFunnyFace extends Component<Props, State> { | ||
constructor(props: Props); | ||
@@ -18,0 +20,0 @@ get expression(): FacialExpression; |
@@ -1,3 +0,4 @@ | ||
import { MouthArrangement, FaceProfile, LipCoordinates } from '../types'; | ||
import { MouthArrangement, FaceProfile, LipCoordinates, FacialExpression } from '../types'; | ||
export declare const getLipCoordinates: (arrangment?: MouthArrangement) => LipCoordinates; | ||
export declare const getChinLevel: (arrangement?: MouthArrangement, profile?: FaceProfile) => number; | ||
export declare const expressionWithBlink: (blinking: boolean, expression: FacialExpression | undefined) => FacialExpression; |
78093
1726
51