Skip to content

Instantly share code, notes, and snippets.

@iftkharhussain
Forked from pritishvaidya/SoundCloudWave.js
Created March 10, 2023 12:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iftkharhussain/c5bd5a6f8db82d56ee29aedc8191e4a5 to your computer and use it in GitHub Desktop.
Save iftkharhussain/c5bd5a6f8db82d56ee29aedc8191e4a5 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import { View, TouchableOpacity } from 'react-native';
import _ from 'lodash';
import { scaleLinear } from 'd3-scale';
import { mean } from 'd3-array';
const ACTIVE = '#FF1844',
INACTIVE = '#424056',
ACTIVE_PLAYABLE = '#1b1b26'
const ACTIVE_INVERSE = '#4F1224',
ACTIVE_PLAYABLE_INVERSE = '#131116',
INACTIVE_INVERSE = '#1C1A27'
function getColor(
bars,
bar,
percentPlayed,
percentPlayable,
inverse
) {
if(bar/bars.length < percentPlayed) {
return inverse ? ACTIVE : ACTIVE_INVERSE
} else if(bar/bars.length < percentPlayable) {
return inverse ? ACTIVE_PLAYABLE : ACTIVE_PLAYABLE_INVERSE
} else {
return inverse ? INACTIVE : INACTIVE_INVERSE
}
}
const Waveform =
(
{
waveform,
height,
width,
setTime,
percentPlayed,
percentPlayable,
inverse
}
) => {
const scaleLinearHeight = scaleLinear().domain([0, waveform.height]).range([0, height]);
const chunks = _.chunk(waveform.samples, waveform.width/((width - 60)/3))
return (
<View style={[{
height,
width,
justifyContent: 'center',
flexDirection: 'row',
},
inverse && {
transform: [
{ rotateX: '180deg' },
{ rotateY: '0deg'},
]
}
]}>
{chunks.map((chunk, i) => (
<TouchableOpacity key={i} onPress={() => {
setTime(i)
}}>
<View style={{
backgroundColor: getColor(chunks, i, percentPlayed, percentPlayable, inverse),
width: 2,
marginRight: 1,
height: scaleLinearHeight(mean(chunk))
}}
/>
</TouchableOpacity>
))}
</View>
)
}
class SoundCloudWave extends Component {
state = {
waveform: null
}
componentDidMount () {
const { waveformUrl } = this.props;
fetch(waveformUrl.replace('png', 'json'))
.then(res => res.json())
.then(json => {
this.setState({
waveform: json,
waveformUrl
})
});
}
render() {
if (!this.state.waveform) return null;
const {height, width, percentPlayed, percentPlayable} = this.props
const { waveform } = this.state
return (
<View style={{flex: 1, justifyContent: 'center'}}>
<Waveform
waveform={waveform}
height={height}
width={width}
setTime={this.props.setTime}
percentPlayed={percentPlayed}
percentPlayable={percentPlayable}
inverse
/>
<Waveform
waveform={waveform}
height={height}
width={width}
setTime={this.props.setTime}
percentPlayed={percentPlayed}
percentPlayable={percentPlayable}
inverse={false}
/>
</View>
)
}
}
export default SoundCloudWave;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment