Skip to content
This repository has been archived by the owner on Jun 19, 2018. It is now read-only.

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
Amos Blanton committed Oct 28, 2013
1 parent dd7f6e2 commit 6360de0
Show file tree
Hide file tree
Showing 103 changed files with 4,819 additions and 339 deletions.
677 changes: 677 additions & 0 deletions COPYING

Large diffs are not rendered by default.

339 changes: 0 additions & 339 deletions LICENSE

This file was deleted.

7 changes: 7 additions & 0 deletions README
@@ -0,0 +1,7 @@
Scratch HTML5 Player

This project aims to create a Scratch Player in HTML5. Scratch is currently implemented with Actionscript 3 and requires the Flash Player version 10.2. Since Flash does not run on iOS (iPads, iPods, etc) and newer Android devices, we would like to have an HTML5 version to display (but not edit) projects on mobile devices. Scratch projects played in the HTML5 player should look and behave as closely as possible to the way they look and behave when played by the Flash player. We will not be accepting pull requests for new features that don't already exist in the Flash based Scratch project player.

There are a few github issues created that represent some of the missing features. At this point, the HTML5 player is about 40% complete and can run some simple projects. Running the HTML5 player on your own website, or locally, you will need to have PHP so that the proxy.php file can be used to load assets from the same domain. This is done to be compatible with Javascript security models in today's browsers. To test the HTML5 player against the Flash player you can use the compare.html web page.

More documentation will be added as time permits. Thanks for contributing, and Scratch On!
22 changes: 22 additions & 0 deletions TRADEMARK_POLICY
@@ -0,0 +1,22 @@
The Scratch trademarks, including the Scratch name, logo, the Scratch
Cat and Gobo graphics (the "Marks"), are property of MIT, and the
use of the Marks is governed by this policy.

# Use

You may use the Marks to refer to Scratch in Substantially Unmodified
form.

"Substantially Unmodified" means the source code provided by MIT,
possibly with minor modifications including but not limited to: bug
fixes (including security), changing the locations of files for better
integration with the host operating system, adding documentation, and
changes to the dynamic linking of libraries.

A version is not "Substantially Unmodified" if it incorporates
features not present in a release of Scratch by MIT. If you do make a
substantial modification, to avoid confusion with versions of Scratch
produced by MIT you must remove all Marks from your version of the
software and refrain from using any of the Marks to refer to your
version.

115 changes: 115 additions & 0 deletions compare.html
@@ -0,0 +1,115 @@
<?
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>
<!DOCTYPE html>
<html>
<head>
<title>Scratch HTML5 vs. Flash</title>
<meta charset="utf-8">
<style type="text/css">
body {
background: #222;
color: #fff;
margin: 0;
}
</style>
<link href="player.css" type="text/css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script src="js/util/Timer.js"></script>
<script src="js/util/OffsetBuffer.js"></script>
<script src="js/util/Color.js"></script>
<script src="js/util/Rectangle.js"></script>
<script src="js/Sprite.js"></script>
<script src="js/Reporter.js"></script>
<script src="js/Stage.js"></script>
<script src="js/sound/WAVFile.js"></script>
<script src="js/sound/SoundDecoder.js"></script>
<script src="js/sound/SoundBank.js"></script>
<script src="js/sound/NotePlayer.js"></script>
<script src="soundbank/Instr.js"></script>
<script src="js/IO.js"></script>
<script src="js/primitives/VarListPrims.js"></script>
<script src="js/primitives/MotionAndPenPrims.js"></script>
<script src="js/primitives/LooksPrims.js"></script>
<script src="js/primitives/SensingPrims.js"></script>
<script src="js/primitives/SoundPrims.js"></script>
<script src="js/primitives/Primitives.js"></script>
<script src="js/Interpreter.js"></script>
<script src="js/Runtime.js"></script>
<script src="js/Scratch.js"></script>
<script type="text/javascript">
if (window.location.hash) {
var project_id = parseInt(window.location.hash.substr(1));
} else {
var project_id = 10000160; // Default project for display
}
</script>
<script>
$(function() {
// The flashvars tell flash about the project data (and autostart=true)
var flashvars = {
server: encodeURIComponent('scratch.mit.edu'),
project_id: project_id
};

// Pass in the cloud token for the project
if(window.getCloudToken)
flashvars.cloud_token = encodeURIComponent(getCloudToken());

var params = {
allowscriptaccess: 'always',
allowfullscreen: 'false',
wmode: 'direct',
menu: 'false'};

var flashPlayer = null;
//var swf_url = "http://cdn.scratch.mit.edu/scratchr2/static/Scratch.swf";
var swf_url = "http://jiggler.media.mit.edu/shanemc/scratchr2/static/Scratch.swf";
swfobject.embedSWF(swf_url, "flashScratch", "480", "400", "10.2.0",
"http://cdn.scratch.mit.edu/scratchr2/static/expressInstall.swf",
flashvars, params, null, function(e) {
$('#flashScratch').css('visibility', 'visible');
if(e.success) flashPlayer = e.ref;
});

$('#trigger_green_flag, #greenSlide').click(function() {
flashPlayer.ASstartRunning();
});

// Stop button behavior
$('#trigger_stop').click(function() {
flashPlayer.ASstopRunning();
});
});
</script>
</head>
<body>
<div style="display: inline-block;">
<div id="up">&nbsp;</div>
<div id="left">&nbsp;</div>
<div id="overContainer">
<div id="greenSlide"><div id="greenSlideFg"><img src="img/greenflag.png"></div></div>
<div id="container"></div>
</div>
<div id="right">&nbsp;</div>
<div id="down">&nbsp;</div>
</div>
<div style="display: inline-block;">
<div id="flashScratch" style="text-align:center;visibility:hidden;">
<p style="color:#aaa;font-size:22px;margin-top:14px;line-height:28px;">Oh Noes! Scratch project cannot display.<br/>Flash player is disabled, missing, or less than version 10.2.</p>
<a href="http://www.adobe.com/go/getflashplayer">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" target="_blank" />
</a>
</div>
</div>

