Web Audio Constructors and jQuery - javascript

I'm trying to figure out a way to have cleaner, efficient code for a web audio project i've been working on. the code I have right now is this:
//OSCILLATOR INFO//
// Oscillator Pitch is in Hz.
// Oscillator Detune is in Cents & can be positive or negative values.
// 1 Octave = double/half the note frequency in Hz. (A3 = 220Hz; A4 = 440Hz; A5 = 880Hz)
// 1 Octave = 1200 Cents. 100 Cents per Semitone. (A3 - A4 = 1200 Cents; A4 - A5 = 1200 Cents)
// 12 Semitones per Octave.
// (A-440Hz detuned by 100 cents = A#; detuned by -100 cents = Ab)
//JQUERY SET UP//
//WEB AUDIO SET UP//
//used start web audio
var ctx = new webkitAudioContext();
speakers = ctx.destination;
var osc1 = ctx.createOscillator();
var osc2 = ctx.createOscillator();
var osc3 = ctx.createOscillator();
$(document).ready(function () {
//WAVEFORM OBJECTS - used to set the value of "cur_wave_osc" under Waveform sliders.//
var wF = {
0: "Sine",
1: "Square",
2: "Sawtooth",
3: "Triangle"
};
//PLAY_PAUSE BUTTONS - used to play & pause the oscillators.//
//OSC1 PLAY_PAUSE//
$('#play_pause_osc1').click(function () {
if ($(this).val() == "Play Osc1") {
$(this).val("Pause");
oscillator1Start();
} else {
$(this).val("Play Osc1");
osc1.disconnect();
}
});
//OSC2 PLAY_PAUSE//
$('#play_pause_osc2').click(function () {
if ($(this).val() == "Play Osc2") {
$(this).val("Pause");
oscillator2Start();
} else {
$(this).val("Play Osc2");
osc2.disconnect();
}
});
//OSC3 PLAY_PAUSE//
$('#play_pause_osc3').click(function () {
if ($(this).val() == "Play Osc3") {
$(this).val("Pause");
oscillator3Start();
} else {
$(this).val("Play Osc3");
osc3.disconnect();
}
});
//GAIN SLIDERS - used for controlling osc volume.//
//OSC1_GAIN//
$(function () {
$("#osc1_vol").slider({
min: 0,
max: 1,
value: 0.5,
step: 0.01,
slide: function (event, ui) {
$("#cur_vol_osc1").val(ui.value);
gainNode1.gain.value = $("#cur_vol_osc1").val();
}
});
$("#cur_vol_osc1").val($("#osc1_vol").slider("value"));
});
//OSC2_GAIN//
$(function () {
$("#osc2_vol").slider({
min: 0,
max: 1,
value: 0.5,
step: 0.01,
slide: function (event, ui) {
$("#cur_vol_osc2").val(ui.value);
gainNode2.gain.value = $("#cur_vol_osc2").val();
}
});
$("#cur_vol_osc2").val($("#osc2_vol").slider("value"));
});
//OSC3_GAIN//
$(function () {
$("#osc3_vol").slider({
min: 0,
max: 1,
value: 0.5,
step: 0.01,
slide: function (event, ui) {
$("#cur_vol_osc3").val(ui.value);
gainNode3.gain.value = $("#cur_vol_osc3").val();
}
});
$("#cur_vol_osc3").val($("#osc3_vol").slider("value"));
});
//PITCH SLIDERS - used for controlling osc pitch.//
//OSC1_PITCH//
$(function () {
$("#osc1_pitch").slider({
min: 0,
max: 25000,
value: 440,
step: 1,
slide: function (event, ui) {
$("#cur_pitch_osc1").val(ui.value);
osc1.frequency.value = $("#cur_pitch_osc1").val();
}
});
$("#cur_pitch_osc1").val($("#osc1_pitch").slider("value"));
});
//OSC2_PITCH//
$(function () {
$("#osc2_pitch").slider({
min: 0,
max: 25000,
value: 440,
step: 1,
slide: function (event, ui) {
$("#cur_pitch_osc2").val(ui.value);
osc2.frequency.value = $("#cur_pitch_osc2").val();
}
});
$("#cur_pitch_osc2").val($("#osc2_pitch").slider("value"));
});
//OSC3_PITCH//
$(function () {
$("#osc3_pitch").slider({
min: 0,
max: 25000,
value: 440,
step: 1,
slide: function (event, ui) {
$("#cur_pitch_osc3").val(ui.value);
osc3.frequency.value = $("#cur_pitch_osc3").val();
}
});
$("#cur_pitch_osc3").val($("#osc3_pitch").slider("value"));
});
//DETUNE SLIDER - used for controlling osc detune.//
//OSC1_DETUNE//
$(function () {
$("#osc1_detune").slider({
min: -4800,
max: 4800,
value: 0,
step: 1,
slide: function (event, ui) {
$("#cur_detune_osc1").val(ui.value);
osc1.detune.value = $("#cur_detune_osc1").val();
}
});
$("#cur_detune_osc1").val($("#osc1_detune").slider("value"));
});
//OSC2_DETUNE//
$(function () {
$("#osc2_detune").slider({
min: -4800,
max: 4800,
value: 0,
step: 1,
slide: function (event, ui) {
$("#cur_detune_osc2").val(ui.value);
osc2.detune.value = $("#cur_detune_osc2").val();
}
});
$("#cur_detune_osc2").val($("#osc2_detune").slider("value"));
});
//OSC3_DETUNE//
$(function () {
$("#osc3_detune").slider({
min: -4800,
max: 4800,
value: 0,
step: 1,
slide: function (event, ui) {
$("#cur_detune_osc3").val(ui.value);
osc3.detune.value = $("#cur_detune_osc3").val();
}
});
$("#cur_detune_osc3").val($("#osc3_detune").slider("value"));
});
//WAVEFORM SLIDERS - used for selecting osc waveform.//
//OSC1_WAVEFORM//
$(function () {
$("#osc1_wave").slider({
min: 0,
max: 3,
value: 0,
step: 1,
slide: function (event, ui) {
$("#cur_wave_osc1").val(wF[ui.value]);
}
});
$("#cur_wave_osc1").val("Sine");
osc1.type = $("#osc1_wave").slider("value");
});
//OSC2_WAVEFORM//
$(function () {
$("#osc2_wave").slider({
min: 0,
max: 3,
value: 0,
step: 1,
slide: function (event, ui) {
$("#cur_wave_osc2").val(wF[ui.value]);
}
});
$("#cur_wave_osc2").val("Sine");
osc2.type = $("#osc2_wave").slider("value");
});
//OSC3_WAVEFORM//
$(function () {
$("#osc3_wave").slider({
min: 0,
max: 3,
value: 0,
step: 1,
slide: function (event, ui) {
$("#cur_wave_osc3").val(wF[ui.value]);
}
});
$("#cur_wave_osc3").val("Sine");
osc3.type = $("#osc3_wave").slider("value");
});
});
//CREATE OSCILLATORS//
//OSC1//
function oscillator1Start() {
//creates the osc
osc1 = ctx.createOscillator();
//sets waveform
osc1.type = $("#osc1_wave").slider("value"); //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
//sets frequency
osc1.frequency.value;
//sets detune
osc1.detune.value;
//creates a gain node
gainNode1 = ctx.createGainNode();
//connects osc to gain node
osc1.connect(gainNode1);
//connects gain node to speakers
gainNode1.connect(speakers);
//sets gain value
gainNode1.gain.value;
//plays the osc
osc1.start(0);
}
//OSC2//
function oscillator2Start() {
//creates the osc
osc2 = ctx.createOscillator();
//sets waveform
osc2.type; //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
//sets frequency
osc2.frequency.value;
//sets detune
osc2.detune.value;
//creates a gain node
gainNode2 = ctx.createGainNode();
//connects osc to gain node
osc2.connect(gainNode2);
//connects gain node to speakers
gainNode2.connect(speakers);
//sets gain value
gainNode2.gain.value;
//plays the osc
osc2.start(0);
}
//OSC3//
function oscillator3Start() {
//creates the osc
osc3 = ctx.createOscillator();
//sets waveform
osc3.type; //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
//sets frequency
osc3.frequency.value;
//sets detune
osc3.detune.value;
//creates a gain node
gainNode3 = ctx.createGainNode();
//connects osc to gain node
osc3.connect(gainNode3);
//connects gain node to speakers
gainNode3.connect(speakers);
//sets gain value
gainNode3.gain.value;
//plays the osc
osc3.start(0);
}
it seems like I have a lot of repetitive code so I was considering making some constructors for things like creating a a new osc or play/pause button. The problem I'm running into though, is since my oscillator controls are controlled via jquery how would i still use my jQuery sliders, buttons in the constructors?
This is as far as I've gotten:
var ctx = new webkitAudioContext();
//object constructor
function Osc(type,freq,detune,gain)
{
this.create = new ctx.createOscillator();
this.type = type; //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
this.freq = freq;
this.detune = detune;
this.gain = gain;
this.changeType = changeType;
function changeType(type)
{
this.type = type;
};
this.changeFreq = changeFreq;
function changeFreq(freq)
{
this.freq = freq;
};
}

See if this can help you get started. What I did was simply demonstrate how to append DOM elements that can trigger oscillators from an object created from a constructor. I also only added one oscillator parameter (frequency/pitch) as I figure you could just duplicate the pattern for whatever oscillator params you want (type,filter, etc). One thing about the below code is the internal DOM appending could use an abstraction in and of itself.
So to really do this right you might have to create a group of mini-abstractions that all work together under one constructor. At least that's the way I see it.
EDIT
*I created a version with JQuery UI pitch slider here and edited the code below to include this:*
http://jsfiddle.net/ay4nL/
HTML
<div id="app"> </div>
CSS
.button{
width:100px;
height:100px;
background-color:orange;
}
Javascript
$(function(){
context = new webkitAudioContext();
function Osc(name,buttonName){
/******* Dom Element creation & appending stuff********/
this.buttonName = buttonName;
if(typeof(this.button)==='undefined') {
this.button = document.createElement('div');
};
this.button.className = buttonName;
this.button.id = name +"_" +buttonName;
var app = document.getElementById("app");
$( "#app" ).append(this.button );
if(typeof(this.pitchSlider)==='undefined') {
this.pitchSlider = document.createElement('div');
};
this.pitchSlider.className = "pitchSlider";
this.pitchSlider.id = name +"_" +"pitchSlider";
console.log(this.pitchSlider.id);
var pitchSlider = document.getElementById(this.pitchSlider.id);
$("#"+this.button.id).append(this.pitchSlider);
/**** Oscillator creation and trigger stuff *****/
var freqValueStorage = 100;
this.button.onmousedown = function(){
this.name = context.createOscillator(),
this.name.type = 2;
this.name.frequency.value = freqValueStorage;
this.name.connect(context.destination);
this.name.start(0);
};
this.button.onmouseup = function () {
this.name.stop(0);
};
/**** JQuery UI slider for pitch/frequency ****/
if(typeof(this.sliderParams )==='undefined') {
this.sliderParams = {
'orientation': "vertical",
'range': "min",
'min': .5,
'max': 100,
'animate': true,
'step': 0.01,
'slide': function(event, ui) {
freqValueStorage = ui.value;
},
stop: function( event, ui ) {}
};
$('#'+ this.pitchSlider.id ).slider(this.sliderParams);
};
};
});
osc = new Osc('osc','button');
console.log(osc.button);

Related

How to play an animation as long as an object is colliding with another in Phaser 3?

I'm creating a game with Phaser 3, specifically with the Matter physics engine. I want an animation to play only while an object is colliding with another.
Code for the object (the variable bench is declared before the create() function)
//Place a bench
bench = this.matter.add.sprite(2000, 200, 'sheet', 'bench', {shapes: shapes.bench});
bench.setScale(2, 1);
bench.setPosition(2250 + bench.centerOfMass.x, 200 + bench.centerOfMass.y);
//Needed this again so that bench can detect collisions
bench.isSensor(true);
Current code
//Detect collision when we are on the bench, so we can play the grind animation
this.matter.world.on('collisionstart', function (grindNow, skater, bench) {
grind = true;
});
The problem is, the code above still logs true to the console when the player is colliding with the ground and I only want to detect collisions with the bench object here. I've tried just playing the animation inside the function, which doesn't work either. I've also tried
if (this) {
grind = true;
}
else {
grind = false;
}
and then tried to use that variable to decide when to play the grinding animation, but that didn't help either. Lastly, I've tried playing the animation inside the create function, which would always return undefined even though the animation had been created.
I've tried setting a variable inside that function and only playing
I have found a solution, although I don't know if you want to use it. I found this plugin that makes it easier to manage collisions with Phaser.
Follow these steps:
First, add this line <script src="//cdn.jsdelivr.net/npm/phaser-matter-collision-plugin"></script> in your game_index.html file like so:
<script src="//cdn.jsdelivr.net/npm/phaser-matter-collision-plugin"></script>
<script src= "skateboarding.js" ></script>
<script src = "archery.js"></script>
<script src = "soccer.js"></script>
If you want to install it in a different way, read the full installation guide.
Second, in the config object add this code snippet:
plugins: {
scene: [
{
plugin: PhaserMatterCollisionPlugin, // The plugin class
key: "matterCollision", // Where to store in Scene.Systems, e.g. scene.sys.matterCollision
mapping: "matterCollision" // Where to store in the Scene, e.g. scene.matterCollision
}
]
},
Now, your config object should look like this:
//Game configurations
var config = {
type: Phaser.AUTO,
width: 1500, //<-- this is the width of what we will see at one time
height: gameHeight,
physics: physicsConfig,
plugins: {
scene: [
{
plugin: PhaserMatterCollisionPlugin, // The plugin class
key: "matterCollision", // Where to store in Scene.Systems, e.g. scene.sys.matterCollision
mapping: "matterCollision" // Where to store in the Scene, e.g. scene.matterCollision
}
]
},
scene: {
preload: preload,
create: create,
update: update
}
}
Third, remove these code snippet:
//Detect the player's collision with the ground
this.matter.world.on('collisionstart', function (onGround, skater, ground) {
//If the player is touching the ground, set this value to true
skaterTouchingGround = true;
});
//Detect collision when we are on the bench, so we can play the grind animation
this.matter.world.on('collisionstart', function (grindNow, skater, bench) {
grind = true;
});
Fourth, on the same place where you removed the previous code snippets add these code blocks:
//Detect the player's collision with the ground
this.matterCollision.addOnCollideStart({
objectA: skater,
objectB: ground,
callback: () => skaterTouchingGround = true
});
//Detect collision when we are on the bench, so we can play the grind animation
this.matterCollision.addOnCollideStart({
objectA: skater,
objectB: bench,
callback: () => grind = true
});
Now, you should be able to get the grind's value printed in the console when touching the player touches the bench.
For your reference, here is the entire code:
//Define our start button for out index page
var startButton = document.querySelector("#startSkate").addEventListener("click", () => {
//Delay in ms to remove our button
let removeDelay = 1;
//Call function to start the game
this.startSkateGame();
//Call the setTimeout method and define a function
setTimeout(function () {
//Get elements and remove them to clear the page
document.getElementById('startArch').remove();
document.getElementById('startSkate').remove();
document.getElementById('startSoccer').remove();
document.getElementById('logo').remove();
//Pass the delay
}, removeDelay);
});
//Define the function that we call when our start button is clicked
startSkateGame = () => {
//Configurations for the physics engine
var physicsConfig = {
default: 'matter',
matter : {
gravity: {
x: 0,
y: 2.5, // <--This is the only way I could get the skater to roll up the ramp.s
},
debug: true //CHANGE THIS TO TRUE TO SEE LINES
}
}
//Variables for height and width
var gameHeight = 750;
var gameWidth = 5000;
//Game configurations
var config = {
type: Phaser.AUTO,
width: 1500, //<-- this is the width of what we will see at one time
height: gameHeight,
physics: physicsConfig,
plugins: {
scene: [
{
plugin: PhaserMatterCollisionPlugin, // The plugin class
key: "matterCollision", // Where to store in Scene.Systems, e.g. scene.sys.matterCollision
mapping: "matterCollision" // Where to store in the Scene, e.g. scene.matterCollision
}
]
},
scene: {
preload: preload,
create: create,
update: update
}
}
/* This variable will be used to make sure the skater
cannot ollie while he is already in the air */
var skaterTouchingGround;
var grind;
//Start the game
var game = new Phaser.Game(config);
//Declare variables so we can access them in all functions
var skater;
var ground;
var sky;
var bench;
//Score variables
let score = 0;
let scoreBoard;
function preload() {
//Images
this.load.image('sky', 'archery_assets/images/sky.png');
//Load sprites from TexturePacker
this.load.atlas('sheet', 'skate_assets/sprites.png', 'skate_assets/sprites.json');
//Load body shapes from PhysicsEditor
this.load.json('shapes', 'skate_assets/spritesPE.json');
}
function create() {
//Background
sky = this.add.image(2500, 325,'sky')
//Scale the image
sky.setDisplaySize(gameWidth, gameHeight);
//Get the hitboxes
var shapes = this.cache.json.get('shapes');
//Set world bounds
this.matter.world.setBounds(0, 0, gameWidth, gameHeight);
//Place ground object
ground = this.matter.add.sprite(0, 0, 'sheet', 'ground', {shape: shapes.ground});
//Ground is 600x600, so double the x pixels and we get screen width
ground.setScale(8.5, 1);
ground.setPosition(2500, 650);
//Let the ground detect collisions
ground.isSensor(true);
//Place the ramp
var ramp = this.matter.add.sprite(0, 0, 'sheet', 'ramp', {shape: shapes.ramp});
ramp.setPosition(550 + ramp.centerOfMass.x, 250 + ramp.centerOfMass.y);
//Place a bench
bench = this.matter.add.sprite(2000, 200, 'sheet', 'bench', {shapes: shapes.bench});
bench.setScale(2, 1);
bench.setPosition(2250 + bench.centerOfMass.x, 200 + bench.centerOfMass.y);
//Needed this again so that bench can detect collisions
bench.isSensor(true);
//Create the skater
skater = this.matter.add.sprite(0, 0, 'sheet', 'roll/0001', {shape: shapes.s0001});
skater.setPosition(100 + skater.centerOfMass.x, 200 + skater.centerOfMass.y);
//Collision filtering
var staticCategory = this.matter.world.nextCategory();
ramp.setCollisionCategory(staticCategory);
ground.setCollisionCategory(staticCategory);
bench.setCollisionCategory(staticCategory);
//Skater needs to be in a different category
var skaterCategory = this.matter.world.nextCategory();
skater.setCollisionCategory(skaterCategory);
//Roll animation
//Generate the frame names
var rollFrameNames = this.anims.generateFrameNames(
'sheet', {start: 1, end: 4, zeroPad: 4,
prefix: 'roll/'}
);
//Create the animation
this.anims.create({
key: 'roll', frames: rollFrameNames, frameRate: 16, repeat: -1
});
//Push animation
var pushFrameNames = this.anims.generateFrameNames(
'sheet', {start: 5, end: 8, zeroPad: 4,
prefix: 'push/'}
);
this.anims.create({
key: 'push', frames: pushFrameNames, frameRate: 16, repeat: 0
});
//Shuvit animation
var shuvFrameNames = this.anims.generateFrameNames(
'sheet', {start: 9, end: 12, zeroPad: 4,
prefix: 'shuv/'}
);
this.anims.create({
key: 'shuv', frames: shuvFrameNames, frameRate: 32, repeat: 0
});
//Ollie animation
var ollieFrameNames = this.anims.generateFrameNames(
'sheet', {start: 13, end: 20, zeroPad: 4,
prefix: 'ollie/'}
);
this.anims.create({
key: 'ollie', frames: ollieFrameNames, frameRate: 24, repeat: 0
});
//Kickflip animation
var kfFrameNames = this.anims.generateFrameNames(
'sheet', {start: 21, end: 33, zeroPad: 4,
prefix: 'kickflip/'}
);
this.anims.create({
key: 'kickflip', frames: kfFrameNames, frameRate: 24, repeat: 0
});
//Nosegrind animation
var ngFrameNames = this.anims.generateFrameNames(
'sheet', {start: 34, end: 37, zeroPad: 4,
prefix: 'nosegrind/'}
);
this.anims.create({
key: 'nosegrind', frames: ngFrameNames, frameRate: 24, repeat: 0
});
//This keeps the rolling animation going once the push animation is done
skater.on('animationcomplete', () => {
skater.anims.play('roll');
});
//Input for arrowkeys
this.arrowKeys = this.input.keyboard.addKeys({
up: 'up',
down: 'down',
left: 'left',
right: 'right'
});
//Input for WASD keys
this.WASDkeys = this.input.keyboard.addKeys({
W: 'W',
A: 'A',
S: 'S',
D: 'D'
});
//Spacebar
this.spacebar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
//Camera to follow the skater
this.cameras.main.setBounds(0, 0, gameWidth, gameHeight);
this.cameras.main.startFollow(skater);
//Detect the player's collision with the ground
this.matterCollision.addOnCollideStart({
objectA: skater,
objectB: ground,
callback: () => skaterTouchingGround = true
});
//Detect collision when we are on the bench, so we can play the grind animation
this.matterCollision.addOnCollideStart({
objectA: skater,
objectB: bench,
callback: () => grind = true
});
//Create the scoreboard as a container
scoreBoard = this.add.container(10, 50);
//Add text to this container, displaying our score
scoreText = this.add.text(10, 50, "SCORE: 0", {fontSize: '56px', color: '#fff'});
//Add the text to the container which will be our scoreboard
scoreBoard.add(scoreText);
//Make the scoreboard follow the player
this.tweens.add({
targets: scoreBoard,
ease: 'Linear',
duration: 1,
delay: 1,
yoyo: false,
repeat: -1
});
}
function update() {
console.log(skaterTouchingGround);
//Set variable for player movement
var pushSpeed = 0;
var ollie = 0;
//Make sure the player isn't doing anything if he's upside down, or crashed
let skaterCrashed;
//Variable to check the angle of the skater
let angleOkay = skater.angle > -89 && skater.angle < 89;
//Determine if the player is crashed or not
if (angleOkay) {
skaterCrashed = false;
}
else {
skaterCrashed = true;
window.alert("You crashed!");
}
//Starting parameter, as we don't want to do anything if we are crashed
if (!skaterCrashed) {
//Pushing
if (Phaser.Input.Keyboard.JustDown(this.spacebar) && skaterTouchingGround) {
//Increase speed
pushSpeed = 15;
//Move player
skater.setVelocityX(pushSpeed);
//Play push animation
skater.anims.play('push');
}
//Ollie
if (Phaser.Input.Keyboard.JustDown(this.arrowKeys.up) && skaterTouchingGround) {
//Set this to false, because we are about to jump
skaterTouchingGround = false;
//Set ollie power
ollie = -15;
//Set skate velocity
skater.setVelocityY(ollie);
//Play the ollie animation
skater.anims.play('ollie');
//Scoring for ollie
score += 1;
}
//Shuvit
if (Phaser.Input.Keyboard.JustDown(this.arrowKeys.down)) {
//Play the shuvit animation
skater.anims.play('shuv');
//Scoring for shuv
score += 3;
}
//Kickflip
if (Phaser.Input.Keyboard.JustDown(this.WASDkeys.W) && skaterTouchingGround) {
//Reset variable since we are jumping
skaterTouchingGround = false
//Set jump height
ollie = -14
//Move the player
skater.setVelocityY(ollie);
//Play animation
skater.anims.play('kickflip');
//Scoring for kickflip
score += 10;
}
//Tilting backwards in the air
if (this.arrowKeys.left.isDown && !skaterTouchingGround) {
//Be able to turn backwards so you don't flip
skater.angle -= 3 ;
}
//Tilting forwards in the air
if (this.arrowKeys.right.isDown && !skaterTouchingGround) {
//Be able to turn forwards so you don't flip
skater.angle += 3 ;
}
}
//Move the scoreboard
scoreText.x = skater.body.position.x - 200;
scoreText.setText("SCORE : " + score);
}
}

