diff options
| -rw-r--r-- | gui.js | 9 | ||||
| -rw-r--r-- | objects.js | 130 | ||||
| -rwxr-xr-x | snap.html | 42 | ||||
| -rw-r--r-- | threads.js | 40 |
4 files changed, 137 insertions, 84 deletions
@@ -211,6 +211,10 @@ IDE_Morph.prototype.init = function (isAutoFill) { this.serializer = new SnapSerializer(); this.globalVariables = new VariableFrame(); + + // recreate all Sprite markers (Snap-YOW) + window.spriteGroup = L.layerGroup().addTo(window.map); + this.currentSprite = new SpriteMorph(this.globalVariables); this.sprites = new List([this.currentSprite]); this.currentCategory = 'map'; @@ -2797,6 +2801,11 @@ IDE_Morph.prototype.newProject = function () { location.hash = ''; } this.globalVariables = new VariableFrame(); + + // recreate all Sprite markers (Snap-YOW) + window.map.removeLayer(window.spriteGroup); + window.spriteGroup = L.layerGroup().addTo(window.map); + this.currentSprite = new SpriteMorph(this.globalVariables); this.sprites = new List([this.currentSprite]); StageMorph.prototype.dimensions = new Point(480, 360); @@ -203,10 +203,15 @@ SpriteMorph.prototype.initBlocks = function () { SpriteMorph.prototype.blocks = { // Map (Snap! in Your Own World) - reportLocation: { + reportUserLocation: { type: 'reporter', category: 'map', - spec: 'current location' + spec: 'current user location' + }, + reportMyLocation: { + type: 'reporter', + category: 'map', + spec: 'my location' }, focusMap: { type: 'command', @@ -218,37 +223,49 @@ SpriteMorph.prototype.initBlocks = function () { dev: true, type: 'command', category: 'map', - spec: 'add a marker to %l' + spec: 'debug: add a marker to %l' }, - - // Motion - forward: { + moveTo: { only: SpriteMorph, type: 'command', - category: 'motion', - spec: 'move %n steps', - defaults: [10] + category: 'map', + spec: 'move to %l' }, turn: { only: SpriteMorph, type: 'command', - category: 'motion', + category: 'map', spec: 'turn %clockwise %n degrees', defaults: [15] }, turnLeft: { only: SpriteMorph, type: 'command', - category: 'motion', + category: 'map', spec: 'turn %counterclockwise %n degrees', defaults: [15] }, setHeading: { only: SpriteMorph, type: 'command', - category: 'motion', + category: 'map', spec: 'point in direction %dir' }, + direction: { + only: SpriteMorph, + type: 'reporter', + category: 'map', + spec: 'direction' + }, + + // Motion + forward: { + only: SpriteMorph, + type: 'command', + category: 'motion', + spec: 'move %n steps', + defaults: [10] + }, doFaceTowards: { only: SpriteMorph, type: 'command', @@ -321,12 +338,6 @@ SpriteMorph.prototype.initBlocks = function () { category: 'motion', spec: 'y position' }, - direction: { - only: SpriteMorph, - type: 'reporter', - category: 'motion', - spec: 'direction' - }, // Looks doSwitchToCostume: { @@ -1319,8 +1330,8 @@ SpriteMorph.prototype.init = function (globals) { this.variables = new VariableFrame(globals || null, this); this.scripts = new ScriptsMorph(this); this.customBlocks = []; - this.costumes = new List(); - this.costume = null; + this.costume = new Costume(window.defaultCostume, "marker"); + this.costumes = new List([this.costume]); this.sounds = new List(); this.normalExtent = new Point(60, 60); // only for costume-less situation this.scale = 1; @@ -1360,14 +1371,12 @@ SpriteMorph.prototype.init = function (globals) { this.isDown = false; // Snap! - YOW code - this.icon = L.icon({ - iconUrl: 'images/marker-icon.png', - iconRetinaUrl: 'images/marker-icon-2x.png', - shadowUrl: 'images/marker-shadow.png' - }); this.geoposition = window.map.getCenter(); - this.marker = L.marker(this.geoposition, {icon: this.icon, title: this.name}); - this.marker.addTo(window.map); + + // TODO this is a bit hacky + this.marker = L.spriteMarker(this.geoposition); + this.marker.addTo(window.spriteGroup); + this.updateMarker(); this.heading = 90; this.changed(); @@ -1375,6 +1384,33 @@ SpriteMorph.prototype.init = function (globals) { this.changed(); }; +SpriteMorph.prototype.updateMarker = function () { + // sadly, the name can not be changed on the fly, so the element has to be recreated + // TODO: XSS? Extend L.Icon? + if (!this.marker) return; + window.spriteGroup.removeLayer(this.marker); + this.icon = L.divIcon({ + className: 'snap-sprite', + html: '<div id="icon-' + this.name + '"></div>', + iconSize: [this.costume.contents.width, this.costume.contents.height], + iconAnchor: [this.rotationOffset.x, this.rotationOffset.y] + }); + this.marker = L.spriteMarker(this.geoposition, {icon: this.icon, title: this.name}); + this.marker.setAngle(this.heading - 90); + this.marker.addTo(window.spriteGroup); + document.getElementById('icon-' + this.name).appendChild(this.costume.contents); +}; + +/* + * // for later + this.icon = new L.Icon.Canvas({ + iconSize: [this.costume.contents.width, this.costume.contents.height]}); + var myself = this; + this.icon.draw = function(ctx, w, h) {ctx.drawImage(myself.costume.contents, 0, 0);}; + this.marker = L.marker(this.geoposition, {icon: this.icon, title: this.name}); + this.marker.addTo(window.spriteGroup); +*/ + // SpriteMorph duplicating (fullCopy) SpriteMorph.prototype.fullCopy = function () { @@ -1554,6 +1590,7 @@ SpriteMorph.prototype.drawNew = function () { } } this.version = Date.now(); + this.updateMarker(); // Snap! YOW }; SpriteMorph.prototype.endWarp = function () { @@ -1732,21 +1769,24 @@ SpriteMorph.prototype.blockTemplates = function (category) { } if (cat === 'map') { - - blocks.push(block('reportLocation')); + blocks.push(block('reportUserLocation')); blocks.push(block('focusMap')); + blocks.push(block('moveTo')); //if (this.world().isDevMode) { blocks.push(block('addMarker')); //} + blocks.push('-'); + blocks.push(block('turn')); + blocks.push(block('turnLeft')); + blocks.push(block('setHeading')); + blocks.push(watcherToggle('direction')); + blocks.push(block('direction')); } /* else if (cat === 'motion') { blocks.push(block('forward')); - blocks.push(block('turn')); - blocks.push(block('turnLeft')); blocks.push('-'); - blocks.push(block('setHeading')); blocks.push(block('doFaceTowards')); blocks.push('-'); blocks.push(block('gotoXY')); @@ -1764,8 +1804,6 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push(block('xPosition')); blocks.push(watcherToggle('yPosition')); blocks.push(block('yPosition')); - blocks.push(watcherToggle('direction')); - blocks.push(block('direction')); } */ else if (cat === 'looks') { @@ -1950,7 +1988,7 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push(block('doSetFastTracking')); blocks.push('-'); blocks.push(block('reportDate')); - blocks.push(block('reportLocation')); + blocks.push(block('reportUserLocation')); // for debugging: /////////////// @@ -2615,7 +2653,7 @@ SpriteMorph.prototype.doSwitchToCostume = function (id) { (id instanceof Array ? id[0] : null) ) ) { - costume = null; + this.costume = new Costume(window.defaultCostume, "marker"); } else { if (id === -1) { this.doWearPreviousCostume(); @@ -2627,7 +2665,7 @@ SpriteMorph.prototype.doSwitchToCostume = function (id) { if (costume === null) { num = parseFloat(id); if (num === 0) { - costume = null; + this.costume = new Costume(window.defaultCostume, "marker"); } else { costume = arr[num - 1] || null; } @@ -3310,6 +3348,13 @@ SpriteMorph.prototype.nestingBounds = function () { return result; }; +// SpriteMorph YOW map primitives + +SpriteMorph.prototype.moveTo = function (pos) { + this.geoposition = pos.contents; + this.updateMarker(); +}; + // SpriteMorph motion primitives Morph.prototype.setPosition = function (aPoint, justMe) { @@ -4451,13 +4496,10 @@ StageMorph.prototype.drawNew = function () { StageMorph.prototype.drawOn = function (aCanvas, aRect) { var map = document.getElementById('map'); - var rectangle, area; - rectangle = aRect || this.bounds; - area = rectangle.intersect(this.bounds).round(); map.style.width = this.dimensions.x * this.scale + 'px'; map.style.height = this.dimensions.y * this.scale + 'px'; - map.style.left = area.left() + 'px'; - map.style.top = area.top() + 'px'; + map.style.left = this.left() + 'px'; + map.style.top = this.top() + 'px'; window.map.invalidateSize(); }; @@ -4922,7 +4964,7 @@ StageMorph.prototype.blockTemplates = function (category) { if (cat === 'map') { - blocks.push(block('reportLocation')); + blocks.push(block('reportUserLocation')); blocks.push(block('focusMap')); if (this.world().isDevMode) { blocks.push(block('addMarker')); @@ -5084,7 +5126,7 @@ StageMorph.prototype.blockTemplates = function (category) { blocks.push(block('doSetFastTracking')); blocks.push('-'); blocks.push(block('reportDate')); - blocks.push(block('reportLocation')); + blocks.push(block('reportUserLocation')); // for debugging: /////////////// @@ -27,7 +27,25 @@ <div id="map" style="position: absolute; width: 480px; height: 360px;" /> <!-- set initial size to 480x360 or the map will not load properly --> <script type="text/javascript"> - var world, map, layer; + L.SpriteMarker = L.Marker.extend({ + options: { + angle: 0 + }, + _setPos: function (pos) { + L.Marker.prototype._setPos.call(this, pos); + this._icon.style[L.DomUtil.TRANSFORM] += ' rotate(' + this.options.angle + 'deg)'; + // TODO: set rotation center with transform-origin + }, + setAngle: function (angle) { + this.options.angle = angle; + this.update(); + } + }); + L.spriteMarker = function(pos, options) { + return new L.SpriteMarker(pos, options); + }; + + var world, map, layer, spriteGroup, defaultCostume; function loop() { world.doOneCycle(); @@ -38,22 +56,42 @@ } function startYOW (e) { + setGlobalPosition(e); + map.stopLocate(); map.on('locationfound', setGlobalPosition); map.locate({watch: true, enableHighAccuracy: true}); new OSMBuildings(map).load(); + window.spriteGroup = spriteGroup; + spriteGroup = L.layerGroup().addTo(map); + world = new WorldMorph(document.getElementById('world')); world.worldCanvas.focus(); new IDE_Morph().openIn(world); setInterval(loop, 10); } + // TODO: this needs to be improved + function loadDefaultCostume (e) { + image = new Image(); + image.src = 'images/marker-icon.png'; + image.onload = function () { + defaultCostume = document.createElement('canvas'); + defaultCostume.width = image.width; + defaultCostume.height = image.height; + var context = defaultCostume.getContext('2d'); + context.drawImage(image, 0, 0); + window.defaultCostume = defaultCostume; + startYOW(e); + } + } + window.map = map; window.layer = layer; map = L.map('map'); - map.on('locationfound', startYOW); + map.on('locationfound', loadDefaultCostume); map.locate({setView: true}); layer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' @@ -2626,51 +2626,15 @@ Process.prototype.reportTimer = function () { return 0; }; -Process.prototype.reportLocation = function (name) { - var myself = this; - - if (!myself.context.position) { - myself.context.position = []; - - if (!navigator.geolocation) { - myself.handleError({name: 'Location', - message: 'navigator.geolocation is not supported'}); - } - - navigator.geolocation.getCurrentPosition( - function (pos) { - myself.context.position = [ - pos.coords.latitude, pos.coords.longitude]; - }, - function (err) { - console.log(err); - myself.handleError({name: 'Location', message: err.message}); - }, - { enableHightAccuracy: true, timeout: 5000, maximumAge: 0} - ); - } else { - if (myself.context.position.length == 2) { - return new List(myself.context.position); - } - } - - this.pushContext('doYield'); - this.pushContext(); +Process.prototype.reportUserLocation = function () { + return new List([window.geoposition.lat, window.geoposition.lng]); }; Process.prototype.focusMap = function (pos, zoom) { - if (pos.contents.length != 2) { - this.handleError({name: 'Location', - message: 'expecting a list of latitude/longitude'}); - } window.map.setView(pos.contents, zoom); }; Process.prototype.addMarker = function (pos) { - if (pos.contents.length != 2) { - this.handleError({name: 'Location', - message: 'expecting a list of latitude/longitude'}); - } L.marker(pos.contents).addTo(window.map); }; |