<div id="info">Loading...</div>

<button id="trigger_green_flag">Green flag</button>
<button id="trigger_stop">Stop</button>

<input type="text" name="project_id" id="project_id" /><button id='go_project'>Go!</button>
</body>
</html>
15 changes: 15 additions & 0 deletions copyright.txt
@@ -0,0 +1,15 @@
// Copyright (C) 2013 Massachusetts Institute of Technology
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 2,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Binary file added img/greenflag.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/say-bottom.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/think-bottom.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions index.html
@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html>
<head>
<title>Scratch HTML5</title>
<meta charset="utf-8">
<!-- iPad properties: set width, disable pinch zoom -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="viewport" content="user-scalable=no, width=540" />
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<style type="text/css">
body {
background: #222;
color: #fff;
margin: 0;
}
</style>
<link href="player.css" type="text/css" rel="stylesheet" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="js/util/Timer.js"></script>
<script src="js/util/OffsetBuffer.js"></script>
<script src="js/util/Color.js"></script>
<script src="js/util/Rectangle.js"></script>
<script src="js/Sprite.js"></script>
<script src="js/Reporter.js"></script>
<script src="js/Stage.js"></script>
<script src="js/sound/WAVFile.js"></script>
<script src="js/sound/SoundDecoder.js"></script>
<script src="js/sound/SoundBank.js"></script>
<script src="js/sound/NotePlayer.js"></script>
<script src="soundbank/Instr.js"></script>
<script src="js/IO.js"></script>
<script src="js/primitives/VarListPrims.js"></script>
<script src="js/primitives/MotionAndPenPrims.js"></script>
<script src="js/primitives/LooksPrims.js"></script>
<script src="js/primitives/SensingPrims.js"></script>
<script src="js/primitives/SoundPrims.js"></script>
<script src="js/primitives/Primitives.js"></script>
<script src="js/Interpreter.js"></script>
<script src="js/Runtime.js"></script>
<script src="js/Scratch.js"></script>
<script type="text/javascript">
if (window.location.hash) {
var project_id = parseInt(window.location.hash.substr(1));
} else {
var project_id = 10000160; // Default project for display
}
</script>
</head>
<body>
<div id="up">&nbsp;</div>
<div id="left">&nbsp;</div>
<div id="overContainer">
<div id="greenSlide"><div id="greenSlideFg"><img src="img/greenflag.png"></div></div>
<div id="container"></div>
</div>
<div id="right">&nbsp;</div>
<div id="down">&nbsp;</div>