jquery multiple slider insert values into textbox

I have multiple sliders that share a common maximum number, I am trying to capture those numbers now into text inputs, but I don't know what I am doing. The JavaScript will print
the numbers into a span no issue as long as the class is "spent". But doesn't work when I've tried it with a text input. I've also made a jsfiddle for this
http://jsfiddle.net/zkyks/
What would the proper way be to bind these values to inputs? I have done this individually by calling the id but I don't know how to to implement that here.
Thanks in advance.
JS
$(
function () {
var
maxValueSlider = 100,
maxValueTotal = 100,
$sliders = $("#eq .work_slider"),
valueSliders = [],
$displaySpentTotal = $('#spent');
$displaySpendable = $('#spendable');
function arraySum(arr) {
var sum = 0,
i;
for (i in arr) sum += arr[i];
return sum;
}
$sliders.each(
function (i, slider) {
var
$slider = $(slider),
$spent = $slider.next('.spent');
valueSliders[i] = 0;
$slider.slider({
range: 'min',
value: 0,
min: 0,
max: maxValueSlider,
step: 5,
animate: true,
orientation: "horizontal",
slide: function (event, ui) {
var
sumRemainder = arraySum(valueSliders) - valueSliders[i],
adjustedValue = Math.min(maxValueTotal - sumRemainder, ui.value);
valueSliders[i] = adjustedValue;
// display the current total
$displaySpentTotal.text(sumRemainder + adjustedValue);
$displaySpendable.text(maxValueTotal - sumRemainder - adjustedValue);
// display the current value
$spent.text(adjustedValue);
// set slider to adjusted value
$slider.slider('value', adjustedValue);
// stop sliding (return false) if value actually required adjustment
return adjustedValue == ui.value;
}
});
});
});
HTML
<div class="panel">
<label class="panel_label">Sliders %:</label>
<div id="eq">
1:<div id="work_slider1" name="work_slider1" class="work_slider"></div>
<input type="text" name="work_spent1" id="work_spent1" />
2:<div id="work_slider2" name="work_slider2" class="work_slider"></div>
<input type="text" name="work_spent2" id="work_spent2" />
3:<div id="work_slider3" name="work_slider3" class="work_slider"></div>
<input type="text" name="work_spent3" id="work_spent3" />
4:<div id="work_slider4" name="work_slider4" class="work_slider"></div>
<input type="text" name="work_spent4" id="work_spent4" />
</div>
<div id="spendable">100</div>
</div>
To make minimal changes in your code, you just need to add one line just before return statement in your slide: function (event, ui) {...}:
$(this).next().val(adjustedValue); //set the value of input next to slider
And remove the <br/> between <div> and <input>.
Or keep one <br/> and use:
$(this).next().next().val(adjustedValue);
Working example: http://jsfiddle.net/k8UkE/
Did some code edititing for the first slider. See if it helps
Replaced following // $displaySpendable = $('#work_spent1')
//$displaySpentTotal.val(sumRemainder + adjustedValue);
$displaySpendable.val(maxValueTotal - sumRemainder - adjustedValue);
$(function () {
var
maxValueSlider = 100,
maxValueTotal = 100,
$sliders = $("#eq .work_slider"),
valueSliders = [],
$displaySpentTotal = $('#spent');
$displaySpendable = $('#work_spent1');
function arraySum(arr) {
var sum = 0,
i;
for (i in arr) sum += arr[i];
return sum;
}
$sliders.each(
function (i, slider) {
var
$slider = $(slider),
$spent = $slider.next('.spent');
valueSliders[i] = 0;
$slider.slider({
range: 'min',
value: 0,
min: 0,
max: maxValueSlider,
step: 5,
animate: true,
orientation: "horizontal",
slide: function (event, ui) {
var
sumRemainder = arraySum(valueSliders) - valueSliders[i],
adjustedValue = Math.min(maxValueTotal - sumRemainder, ui.value);
valueSliders[i] = adjustedValue;
// display the current total
**$displaySpentTotal.val(sumRemainder + adjustedValue);
$displaySpendable.val(maxValueTotal - sumRemainder - adjustedValue);**
// display the current value
$spent.text(adjustedValue);
// set slider to adjusted value
$slider.slider('value', adjustedValue);
// stop sliding (return false) if value actually required adjustment
return adjustedValue == ui.value;
}
});
});
});

