mirror of
https://github.com/jcreek/SelectionWheel.git
synced 2026-07-14 11:43:43 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f20995a879 | |||
| 84e1e39f9c | |||
| 7783162127 | |||
| f1efac7c7f | |||
| d8fe76f62c | |||
| b9a40bb8a5 | |||
| ff58967c8c | |||
| d15f55b94b | |||
| d411a76c49 | |||
| 546c647234 | |||
| e7f80e1885 | |||
| 5dc201eac7 | |||
| bd7ef970b9 | |||
| 0d641c4f66 | |||
| 983b097a3c | |||
| 86b94e2e6a | |||
| 9e56971116 |
Generated
+212
-460
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "SelectionWheel",
|
"name": "SelectionWheel",
|
||||||
"version": "1.4.0",
|
"version": "1.5.0",
|
||||||
"description": "A fun and simple selection wheel.",
|
"description": "A fun and simple selection wheel.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -38,8 +38,10 @@
|
|||||||
"workbox-cli": "^6.5.4"
|
"workbox-cli": "^6.5.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fireworks-js/web": "^2.5.1",
|
||||||
"@types/d3": "^7.4.0",
|
"@types/d3": "^7.4.0",
|
||||||
"d3": "^7.6.1",
|
"d3": "^7.6.1",
|
||||||
|
"fireworks-js": "^2.5.1",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
"react-dev-utils": "^12.0.1",
|
"react-dev-utils": "^12.0.1",
|
||||||
"webpack-manifest-plugin": "^5.0.0",
|
"webpack-manifest-plugin": "^5.0.0",
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,17 @@
|
|||||||
|
export default {
|
||||||
|
pauseAudio(audio: HTMLAudioElement) {
|
||||||
|
audio.pause();
|
||||||
|
},
|
||||||
|
playAudio(audio: HTMLAudioElement) {
|
||||||
|
audio.play();
|
||||||
|
},
|
||||||
|
stopAudio(audio: HTMLAudioElement) {
|
||||||
|
audio.pause();
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
audio.currentTime = 0;
|
||||||
|
},
|
||||||
|
toggleMute(audio: HTMLAudioElement) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
audio.muted = !audio.muted;
|
||||||
|
},
|
||||||
|
};
|
||||||
+70
-10
@@ -1,11 +1,39 @@
|
|||||||
import * as d3 from 'd3';
|
import * as d3 from 'd3';
|
||||||
|
import { Fireworks } from 'fireworks-js';
|
||||||
import loadServiceWorker from './loadServiceWorker';
|
import loadServiceWorker from './loadServiceWorker';
|
||||||
|
import audioControls from './audioControls';
|
||||||
|
import spinnerMp3 from './assets/spinner-sound.mp3';
|
||||||
|
import tadaMp3 from './assets/tada-fanfare.mp3';
|
||||||
|
|
||||||
require('./assets/favicon.ico');
|
require('./assets/favicon.ico');
|
||||||
require('./assets/android-chrome-192x192.png');
|
require('./assets/android-chrome-192x192.png');
|
||||||
require('./assets/android-chrome-512x512.png');
|
require('./assets/android-chrome-512x512.png');
|
||||||
|
require('./assets/apple-touch-icon.png');
|
||||||
|
require('./assets/favicon-16x16.png');
|
||||||
|
require('./assets/favicon-32x32.png');
|
||||||
require('./styles/main.scss');
|
require('./styles/main.scss');
|
||||||
|
|
||||||
|
const wheelSpinningSound = new Audio(spinnerMp3);
|
||||||
|
const tadaSound = new Audio(tadaMp3);
|
||||||
|
if (window.localStorage.audioMuteSetting) {
|
||||||
|
wheelSpinningSound.muted = window.localStorage.audioMuteSetting;
|
||||||
|
tadaSound.muted = window.localStorage.audioMuteSetting;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fireworksContainer = document.getElementById('fireworks-container');
|
||||||
|
function fireworksContainerOnClick() {
|
||||||
|
fireworksContainer.style.display = 'none';
|
||||||
|
document.getElementById('chart').click();
|
||||||
|
document.getElementsByClassName('chartholder')[0].dispatchEvent(new Event('click'));
|
||||||
|
}
|
||||||
|
fireworksContainer.onclick = fireworksContainerOnClick;
|
||||||
|
|
||||||
|
const fireworks = new Fireworks(fireworksContainer, {
|
||||||
|
// sound: {
|
||||||
|
// enabled: !wheelSpinningSound.muted,
|
||||||
|
// },
|
||||||
|
});
|
||||||
|
|
||||||
const padding = {
|
const padding = {
|
||||||
top: 20,
|
top: 20,
|
||||||
right: 40,
|
right: 40,
|
||||||
@@ -74,7 +102,7 @@ function makeArrowAndCircle(
|
|||||||
.attr('x', 0)
|
.attr('x', 0)
|
||||||
.attr('y', 0)
|
.attr('y', 0)
|
||||||
.attr('preserveAspectRatio', 'xMaxYMax slice');
|
.attr('preserveAspectRatio', 'xMaxYMax slice');
|
||||||
}
|
|
||||||
container
|
container
|
||||||
.append('circle')
|
.append('circle')
|
||||||
.attr('cx', 0)
|
.attr('cx', 0)
|
||||||
@@ -83,16 +111,14 @@ function makeArrowAndCircle(
|
|||||||
.style('fill', 'white')
|
.style('fill', 'white')
|
||||||
.style('fill', 'url(#image)')
|
.style('fill', 'url(#image)')
|
||||||
.style('cursor', 'pointer');
|
.style('cursor', 'pointer');
|
||||||
if (imageUrlForSpinner.length === 0) {
|
} else {
|
||||||
// spin text
|
|
||||||
container
|
container
|
||||||
.append('text')
|
.append('circle')
|
||||||
.attr('x', 0)
|
.attr('cx', 0)
|
||||||
.attr('y', 10)
|
.attr('cy', 0)
|
||||||
.attr('text-anchor', 'middle')
|
.attr('r', 60)
|
||||||
.text('SPIN')
|
.style('fill', 'white')
|
||||||
.style('font-weight', 'bold')
|
.style('cursor', 'pointer');
|
||||||
.style('font-size', '30px');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,9 +181,16 @@ function drawWheel() {
|
|||||||
// all slices have been seen, all done
|
// all slices have been seen, all done
|
||||||
// console.log(`OldPick: ${oldpick.length}`, `Data length: ${data.length}`);
|
// console.log(`OldPick: ${oldpick.length}`, `Data length: ${data.length}`);
|
||||||
if (oldpick.length === data.length) {
|
if (oldpick.length === data.length) {
|
||||||
|
fireworksContainer.style.display = 'none';
|
||||||
|
fireworks.clear();
|
||||||
stopSpinning();
|
stopSpinning();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
audioControls.stopAudio(tadaSound);
|
||||||
|
audioControls.playAudio(wheelSpinningSound);
|
||||||
|
fireworksContainer.style.display = 'none';
|
||||||
|
fireworks.stop();
|
||||||
const ps = 360 / data.length;
|
const ps = 360 / data.length;
|
||||||
const rng = Math.floor(Math.random() * 1440 + 360);
|
const rng = Math.floor(Math.random() * 1440 + 360);
|
||||||
|
|
||||||
@@ -179,10 +212,21 @@ function drawWheel() {
|
|||||||
.on('end', () => {
|
.on('end', () => {
|
||||||
// mark question as seen
|
// mark question as seen
|
||||||
d3.select(`.slice:nth-child(${picked + 1}) path`).attr('fill', '#111');
|
d3.select(`.slice:nth-child(${picked + 1}) path`).attr('fill', '#111');
|
||||||
|
d3.select(`.slice:nth-child(${picked + 1}) text`).attr('fill', '#ffffff');
|
||||||
// populate question
|
// populate question
|
||||||
d3.select('#question h1').text(data[picked].label.trim());
|
d3.select('#question h1').text(data[picked].label.trim());
|
||||||
oldrotation = rotation;
|
oldrotation = rotation;
|
||||||
|
|
||||||
|
audioControls.stopAudio(wheelSpinningSound);
|
||||||
|
audioControls.playAudio(tadaSound);
|
||||||
|
fireworksContainer.style.display = 'block';
|
||||||
|
const sizes = {
|
||||||
|
width: window.innerWidth,
|
||||||
|
height: window.innerHeight,
|
||||||
|
};
|
||||||
|
fireworks.updateSize(sizes);
|
||||||
|
fireworks.start();
|
||||||
|
|
||||||
/* Get the result value from object "data" */
|
/* Get the result value from object "data" */
|
||||||
// console.log(data[picked].value);
|
// console.log(data[picked].value);
|
||||||
|
|
||||||
@@ -198,6 +242,15 @@ function drawWheel() {
|
|||||||
|
|
||||||
function startOver() {
|
function startOver() {
|
||||||
stopSpinning();
|
stopSpinning();
|
||||||
|
audioControls.stopAudio(wheelSpinningSound);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMute() {
|
||||||
|
audioControls.toggleMute(wheelSpinningSound);
|
||||||
|
audioControls.toggleMute(tadaSound);
|
||||||
|
this.textContent = wheelSpinningSound.muted ? 'Unmute' : 'Mute';
|
||||||
|
window.localStorage.audioMuteSetting = wheelSpinningSound.muted;
|
||||||
|
// TODO - toggle muting the fireworks from here
|
||||||
}
|
}
|
||||||
|
|
||||||
function startSpinning() {
|
function startSpinning() {
|
||||||
@@ -229,7 +282,14 @@ function startSpinning() {
|
|||||||
startOverElement.setAttribute('role', 'button');
|
startOverElement.setAttribute('role', 'button');
|
||||||
startOverElement.onclick = startOver;
|
startOverElement.onclick = startOver;
|
||||||
startOverElement.textContent = 'Start over';
|
startOverElement.textContent = 'Start over';
|
||||||
|
const muteElement = document.createElement('button');
|
||||||
|
muteElement.setAttribute('id', 'mute');
|
||||||
|
muteElement.setAttribute('class', 'button button-black');
|
||||||
|
muteElement.setAttribute('role', 'button');
|
||||||
|
muteElement.onclick = toggleMute;
|
||||||
|
muteElement.textContent = wheelSpinningSound.muted ? 'Unmute' : 'Mute';
|
||||||
chartElement.appendChild(startOverElement);
|
chartElement.appendChild(startOverElement);
|
||||||
|
chartElement.appendChild(muteElement);
|
||||||
document.getElementById('spinner-container').appendChild(chartElement);
|
document.getElementById('spinner-container').appendChild(chartElement);
|
||||||
const questionElement = document.createElement('div');
|
const questionElement = document.createElement('div');
|
||||||
questionElement.setAttribute('id', 'question');
|
questionElement.setAttribute('id', 'question');
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ import { registerRoute, NavigationRoute, Route } from 'workbox-routing';
|
|||||||
// eslint-disable-next-line no-underscore-dangle, no-restricted-globals
|
// eslint-disable-next-line no-underscore-dangle, no-restricted-globals
|
||||||
precacheAndRoute(self.__WB_MANIFEST);
|
precacheAndRoute(self.__WB_MANIFEST);
|
||||||
|
|
||||||
// Enable navigation preload - this should reduce navigation latency
|
|
||||||
navigationPreload.enable();
|
|
||||||
|
|
||||||
const navigationRoute = new NavigationRoute(new NetworkFirst({
|
const navigationRoute = new NavigationRoute(new NetworkFirst({
|
||||||
cacheName: 'navigations',
|
cacheName: 'navigations',
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -91,6 +91,12 @@ body {
|
|||||||
left: auto;
|
left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#mute {
|
||||||
|
position: absolute;
|
||||||
|
top: 140px;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
#spinner-container {
|
#spinner-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -176,6 +182,15 @@ text{
|
|||||||
margin-bottom: 50px;
|
margin-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#fireworks-container {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
#image{
|
#image{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -40,7 +40,13 @@
|
|||||||
|
|
||||||
<div id="input-container">
|
<div id="input-container">
|
||||||
<textarea id="input-lines" class="input-items" rows="15" cols="60" name="text"
|
<textarea id="input-lines" class="input-items" rows="15" cols="60" name="text"
|
||||||
placeholder="Enter names to be shuffled, one per line. Leave this area empty in order to use a default set of generated names."></textarea>
|
placeholder="Enter names to be shuffled, one per line. Leave this area empty in order to use a default set of generated names.
|
||||||
|
|
||||||
|
Click or tap on the wheel to spin it.
|
||||||
|
|
||||||
|
You can also customise the centre of the spinner with an image. Just put ?imgUrl= at the end of the web address and the URL of the image you want to use.
|
||||||
|
|
||||||
|
For example, https://wheel.jcreek.co.uk/?imgUrl=https://www.mammal.org.uk/wp-content/uploads/2021/09/red-fox-300x300.jpg"></textarea>
|
||||||
<button id="startSpinning" class="input-items button button-green" role="button">Start spinning</button>
|
<button id="startSpinning" class="input-items button button-green" role="button">Start spinning</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -50,5 +56,7 @@
|
|||||||
<span> | </span>
|
<span> | </span>
|
||||||
<span class="footer-items"><a href="/privacy-policy.html">Privacy Policy</a></span>
|
<span class="footer-items"><a href="/privacy-policy.html">Privacy Policy</a></span>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<div id="fireworks-container"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user