<div id="info">Loading...</div>

<button id="trigger_green_flag">Green flag</button>
<button id="trigger_stop">Stop</button>

<input type="text" name="project_id" id="project_id" /><button id='go_project'>Go!</button>
</body>
</html>
136 changes: 136 additions & 0 deletions js/IO.js
@@ -0,0 +1,136 @@
// Copyright (C) 2013 Massachusetts Institute of Technology
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 2,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

// Scratch HTML5 Player
// IO.js
// Tim Mickel, March 2012

// IO handles JSON communication and processing.
// We make the sprites and threads here.

'use strict';

var IO = function() {
this.data = null;
// In production, simply use the local path (no proxy)
// since we won't be hampered by the same-origin policy.
this.base = 'proxy.php?resource=internalapi/';
this.project_base = this.base + 'project/';
this.project_suffix = '/get/';
this.asset_base = this.base + 'asset/';
this.asset_suffix = '/get/';
this.soundbank_base = 'soundbank/';
this.spriteLayerCount = 0;
}

IO.prototype.loadProject = function(project_id) {
var runningIO = this;
$.getJSON(this.project_base + project_id + this.project_suffix,
function(data) {
runningIO.data = data;
runningIO.makeObjects();
runningIO.loadThreads();
runningIO.loadNotesDrums();
runtime.loadStart(); // Try to run the project.
}
);
}

IO.prototype.soundRequest = function(sound, sprite) {
var request = new XMLHttpRequest();
request.open('GET', this.asset_base + sound['md5'] + this.asset_suffix, true);
request.responseType = 'arraybuffer';
request.onload = function() {
var waveData = request.response;
// Decode the waveData and populate a buffer channel with the samples
var snd = new SoundDecoder(waveData);
var samples = snd.getAllSamples();
sound.buffer = runtime.audioContext.createBuffer(1, samples.length, runtime.audioContext.sampleRate);
var data = sound.buffer.getChannelData(0);
for (var i = 0; i < data.length; i++) {
data[i] = samples[i];
}
sprite.soundsLoaded++;
}
request.send();
}

IO.prototype.loadNotesDrums = function() {
var self = this;
$.each(Instr.wavs, function(name, file) {
var request = new XMLHttpRequest();
request.open('GET', self.soundbank_base + escape(file), true);
request.responseType = 'arraybuffer';
request.onload = function() {
var waveData = new OffsetBuffer(request.response);
// Decode the waveData and populate a buffer channel with the samples
var info = WAVFile.decode(request.response);
waveData.offset = info.sampleDataStart;
var soundBuffer = waveData.readBytes(2 * info.sampleCount);
Instr.samples[name] = soundBuffer;
Instr.wavsLoaded++;
}
request.send();
});
}

IO.prototype.makeObjects = function() {
// Create the stage
runtime.stage = new Stage(this.data);
runtime.stage.attach(runtime.scene);
runtime.stage.attachPenLayer(runtime.scene);
runtime.stage.loadSounds();

// Create the sprites
$.each(this.data.children, function(index, obj) {
var newSprite;
if(!obj.cmd) {
newSprite = new Sprite(obj);
} else {
newSprite = new Reporter(obj);
runtime.reporters.push(newSprite);
}
runtime.sprites.push(newSprite);
newSprite.attach(runtime.scene);
if (!obj.cmd)
newSprite.loadSounds();
});
}

IO.prototype.loadThreads = function() {
var target = runtime.stage;
var scripts = target.data.scripts;
if (scripts) {
for (var s in scripts) {
target.stacks.push(interp.makeBlockList(scripts[s][2]));
}
}
$.each(this.data.children, function(index, obj) {
target = runtime.sprites[index];
if (typeof(target) != 'undefined' && target.data && target.data.scripts) {
$.each(target.data.scripts, function(j, s) {
target.stacks.push(interp.makeBlockList(s[2]));
});
}
});
}

// Returns the number sprite we are rendering
// used for initial layering assignment
IO.prototype.getCount = function() {
var rv = this.spriteLayerCount;
this.spriteLayerCount++;
return rv;
}

0 comments on commit 6360de0

Please sign in to comment.