Multiple Jquery UI Slider non linear value

I have been searching and trying to find a solution for this but unfortunately can't get my way round it. I have multiple jQuery UI sliders which all have their values on sliding from an array. At the end I am trying to get the value of the slider and add it up with the other sliders. Here is the code for only two sliders:
$(function () {
var labelArr = new Array(0, 200, 400, 600);
$("#slider").slider({
values: 0,
min: 0,
max: labelArr.length - 1,
slide: function (event, ui) {
mbdata = labelArr[ui.value] + $("#slider_2").slider("value") + $("#slider_3").slider("value") + $("#slider_4").slider("value") + $("#slider_5").slider("value") + $("#slider_6").slider("value");
g1.refresh(mbdata);
}
});
});
$(function () {
var labelArr = new Array(0, 300, 900, 1200);
$("#slider_2").slider({
value: 0,
min: 0,
max: labelArr.length - 1,
slide: function (event, ui) {
mbdata = labelArr[ui.value] + $("#slider_3").slider("value") + $("#slider").slider("value") + $("#slider_4").slider("value") + $("#slider_5").slider("value") + $("#slider_6").slider("value");
g1.refresh(mbdata);
}
});
});
The first slider works good, but unfortunately when I slide the second one the values are not showing the array ones but simply 1 , 2 , 3
Can someone please try giving me some help
Many thanks
I changed the whole script, but hopefully its doing now what you want it to do - just extend the sliderRangesValues Array (and add a new div with the right ID) to add more slider and values. Its now a much more flexible script:
http://jsfiddle.net/fKUAe/1/
Dummy HTML:
<div id="slider0" class="slider"></div>
<div id="slider1" class="slider"></div>
<div id="slider2" class="slider"></div>
<input type="text" id="slidervalues" value="0" />
jQuery:
var sliderRangeValues = [
[0, 100, 200, 300],
[0, 300, 600, 900],
[0, 1, 2, 3, 4, 5]
];
function getAllSliderValues(sliderCount) {
var sliderValues = 0;
for (var i = 0; i < sliderCount; i++) {
var uiValue = $('#slider' + i).slider('value');
sliderValues += sliderRangeValues[i][uiValue];
}
$('#slidervalues').val(sliderValues);
}
function initSlider(i, sliderCount) {
$('#slider' + i).slider({
values: 0,
min: 0,
max: sliderRangeValues[i].length - 1,
slide: function (event, ui) {
$('#slider' + i).slider('value', ui.value);
getAllSliderValues(sliderCount);
}
});
}
$(function () {
var sliderCount = $('.slider').length;
for (var i = 0; i < sliderCount; i++) {
initSlider(i, sliderCount);
}
});

Two jquery slide ranger

First question from me! I have search for possible ways to do this function that i want but could not find anything that helped me out..
I´m new at javascript and working with this as base:
http://jsfiddle.net/danieltulp/gz5gN/42/
When i adjust the Price-slider, i want to se what price in numbers that i´m searching for.
ex. search from 123$ - 900$
And the same with quality.
I´m also trying to make each slider have different min-max and values, is that possible?
$(function() {
var options = {
range: true,
min: 0,
max: 250,
step: 1,
values: [0, 250],
change: function(event, ui) {
var minP = $("#price").slider("values", 0);
var maxP = $("#price").slider("values", 1);
var minQ = $("#quality").slider("values", 0);
var maxQ = $("#quality").slider("values", 1);
showProducts(minP, maxP, minQ, maxQ);
}
};
2 functions are needed. One for each slider's onChange event. After each onChange function execution min and max values for each slider should be updated based on the calculation results. showProducts() will work in its current form.
This UX feels too complicated. Have you considered representing your data filtering somehow else?
This is how i solved it!
fiddle found here: http://jsfiddle.net/5PAa7/28/
i put it in to two variables instead of two functions.
function showProductsP(minP, maxP) {
$(".product-box").filter(function() {
var price = parseInt($(this).data("price"), 10);
if(price >= minP && price <= maxP){
$(this).show();
} else {
$(this).hide();
}
});
$(function() {
var options = {
range: true,
min: 0,
max: 900,
step: 5,
values: [0, 900],
slide: function(event, ui) {
var minP = $("#slider-price").slider("values", 0);
var maxP = $("#slider-price").slider("values", 1);
var minL = $("#slider-length").slider("values", 0);
var maxL = $("#slider-length").slider("values", 1);
$(this).parent().find(".amount").html(ui.values[ 0 ] + " - " + ui.values[ 1 ]);
showProducts(minP, maxP, minL, maxL);
}
};
var options_length = {
range: true,
min: 0,
max: 60,
step: 1,
values: [0, 60],
slide: function(event, ui) {
var minP = $("#slider-price").slider("values", 0);
var maxP = $("#slider-price").slider("values", 1);
var minL = $("#slider-length").slider("values", 0);
var maxL = $("#slider-length").slider("values", 1);
$(this).parent().find(".amount").html(ui.values[ 0 ] + " - " + ui.values[ 1 ]);
showProducts(minP, maxP, minL, maxL);
}
};

Jquery UI Slider with Web Audio Nodes

I'm having a bit of an issue here. What I'm trying to have is a jQuery slider that displays its value and sets that value to the frequency and detune of my Oscillator. The problem is, I have the sliders working great, but as soon as I uncomment the Web Audio stuff or add the change: event to my sliders, they disappear.
Here's the working code:
$(document).ready(function(){
$(function() {
$("#osc1_pitch").slider({
min: 0,
max: 25000,
value: 440,
step: 2,
slide: function(event, ui) {
$("#cur_pitch").val(ui.value);
}
});
$("#cur_pitch").val($("#osc1_pitch").slider("value"));
});
$(function() {
$("#osc1_detune").slider({
min: -4800,
max: 4800,
value: 0,
step: 2,
slide: function(event, ui) {
$("#cur_detune").val(ui.value);
}
});
$("#cur_detune").val($("#osc1_detune").slider("value"));
});
});
But when I add this underneath the slide: event, they disappear
change: function(event, ui){
osc.frequency.value = $("#cur_pitch").val();
}
Same thing when I uncomment my Web Audio code:
var pitch = document.getElementById('cur_pitch').value;
var detune = document.getElementById('cur_detune').value;
var ctx = new webkitAudioContext();
function osc1(){
osc = ctx.createOscillator(),
osc.type = 0; //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
osc.frequency.value = pitch;
osc.detune.value = detune;
gainNode = ctx.createGainNode();
osc.connect(gainNode);
gainNode.connect(ctx.destination);
gainNode.gain.value = 1;
osc.noteOn(0);
};
Here's the working code in a fiddle with the problem code commented out: http://jsfiddle.net/ryanhagz/ruXd7/1/
I've looked everywhere for a proper answer and there's a bunch of ways I've seen to connect UI elements with Web Audio, but everything I've seen doesn't seem to work for me. I have a feeling it's something really simple too. As always, any help's appreciated!
EDIT: I've added the slidechange: event and set the initial value of the pitch and frequency to the value of the slider and it seems to work better, but the sliders still aren't effecting the pitch or detune.
new code:
var ctx = new webkitAudioContext();
function osc1(){
osc = ctx.createOscillator(),
osc.type = 0; //0 = sine, 1 = square, 2 = saw, 3 = triangle, 4 = custom
osc.frequency.value;
osc.detune.value;
gainNode = ctx.createGainNode();
osc.connect(gainNode);
gainNode.connect(ctx.destination);
gainNode.gain.value = 1;
osc.noteOn(0);
};
$(document).ready(function(){
$(function() {
$("#osc1_pitch").slider({
min: 0,
max: 25000,
value: 440,
step: 1,
slide: function(event, ui) {
$("#cur_pitch").val(ui.value);
}
});
$("#cur_pitch").val($("#osc1_pitch").slider("value"));
$("#cur_pitch").on("slidechange", function(event, ui) {
osc.detune.value = $("#cur_pitch").val();
});
});
$(function() {
$("#osc1_detune").slider({
min: -4800,
max: 4800,
value: 0,
step: 1,
slide: function(event, ui) {
$("#cur_detune").val(ui.value);
}
});
$("#cur_detune").val($("#osc1_detune").slider("value"));
$("#cur_detune").on("slidechange", function(event, ui) {
osc.detune.value = $("#cur_detune").val();
});
});
});
When you are including your problem code you need to add a , after your slide events.
slide: function(event, ui) {
$("#cur_pitch").val(ui.value);
},
And
slide: function(event, ui) {
$("#cur_detune").val(ui.value);
},
http://jsfiddle.net/ruXd7/3/

Categories

Resources