"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[20915],{20915:(n,e,t)=>{t.r(e),t.d(e,{default:()=>s});var i=t(67841),o=t(89207);let s=()=>(0,i.jsx)(o.default,{title:"Play/Pause Demo",layout:"split",size:"wide",splitRatio:.65,minPreviewHeight:"12rem",dependencies:{"use-sound":"4.0.3"},files:{"/App.js":"\nimport React from 'react';\nimport useSound from 'use-sound';\n\nimport PlayButton from './PlayButton';\nimport styles from './PlayPauseDemo.module.css';\n\nconst soundUrl = '/sounds/guitar-loop.mp3';\n\nfunction PlayPauseDemo() {\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [play, { stop }] = useSound(soundUrl, {\n onend: () => setIsPlaying(false),\n });\n\n return (\n {\n play();\n setIsPlaying(true);\n }}\n stop={() => {\n stop();\n setIsPlaying(false);\n }}\n />\n );\n}\n\nexport default PlayPauseDemo;","/PlayButton.js":"\n/*\n NOTE: I wrote this component many many years ago.\n If you want to use it in your own work, I suggest\n re-writing to use hooks.\n*/\nimport React from 'react';\n\nfunction easeOutCubic(\n currentIteration,\n startValue,\n changeInValue,\n totalIterations\n) {\n return (\n changeInValue *\n (Math.pow(currentIteration / totalIterations - 1, 3) + 1) +\n startValue\n );\n}\n\nconst noop = () => {};\n\nfunction getStopIconPoints({ size, progressCircleWidth }) {\n const innerSize = getInnerSize({ size, progressCircleWidth });\n\n return [\n [\n innerSize * 0.3 + progressCircleWidth,\n innerSize * 0.3 + progressCircleWidth,\n ],\n [\n innerSize * 0.3 + progressCircleWidth,\n innerSize * 0.7 + progressCircleWidth,\n ],\n [\n innerSize * 0.7 + progressCircleWidth,\n innerSize * 0.7 + progressCircleWidth,\n ],\n [\n innerSize * 0.7 + progressCircleWidth,\n innerSize * 0.3 + progressCircleWidth,\n ],\n ];\n}\n\nfunction getPlayIconPoints({ size, progressCircleWidth }) {\n const innerSize = getInnerSize({ size, progressCircleWidth });\n\n return [\n [\n (innerSize * 7) / 20 + progressCircleWidth,\n (innerSize * 1) / 4 + progressCircleWidth,\n ],\n [\n (innerSize * 7) / 20 + progressCircleWidth,\n (innerSize * 3) / 4 + progressCircleWidth,\n ],\n [\n (innerSize * 31) / 40 + progressCircleWidth,\n (innerSize * 1) / 2 + progressCircleWidth,\n ],\n [\n (innerSize * 31) / 40 + progressCircleWidth,\n (innerSize * 1) / 2 + progressCircleWidth,\n ],\n ];\n}\n\nfunction getInnerSize({ size, progressCircleWidth }) {\n return size - progressCircleWidth * 2;\n}\n\nclass PlayButton extends React.Component {\n static defaultProps = {\n play: noop,\n stop: noop,\n audioFormat: 'mp3',\n size: 45,\n progressCircleWidth: 4,\n progressCircleColor: '#78A931',\n idleBackgroundColor: '#191b1d',\n activeBackgroundColor: '#191b1d',\n stopIconColor: '#FFFFFF',\n playIconColor: '#FFFFFF',\n iconAnimationLength: 450,\n fadeInLength: 0,\n fadeOutLength: 0,\n };\n\n constructor(props) {\n super(props);\n this.state = {\n progress: 0,\n iconPoints: getPlayIconPoints(props),\n };\n }\n\n UNSAFE_componentWillReceiveProps(nextProps) {\n // Figure out what needs to happen with these new props.\n const justStartedPlaying = !this.props.active && nextProps.active;\n const justStoppedPlaying = this.props.active && !nextProps.active;\n\n if (justStartedPlaying) {\n this.animateIcon('stop');\n } else if (justStoppedPlaying) {\n this.animateIcon('play');\n }\n }\n\n clickHandler = () => {\n this.props.active ? this.props.stop() : this.props.play();\n };\n\n animateIcon = (shape) => {\n const easingFunction = easeOutCubic;\n const startTime = new Date().getTime();\n const animationDuration = this.props.iconAnimationLength;\n const initialPoints = this.state.iconPoints;\n const finalPoints =\n shape === 'stop'\n ? getStopIconPoints(this.props)\n : getPlayIconPoints(this.props);\n\n const updatePosition = () => {\n requestAnimationFrame(() => {\n const time = new Date().getTime() - startTime;\n\n // Our end condition. The time has elapsed, the animation is completed.\n if (time > animationDuration) return;\n\n // Let's figure out where the new points should be.\n // There are a total of 8 numbers to work out (4 points, each with x/y).\n // easiest way is probably just to map through them.\n const newPoints = initialPoints.map((initialPoint, index) => {\n const [initialX, initialY] = initialPoint;\n const [finalX, finalY] = finalPoints[index];\n\n return [\n easingFunction(\n time,\n initialX,\n finalX - initialX,\n animationDuration\n ),\n easingFunction(\n time,\n initialY,\n finalY - initialY,\n animationDuration\n ),\n ];\n });\n\n this.setState(\n {\n iconPoints: newPoints,\n },\n updatePosition\n );\n });\n };\n\n updatePosition();\n };\n\n renderIcon() {\n const { iconColor } = this.props;\n const points = this.state.iconPoints\n .map((p) => p.join(','))\n .join(' ');\n\n return (\n \n );\n }\n\n renderMainCircle() {\n const {\n size,\n idleBackgroundColor,\n activeBackgroundColor,\n } = this.props;\n\n const radius = size / 2;\n\n return (\n \n );\n }\n\n render() {\n const {\n size,\n active,\n play,\n stop,\n className,\n } = this.props;\n\n return (\n (active ? stop() : play())}\n className={className}\n >\n \n {this.renderMainCircle()}\n {this.renderIcon()}\n \n \n );\n }\n}\n\nexport default PlayButton;\n ","/PlayPauseDemo.module.css":{hidden:!1,code:"\n.btn {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: transparent;\n border: none;\n}\n "}}})}}]); //# sourceMappingURL=20915.fbb4f3d1612d8231.js.map