Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@code-dot-org/dance-party

Package Overview
Dependencies
Maintainers
8
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@code-dot-org/dance-party - npm Package Compare versions

Comparing version 0.0.27 to 0.0.28

assets/create_sprite_sheets.sh

18

package.json
{
"name": "@code-dot-org/dance-party",
"version": "0.0.27",
"version": "0.0.28",
"description": "",

@@ -9,7 +9,7 @@ "main": "dist/main.js",

"dev": "webpack-dev-server --mode development",
"codecov": "mkdir coverage && nyc report --reporter=text-lcov > ./coverage/unit.lcov && codecov",
"codecov": "mkdir -p coverage && nyc report --reporter=text-lcov > ./coverage/unit.lcov && codecov",
"lint": "eslint --ext .js src test",
"test": "npm run lint && nyc tape ./test/**/*.js",
"test": "npm run lint && nyc npm run test:unit && npm run test:integration",
"test:unit": "tape ./test/unit/*.js",
"test:integration": "tape ./test/integration/*.js",
"test:integration": "karma start",
"preversion": "npm run test",

@@ -26,3 +26,3 @@ "version": "npm run build",

"devDependencies": {
"@code-dot-org/p5.play": "1.3.5-cdo",
"@code-dot-org/p5.play": "1.3.8-cdo",
"babel-core": "^6.26.3",

@@ -36,3 +36,11 @@ "babel-loader": "^7.1.4",

"eslint": "^2.8.0",
"istanbul-instrumenter-loader": "^3.0.1",
"jsdom": "^12.2.0",
"karma": "^2.0.5",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-tap": "^4.1.4",
"karma-tap-pretty-reporter": "^4.1.0",
"karma-webpack": "4.0.0-rc.2",
"nyc": "^13.1.0",

@@ -39,0 +47,0 @@ "raw-loader": "^0.5.1",

@@ -24,3 +24,10 @@ module.exports = {

{name: "XHighKick", mirror: false, shortBurst: true},
{name: "XBend", mirror: false, shortBurst: true},
{name: "XFever", mirror: false, shortBurst: true},
{name: "XHop", mirror: false, shortBurst: true},
{name: "XKnee", mirror: false, shortBurst: true},
{name: "XKneel", mirror: false, shortBurst: true},
{name: "XOle", mirror: false, shortBurst: true},
{name: "XSlide", mirror: false, shortBurst: true},
],
};

@@ -18,5 +18,24 @@ /* eslint-disable */

ThisOrThat: 10,
Thriller: 11
Thriller: 11,
XArmsSide: 12,
XArmsUp: 13,
XJump: 14,
XClapSide: 15,
XHeadHips: 16,
XHighKick: 17,
XBend: 18,
XFever: 19,
XHop: 20,
XKnee: 21,
XKneel: 22,
XOle: 23,
XSlide: 24,
};
var QueueType = {
every: 'every',
after: 'after',
other: 'other'
};
// Event handlers, loops, and callbacks.

@@ -34,2 +53,5 @@ var inputEvents = [];

