Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
}
},
"dependencies": {
"@babel/core": "^7.16.0",
"@babel/runtime": "^7.16.0",
"flubber": "~0.4.2",
"hoist-non-react-statics": "~3.0.1",
"lodash.clamp": "~4.0.3",
Expand Down
62 changes: 47 additions & 15 deletions src/components/SvgMask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
} from 'react-native'
import Svg, { PathProps } from 'react-native-svg'
import { IStep, ValueXY } from '../types'
import { svgMaskPathMorph } from '../utilities'
import { svgMaskPathMorph, IS_NATIVE } from '../utilities'
import { AnimatedSvgPath } from './AnimatedPath'

interface Props {
Expand All @@ -37,9 +37,19 @@ interface State {
animation: Animated.Value
canvasSize: ValueXY
previousPath: string
nextSvgPath: string
composedSvgPath: string
viewBoxDimentions: string
}

const IS_WEB = Platform.OS !== 'web'
const getSvgPath = () =>
`M0,0H${Dimensions.get('window').width}V${
Dimensions.get('window').height
}H0V0ZM${Dimensions.get('window').width / 2},${
Dimensions.get('window').height / 2
} h 1 v 1 h -1 Z`
const getViewBoxDimentions = () =>
`0 0 ${Dimensions.get('window').width} ${Dimensions.get('window').height}`

export class SvgMask extends Component<Props, State> {
static defaultProps = {
Expand All @@ -50,11 +60,12 @@ export class SvgMask extends Component<Props, State> {
}

listenerID: string
resizeListenerID: string | null
rafID: number
mask: React.RefObject<PathProps> = React.createRef()

windowDimensions: ScaledSize | null = null
firstPath: string | undefined
windowDimensions: ScaledSize
dimensionsSubscription: any

constructor(props: Props) {
super(props)
Expand All @@ -64,12 +75,6 @@ export class SvgMask extends Component<Props, State> {
default: Dimensions.get('window'),
})

this.firstPath = `M0,0H${this.windowDimensions.width}V${
this.windowDimensions.height
}H0V0ZM${this.windowDimensions.width / 2},${
this.windowDimensions.height / 2
} h 1 v 1 h -1 Z`

this.state = {
canvasSize: {
x: this.windowDimensions.width,
Expand All @@ -79,18 +84,30 @@ export class SvgMask extends Component<Props, State> {
position: props.position,
opacity: new Animated.Value(0),
animation: new Animated.Value(0),
previousPath: this.firstPath,
previousPath: getSvgPath(),
viewBoxDimentions: getViewBoxDimentions(),
nextSvgPath: getSvgPath(),
composedSvgPath: getSvgPath(),
}

this.listenerID = this.state.animation.addListener(this.animationListener)
}

componentDidMount() {
IS_NATIVE
? (this.dimensionsSubscription = Dimensions.addEventListener(
'change',
this.recalculatePath,
))
: window.addEventListener('resize', this.recalculatePath)
}

componentDidUpdate(prevProps: Props) {
if (
prevProps.position !== this.props.position ||
prevProps.size !== this.props.size
) {
this.animate()
this.recalculatePath()
}
}

Expand All @@ -101,6 +118,9 @@ export class SvgMask extends Component<Props, State> {
if (this.rafID) {
cancelAnimationFrame(this.rafID)
}
IS_NATIVE
? this.dimensionsSubscription?.remove()
: window.removeEventListener('resize', this.recalculatePath)
}

getPath = () => {
Expand All @@ -125,7 +145,7 @@ export class SvgMask extends Component<Props, State> {
const d = this.getPath()
this.rafID = requestAnimationFrame(() => {
if (this.mask && this.mask.current) {
if (IS_WEB) {
if (IS_NATIVE) {
// @ts-ignore
this.mask.current.setNativeProps({ d })
} else {
Expand Down Expand Up @@ -181,6 +201,16 @@ export class SvgMask extends Component<Props, State> {
})
}

recalculatePath = () => {
this.setState((state) => ({
...state,
previousPath: getSvgPath(),
viewBoxDimentions: getViewBoxDimentions(),
}))
this.setState((state) => ({ ...state, composedSvgPath: this.getPath() }))
this.animate()
}

render() {
if (!this.state.canvasSize) {
return null
Expand All @@ -199,14 +229,16 @@ export class SvgMask extends Component<Props, State> {
pointerEvents='none'
width={this.state.canvasSize.x}
height={this.state.canvasSize.y}
viewBox={this.state.viewBoxDimentions}
>
<AnimatedSvgPath
ref={this.mask}
fill={this.props.backdropColor}
strokeWidth={0}
fillRule='evenodd'
d={this.firstPath}
opacity={this.state.opacity as any}
d={this.state.composedSvgPath}
// @ts-ignore
opacity={this.state.opacity._value as any}
/>
</Svg>
</Wrapper>
Expand Down
34 changes: 31 additions & 3 deletions src/components/TourGuideProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import mitt from 'mitt'
import * as React from 'react'
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
import {
StyleProp,
StyleSheet,
View,
ViewStyle,
Dimensions,
} from 'react-native'
import { TourGuideContext } from '../components/TourGuideContext'
import { useIsMounted } from '../hooks/useIsMounted'
import { IStep, Labels, StepObject, Steps } from '../types'
Expand Down Expand Up @@ -53,6 +59,8 @@ export const TourGuideProvider = ({
const [steps, setSteps] = useState<Steps>({})
const [canStart, setCanStart] = useState<boolean>(false)

const [windowIsResized, setWindowResized] = useState(false)

const startTries = useRef<number>(0)
const mounted = useIsMounted()

Expand All @@ -67,10 +75,30 @@ export const TourGuideProvider = ({
}, [visible])

useEffect(() => {
if (visible || currentStep) {
if (visible || (windowIsResized && currentStep) || currentStep) {
moveToCurrentStep()
setWindowResized(false)
}
}, [visible, currentStep, windowIsResized])

const setWindowIsResized = () => {
setWindowResized(true)
}

useEffect(() => {
let subscription: any
if (utils.IS_NATIVE) {
subscription = Dimensions.addEventListener('change', setWindowIsResized)
} else {
window.addEventListener('resize', setWindowIsResized)
}

return () => {
utils.IS_NATIVE
? subscription?.remove()
: window.removeEventListener('resize', setWindowIsResized)
}
}, [visible, currentStep])
}, [])

useEffect(() => {
if (mounted) {
Expand Down
15 changes: 10 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
export { TourGuideZone, TourGuideZoneProps } from './components/TourGuideZone'
export { TourGuideProvider, TourGuideProviderProps } from './components/TourGuideProvider'
export { TourGuideContext, ITourGuideContext } from './components/TourGuideContext'
export { Tooltip, TooltipProps } from './components/Tooltip'
export { TourGuideZoneByPosition, TourGuideZoneByPositionProps } from './components/TourGuideZoneByPosition'
export { TourGuideZone } from './components/TourGuideZone'
export { TourGuideProvider } from './components/TourGuideProvider'
export { TourGuideContext } from './components/TourGuideContext'
export { Tooltip } from './components/Tooltip'
export { TourGuideZoneByPosition } from './components/TourGuideZoneByPosition'
export { useTourGuideController } from './hooks/useTourGuideController'
export type { TourGuideZoneProps } from './components/TourGuideZone'
export type { TourGuideProviderProps } from './components/TourGuideProvider'
export type { ITourGuideContext } from './components/TourGuideContext'
export type { TooltipProps } from './components/Tooltip'
export type { TourGuideZoneByPositionProps } from './components/TourGuideZoneByPosition'
export * from './types'
3 changes: 3 additions & 0 deletions src/utilities.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @ts-ignore
import { interpolate, separate, splitPathString, toCircle } from 'flubber'
import { Platform } from 'react-native'
import clamp from 'lodash.clamp'
import memoize from 'memoize-one'
import {
Expand All @@ -12,6 +13,8 @@ import {
ValueXY,
} from './types'

export const IS_NATIVE = Platform.OS !== 'web'

export const getFirstStep = (steps: Steps): IStep | null =>
steps &&
Object.values(steps).reduce(
Expand Down
21 changes: 17 additions & 4 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"include": ["src"],
"include": [
"src"
],
"compilerOptions": {
"declaration": true,
"outDir": "./lib",
Expand Down Expand Up @@ -28,8 +30,19 @@
"resolveJsonModule": true,
"noFallthroughCasesInSwitch": true,
"strictPropertyInitialization": false,
"lib": ["dom", "esnext"],
"typeRoots": ["./node_modules/@types", "./@types"]
"lib": [
"dom",
"esnext"
],
"typeRoots": [
"./node_modules/@types",
"./@types"
]
},
"exclude": ["node_modules", "src/**/*.test.ts", "src/**/*.test.tsx"]
"exclude": [
"node_modules",
"src/**/*.test.ts",
"src/**/*.test.tsx"
],
"extends": "expo/tsconfig.base"
}
Loading