/**
* @returns {Object} An object with two arrays, each of which is a list of numbers
*/
function getCueList() {

@@ -61,21 +83,53 @@ var timestamps = [];

/**
* @param {Object} events - An object where each key is an event type. Each value
* is another object, where the keys represent the param of the event to be run
*/
function runUserEvents(events) {
var currentEvents = {};
// We have three separate event queues.
// First we run every N seconds/measures events
// Then we run after N seconds/measures events
// Finally we run all other events
var queues = {};
Object.keys(QueueType).forEach(function(key) {
queues[key] = [];
});
// Iterate through all of the inputEvents we've cached in the interpreter, looking
// to see if they meet the criteria of the passed in events object. If they do,
// we add them to the appropriate event queue
for (var i = 0; i < inputEvents.length; i++) {
var eventType = inputEvents[i].type;
var event = inputEvents[i].event;
var param = inputEvents[i].param;
var priority = inputEvents[i].priority;
var queueType = inputEvents[i].queueType;
if (events[eventType] && events[eventType][param]) {
//If there are multiple cues of the same type, only run the event with the highest priority
if (!currentEvents[eventType] || currentEvents[eventType].priority < priority) {
currentEvents[eventType] = {event: event, priority: priority};
if (!queues[queueType]) {
throw new Error('Unknown queueType: ', queueType);
}
queues[queueType].push({
priority: inputEvents[i].priority,
func: inputEvents[i].func
});
}
}
for (var input in currentEvents){
if(currentEvents.hasOwnProperty(input)){
currentEvents[input].event();
}
function prioritySort(a, b) {
// TODO: If compareFunction(a, b) returns 0, leave a and b unchanged with respect
// to each other, but sorted with respect to all different elements. Note: the
// ECMAscript standard does not guarantee this behaviour, and thus not all
// browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
// ^ Matters to us, because we initially seed items according to block position
// and we want to maintain that ordering in our sort when priorities are equal
// There are ways we could ensure that
return a.priority - b.priority;
}
function executeFuncs(item) {
item.func();
}
queues[QueueType.every].sort(prioritySort).forEach(executeFuncs);
queues[QueueType.after].sort(prioritySort).forEach(executeFuncs);
queues[QueueType.other].forEach(executeFuncs);
}

@@ -99,19 +153,36 @@

function whenKey(key, event) {
/**
* @param {string} key - Many options, including up, down, left, right, a-z, 0-9
* @param {function} func - Code to run when event fires
*/
function whenKey(key, func) {
inputEvents.push({
type: 'this.p5_.keyWentDown',
event: event,
param: key
func: func,
param: key,
queueType: QueueType.other,
});
}
function whenPeak(range, event) {
/**
* @param {string} range - Should be "bass", "mid", or "treble"
* @param {function} func - Code to run when event fires
*/
function whenPeak(range, func) {
inputEvents.push({
type: 'Dance.fft.isPeak',
event: event,
param: range
func: func,
param: range,
queueType: QueueType.other,
});
}
function atTimestamp(timestamp, unit, event) {
/**
* @param {number} timestamp
* @param {string} unit - Should be "measures" or "seconds"
* @param {function} func - Code to run when event fires
*/
function atTimestamp(timestamp, unit, func) {
// Despite the functions name, if we call atTimestamp(4, "measures", foo), we
// actually want to fire on the 5th measure (i.e after 4 measures have completed)
if (unit === "measures") {

@@ -121,13 +192,18 @@ timestamp += 1;

// Increment priority by 1 to account for 'atTimestamp' events having a higher priority
// than everySecond events when they have share a timestamp parameter
inputEvents.push({
type: 'cue-' + unit,
event: event,
func: func,
param: timestamp,
priority: timestamp + 1
queueType: QueueType.after,
// actual priority value is inconsequential here
priority: 0,
});
}
function everySeconds(n, unit, event) {
/**
* @param {number} n
* @param {string} unit - Should be "measures" or "seconds"
* @param {function} func - Code to run when event fires
*/
function everySeconds(n, unit, func) {
// Measures start counting at 1, whereas seconds start counting at 0.

@@ -145,29 +221,43 @@ // e.g. "every 4 measures" will generate events at "5, 9, 13" measures.

}
everySecondsRange(n, unit, start, stop, event);
everySecondsRange(n, unit, start, stop, func);
}
function everySecondsRange(n, unit, start, stop, event) {
if (n > 0) {
// Offset by n so that we don't generate an event at the beginning
// of the first period.
var timestamp = start + n;
/**
* @param {number} n
* @param {string} unit - Should be "measures" or "seconds"
* @param {number} start
* @param {number} stop
* @param {function} func - Code to run when event fires
*/
function everySecondsRange(n, unit, start, stop, func) {
if (n <= 0) {
return;
}
while (timestamp < stop) {
inputEvents.push({
type: 'cue-' + unit,
event: event,
param: timestamp,
priority: n
});
timestamp += n;
}
// Offset by n so that we don't generate an event at the beginning
// of the first period.
var timestamp = start + n;
while (timestamp < stop) {
inputEvents.push({
type: 'cue-' + unit,
func: func,
param: timestamp,
queueType: QueueType.every,
priority: n
});
timestamp += n;
}
}
function everyVerseChorus(unit, event) {
/**
* @param {string} unit - Should be "verse" or "chorus"
* @param {function} func - Code to run when event fires
*/
function everyVerseChorus(unit, func) {
inputEvents.push({
type: 'verseChorus',
event: event,
func: func,
param: unit
});
}

@@ -8,2 +8,3 @@ /* eslint-disable no-unused-vars, curly, eqeqeq, babel/semi, semi, no-undef */

const modifySongData = require('./modifySongData');
const ResourceLoader = require('./ResourceLoader');

@@ -26,3 +27,2 @@ function Behavior(func, id, extraArgs) {

const img_base = "https://curriculum.code.org/images/sprites/spritesheet_tp/";
const SIZE = constants.SIZE;

@@ -43,3 +43,2 @@ const FRAMES = constants.FRAMES;

playSound,
moveNames,
recordReplayLog,

@@ -52,2 +51,5 @@ showMeasureLabel = true,

},
// For testing: Can provide a custom resource loader class
// to load fixtures and/or isolate us entirely from network activity
resourceLoader = new ResourceLoader(),
}) {

@@ -58,10 +60,4 @@ this.onHandleEvents = onHandleEvents;

this.i18n = i18n;
this.resourceLoader_ = resourceLoader;
this.currentFrameEvents = {
'this.p5_.keyWentDown': {},
'Dance.fft.isPeak': {},
'cue-seconds': {},
'cue-measures': {},
};
this.world = {

@@ -107,3 +103,3 @@ height: 400,

this.world.SPRITE_NAMES = constants.SPRITE_NAMES;
this.world.MOVE_NAMES = moveNames || constants.MOVE_NAMES;
this.world.MOVE_NAMES = constants.MOVE_NAMES;

@@ -133,2 +129,3 @@ if (spriteConfig) {

this.p5_ = p5Inst;
this.resourceLoader_.initWithP5(p5Inst);
this.sprites_ = p5Inst.createGroup();

@@ -143,2 +140,6 @@ p5Inst.preload = () => this.preload();

teardown() {
this.p5_.remove();
}
onKeyDown(keyCode) {

@@ -177,2 +178,7 @@ this.p5_._onkeydown({ which: keyCode });

/**
* @param {Object} timestamps
* @param {number[]} timestamps.measures
* @param {number[]} timestamps.seconds
*/
addCues(timestamps) {

@@ -193,3 +199,2 @@ // Sort cues

this.p5_.noLoop();
this.currentFrameEvents.any = false;

@@ -201,31 +206,14 @@ this.world.fg_effect = null;

preload() {
// Load spritesheets compressed to various levels of quality with pngquant
// Pass queryparam ?quality=<quality> to try a particular quality level.
// Only those png assets will be downlaoded.
// Available quality levels:
// 50 - 40% smaller
// 25 - 46%
// 10 - 51%
// 5 - 55%
// 1 - 55%
// 0 - 63% smaller
let qualitySuffix = '-q50'; // Default to q50 for now. Set to '' to go back to full-quality.
const qualitySetting = queryParam('quality');
if (qualitySetting) {
qualitySuffix = `-q${qualitySetting}`;
document.title = `q${qualitySetting} - ${document.title}`;
}
// Load spritesheet JSON files
this.world.SPRITE_NAMES.forEach(this_sprite => {
ANIMATIONS[this_sprite] = [];
this.world.MOVE_NAMES.forEach(({ name, mirror }, moveIndex) => {
const baseUrl = `${img_base}${this_sprite}_${name}`;
this.p5_.loadJSON(`${baseUrl}.json`, jsonData => {
// Passing true as the 3rd arg to loadSpriteSheet() indicates that we want
// it to load the image as a Image (instead of a p5.Image), which avoids
// a canvas creation. This makes it possible to run on mobile Safari in
// iOS 12 with canvas memory limits.
this.setAnimationSpriteSheet(this_sprite, moveIndex,
this.p5_.loadSpriteSheet(`${baseUrl}${qualitySuffix}.png`, jsonData.frames, true), mirror)
this.resourceLoader_.getAnimationData(animationData => {
this.world.SPRITE_NAMES.forEach(costume => {
const costumeData = animationData[costume.toLowerCase()];
ANIMATIONS[costume] = [];
this.world.MOVE_NAMES.forEach(({ name: moveName, mirror }, moveIndex) => {
const moveData = costumeData[moveName.toLowerCase()];
this.setAnimationSpriteSheet(
costume,
moveIndex,
this.resourceLoader_.loadSpriteSheet(moveData.spritesheet, moveData.frames),
mirror
);
});

@@ -332,3 +320,3 @@ });

sprite.current_move = 0;
sprite.previous_move = 0;
sprite.previous_move = 0; // I don't think this is used?

@@ -937,10 +925,14 @@ for (var i = 0; i < ANIMATIONS[costume].length; i++) {

/**
* @return {Object} TODO: describe
*/
updateEvents_() {
const events = this.currentFrameEvents;
const { analysis } = this.songMetadata_ || {};
events.any = false;
events['this.p5_.keyWentDown'] = {};
events['Dance.fft.isPeak'] = {};
events['cue-seconds'] = {};
events['cue-measures'] = {};
// Will potentially set the following:
// this.p5_.keyWentDown
// Dance.fft.isPeak
// cue-seconds
// cue-measures
const events = {};
this.peakThisFrame_ = false;

@@ -950,3 +942,3 @@

if (this.p5_.keyWentDown(key)) {
events.any = true;
events['this.p5_.keyWentDown'] = events['this.p5_.keyWentDown'] || {}
events['this.p5_.keyWentDown'][key] = true;

@@ -963,3 +955,3 @@ }

if (beats[range]) {
events.any = true;
events['Dance.fft.isPeak'] = events['Dance.fft.isPeak'] || {}
events['Dance.fft.isPeak'][range] = true;

@@ -973,3 +965,3 @@ this.peakThisFrame_ = true;

while (this.world.cues.seconds.length > 0 && this.world.cues.seconds[0] < this.getCurrentTime()) {
events.any = true;
events['cue-seconds'] = events['cue-seconds'] || {}
events['cue-seconds'][this.world.cues.seconds.splice(0, 1)] = true;

@@ -979,5 +971,7 @@ }

while (this.world.cues.measures.length > 0 && this.world.cues.measures[0] < this.getCurrentMeasure()) {
events.any = true;
events['cue-measures'] = events['cue-measures'] || {};
events['cue-measures'][this.world.cues.measures.splice(0, 1)] = true;
}
return events;
}

@@ -1014,3 +1008,3 @@

draw() {
this.updateEvents_();
const events = this.updateEvents_();
this.sampleFrameRate_();

@@ -1067,4 +1061,4 @@

if (this.currentFrameEvents.any && this.onHandleEvents) {
this.onHandleEvents(this.currentFrameEvents);
if (Object.keys(events).length && this.onHandleEvents) {
this.onHandleEvents(events);
}

@@ -1071,0 +1065,0 @@ }

const DanceParty = require('../../src/p5.dance');
const UnitTestResourceLoader = require('./UnitTestResourceLoader');

@@ -7,9 +8,9 @@ module.exports = {

new DanceParty({
moveNames: [],
playSound: (url, callback) => callback(),
onInit: nativeAPI => resolve(nativeAPI),
resourceLoader: new UnitTestResourceLoader(),
...props
});
});
}
},
};
const {createDanceAPI} = require('./createDanceAPI');
const fs = require('fs');
const path = require('path');
const interpreted = fs.readFileSync(path.join(__dirname, '..', '..', 'src', 'p5.dance.interpreted.js'), 'utf8');
const ResourceLoader = require('../../src/ResourceLoader');
const interpreted = require('raw-loader!../../src/p5.dance.interpreted.js');
const injectInterpreted = require('./injectInterpreted');

@@ -11,5 +9,7 @@

createDanceAPI({
resourceLoader: new ResourceLoader('/base/assets/sprite_sheets/'),
onPuzzleComplete: (result, message) => {
onPuzzleComplete(result, message);
nativeAPI.reset();
nativeAPI.teardown();
},

@@ -28,16 +28,2 @@ onInit: api => {

// Mock 4 cat and moose animation poses.
const moveCount = 10;
for (let i = 0; i < moveCount; i++) {
api.setAnimationSpriteSheet("CAT", i, {}, () => {});
api.setAnimationSpriteSheet("MOOSE", i, {}, () => {});
api.setAnimationSpriteSheet("ROBOT", i, {}, () => {});
api.world.MOVE_NAMES.push({
name: `move${i}`
});
}
api.world.fullLengthMoveCount = moveCount;
api.world.restMoveCount = 1;
api.addCues(getCueList());

@@ -44,0 +30,0 @@ api.onHandleEvents = currentFrameEvents => runUserEvents(currentFrameEvents);

const test = require('tape');
const helpers = require('../helpers/createDanceAPI');
test('getCues sorts measures and seconds cues', async t => {
test('addCues sorts measures and seconds cues', async t => {
const nativeAPI = await helpers.createDanceAPI();

@@ -35,2 +35,1 @@ nativeAPI.play({

});
const test = require('tape');
const helpers = require('../helpers/createDanceAPI');
test('setBackground changes the bgEffect to color_cycle effect', async t => {
test('setBackground clears the bgEffect and sets background_color', async t => {
const nativeAPI = await helpers.createDanceAPI();
nativeAPI.setBackgroundEffect('diamonds');
// Initial Values
t.equal(nativeAPI.world.bg_effect, 'diamonds');
nativeAPI.setBackground('purple');
t.equal(nativeAPI.world.background_color, 'purple');
t.equal(nativeAPI.world.bg_effect, null);
t.end();
nativeAPI.reset();
});
test('setBackgroundEffect changes the bgEffect to color_cycle effect', async t => {
const nativeAPI = await helpers.createDanceAPI();
// Initial Values
t.equal(nativeAPI.world.bg_effect, null);
nativeAPI.setBackgroundEffect('color_cycle');

@@ -11,0 +27,0 @@

const test = require('tape');
const constants = require('../../src/constants');
const helpers = require('../helpers/createDanceAPI');
const UnitTestResourceLoader = require('../helpers/UnitTestResourceLoader');

@@ -180,3 +182,6 @@ test('Sprite dance decrements and loops for prev dance', async t => {

const subTest = async ({ moveCount = 3, testCode }) => {
const nativeAPI = await helpers.createDanceAPI();
// These tests set up their own moves, assuming no initial moves
const nativeAPI = await helpers.createDanceAPI({
spriteConfig: world => world.MOVE_NAMES = []
});
nativeAPI.play({

@@ -256,22 +261,7 @@ bpm: 120,

test('Sprite move sorting works reliably', async t => {
const P5 = require('../../src/loadP5');
P5.prototype.loadJSON = function (_url, callback) {
setTimeout(() => {
this._preloadCount--;
this._runIfPreloadsAreDone();
callback('{"frames":{}}');
}, 0);
};
P5.prototype.loadImageElement = function (_url, callback) {
setTimeout(() => {
this._preloadCount--;
this._runIfPreloadsAreDone();
callback(new Image());
}, 0);
};
const subTest = async ({ moveNames, testCode }) => {
const nativeAPI = await helpers.createDanceAPI({ moveNames, spriteConfig: world => { world.SPRITE_NAMES = ['foo']; } });
const nativeAPI = await helpers.createDanceAPI({
spriteConfig: world => { world.MOVE_NAMES = moveNames; },
resourceLoader: new UnitTestResourceLoader(constants.SPRITE_NAMES, moveNames),
});

@@ -278,0 +268,0 @@ nativeAPI.p5_.noLoop();

@@ -18,4 +18,4 @@ const test = require('tape');

nativeAPI.updateEvents_();
t.deepEqual(nativeAPI.currentFrameEvents['this.p5_.keyWentDown'], {
const events = nativeAPI.updateEvents_();
t.deepEqual(events['this.p5_.keyWentDown'], {
left: true,

@@ -22,0 +22,0 @@ space: true,

module.exports = {
devtool: 'eval-cheap-module-source-map',
entry: {

@@ -3,0 +4,0 @@ main: './src/index.js',

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc