Compare commits

...

12 Commits

Author SHA1 Message Date
8bab919db2 0.0.87 2018-02-01 22:21:15 -08:00
89a82b54dc Ir proximity in simulator (#299)
* support for IR proximity

* fixing build issue

* missing break

* remove auto-start of sensor

* setting mode on onEvent

* flooring slider value

* bump up proximity

* fixing threshold blocks
2018-02-01 22:03:01 -08:00
15ee6ebe9c 0.0.86 2018-02-01 16:46:10 -08:00
9bf50665fc improving the spacing & block names (#298) 2018-02-01 16:21:08 -08:00
f594cdefac add infrared sensor in ev3 library (#296) 2018-02-01 16:18:20 -08:00
5ce7a83f5d 0.0.85 2018-02-01 14:41:42 -08:00
d7ef7c353c typo in generated filter 2018-02-01 14:08:28 -08:00
c7cb300cd9 fixing lights in Edge/Firefox 2018-02-01 14:03:36 -08:00
4e194536d3 0.0.84 2018-01-31 20:10:23 -08:00
570cd7474f upgrade pxt 2018-01-31 20:10:13 -08:00
9ea5597734 0.0.83 2018-01-31 18:10:38 -08:00
2c0cc6a3d7 Use decodebase64 (#295)
* avoid atob directly

* prevent port names to be selected

* updated pxt
2018-01-31 18:10:15 -08:00
22 changed files with 318 additions and 40 deletions

View File

@ -77,7 +77,7 @@ export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
let rbfBIN = pxt.U.fromHex(rbfHex)
pxt.HF2.write16(rbfBIN, 4, rbfBIN.length)
let origElfUF2 = UF2.parseFile(pxt.U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()])))
let origElfUF2 = UF2.parseFile(pxt.U.stringToUint8Array(ts.pxtc.decodeBase64(resp.outfiles[pxt.outputName()])))
let mkFile = (ext: string, data: Uint8Array = null) => {
let f = UF2.newBlockFile()

View File

@ -115,7 +115,7 @@ namespace sensors {
//% parts="colorsensor"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=100 blockGap=8
//% weight=100 blockGap=12
//% group="Color Sensor"
onColorDetected(color: ColorSensorColor, handler: () => void) {
this.setMode(ColorSensorMode.Color)
@ -174,7 +174,7 @@ namespace sensors {
//% parts="colorsensor"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=89 blockGap=8
//% weight=89 blockGap=12
//% group="Color Sensor"
onLightChanged(mode: LightIntensityMode, condition: LightCondition, handler: () => void) {
this.setMode(<ColorSensorMode><number>mode)

View File

@ -116,7 +116,7 @@ namespace brick {
//% blockId=buttonEvent block="on %button|%event"
//% parts="brick"
//% blockNamespace=brick
//% weight=99 blockGap=8
//% weight=99 blockGap=16
//% group="Buttons"
//% button.fieldEditor="brickbuttons"
onEvent(ev: ButtonEvent, body: () => void) {

View File

@ -187,7 +187,7 @@ namespace motors {
*/
//% weight=6 blockGap=8
//% group="Move"
//% blockId=motorStop block="%motors|stop"
//% blockId=motorStop block="stop %motors|"
stop() {
this.init();
stop(this._port, this._brake);
@ -206,7 +206,7 @@ namespace motors {
*/
//% weight=5
//% group="Move"
//% blockId=motorReset block="%motors|reset"
//% blockId=motorReset block="reset %motors|"
reset() {
this.init();
reset(this._port);
@ -279,7 +279,7 @@ namespace motors {
* Pauses the execution until the previous command finished.
* @param timeOut optional maximum pausing time in milliseconds
*/
//% blockId=motorPauseUntilRead block="%motor|pause until ready"
//% blockId=motorPauseUntilRead block="pause until %motor|ready"
//% weight=90
//% group="Move"
pauseUntilReady(timeOut?: number) {
@ -385,7 +385,7 @@ namespace motors {
/**
* Clears the motor count
*/
//% blockId=motorClearCount block="%motor|clear counts"
//% blockId=motorClearCount block="clear %motor|counters"
//% weight=68
//% blockGap=8
//% group="Counters"

View File

@ -1,20 +1,20 @@
//% color="#68C3E2" weight=100 icon="\uf106"
//% groups='["Buttons", "Screen"]'
//% labelLineWidth=0
//% labelLineWidth=60
namespace brick {
}
//% color="#C8509B" weight=95 icon="\uf10f"
//% labelLineWidth=0
//% labelLineWidth=100
//% groups='["Touch Sensor", "Color Sensor", "Ultrasonic Sensor", "Gyro Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Threshold"]'
namespace sensors {
}
//% color="#A5CA18" weight=90 icon="\uf10d"
//% groups='["Move", "Counters"]'
//% labelLineWidth=0
//% labelLineWidth=50
namespace motors {
}

View File

@ -14,6 +14,7 @@
"touch-sensor": "file:../touch-sensor",
"ultrasonic-sensor": "file:../ultrasonic-sensor",
"gyro-sensor": "file:../gyro-sensor",
"infrared-sensor": "file:../infrared-sensor",
"mood": "file:../mood"
},
"public": true

View File

@ -82,12 +82,12 @@ namespace sensors {
* Forces a calibration of the gyro. Must be called when the sensor is completely still.
*/
//% help=input/gyro/calibrate
//% block="%sensor|reset"
//% block="reset %sensor|"
//% blockId=gyroReset
//% parts="gyroscope"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=50 blockGap=8
//% weight=50
//% group="Gyro Sensor"
reset(): void {
if (this.calibrating) return; // already in calibration mode

View File

@ -23,7 +23,7 @@ const enum IrRemoteButton {
const enum InfraredSensorEvent {
//% block="object near"
ObjectNear = 1,
ObjectNear = 3,
//% block="object detected"
ObjectDetected = 2
}
@ -60,11 +60,12 @@ namespace sensors {
buttons.push(new RemoteInfraredBeaconButton(new brick.Button()))
}
// this defeats our static allocation system
// make sure sensors are up
create(infraredSensor1)
create(infraredSensor2)
create(infraredSensor3)
create(infraredSensor4)
//create(infraredSensor1)
//create(infraredSensor2)
//create(infraredSensor3)
//create(infraredSensor4)
}
let num = -1
@ -196,6 +197,7 @@ namespace sensors {
//% weight=100 blockGap=8
//% group="Infrared Sensor"
onEvent(event: InfraredSensorEvent, handler: () => void) {
this._setMode(IrSensorMode.Proximity)
control.onEvent(this._id, event, handler);
}
@ -210,6 +212,7 @@ namespace sensors {
//% weight=99 blockGap=8
//% group="Infrared Sensor"
pauseUntil(event: InfraredSensorEvent) {
this._setMode(IrSensorMode.Proximity)
control.waitForEvent(this._id, event);
}
@ -222,7 +225,7 @@ namespace sensors {
//% blockId=infraredGetProximity
//% parts="infrared"
//% blockNamespace=sensors
//% weight=65 blockGap=8
//% weight=98 blockGap=8
//% group="Infrared Sensor"
proximity(): number {
this._setMode(IrSensorMode.Proximity)

View File

@ -34,7 +34,7 @@ namespace sensors {
//% parts="touch"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=99 blockGap=8
//% weight=99 blockGap=12
//% group="Touch Sensor"
onEvent(ev: ButtonEvent, body: () => void) {
this.button.onEvent(ev, body)
@ -50,7 +50,7 @@ namespace sensors {
//% parts="touch"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=98 blockGap=8
//% weight=98 blockGap=12
//% group="Touch Sensor"
pauseUntil(ev: ButtonEvent) {
this.button.pauseUntil(<ButtonEvent><number>ev);
@ -66,7 +66,7 @@ namespace sensors {
//% parts="touch"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=81
//% weight=81 blockGap=8
//% group="Touch Sensor"
isPressed() {
return this.button.isPressed();
@ -82,7 +82,7 @@ namespace sensors {
//% parts="touch"
//% blockNamespace=sensors
//% sensor.fieldEditor="ports"
//% weight=81 blockGap=8
//% weight=81
//% group="Touch Sensor"
wasPressed() {
return this.button.wasPressed();

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "pxt-ev3",
"version": "0.0.82",
"version": "0.0.87",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "pxt-ev3",
"version": "0.0.82",
"version": "0.0.87",
"description": "LEGO Mindstorms EV3 for Microsoft MakeCode",
"private": true,
"keywords": [
@ -45,7 +45,7 @@
},
"dependencies": {
"pxt-common-packages": "0.17.13",
"pxt-core": "3.1.3"
"pxt-core": "3.2.1"
},
"scripts": {
"test": "node node_modules/pxt-core/built/pxt.js travis"

View File

@ -143,6 +143,7 @@ namespace pxsim {
case DAL.DEVICE_TYPE_COLOR: this.inputNodes[port] = new ColorSensorNode(port); break;
case DAL.DEVICE_TYPE_TOUCH: this.inputNodes[port] = new TouchSensorNode(port); break;
case DAL.DEVICE_TYPE_ULTRASONIC: this.inputNodes[port] = new UltrasonicSensorNode(port); break;
case DAL.DEVICE_TYPE_IR: this.inputNodes[port] = new InfraredSensorNode(port); break;
}
}
return this.inputNodes[port];

35
sim/state/infrared.ts Normal file
View File

@ -0,0 +1,35 @@
/// <reference path="./sensor.ts"/>
namespace pxsim {
export enum InfraredSensorMode {
None = -1,
Proximity = 0,
Seek = 1,
RemoteControl = 2
}
export class InfraredSensorNode extends UartSensorNode {
id = NodeType.InfraredSensor;
private proximity: number = 50; // [0..100]
constructor(port: number) {
super(port);
}
getDeviceType() {
return DAL.DEVICE_TYPE_IR;
}
setPromixity(proximity: number) {
if (this.proximity != proximity) {
this.proximity = proximity;
this.setChangedState();
}
}
getValue() {
return this.proximity;
}
}
}

View File

@ -7,7 +7,8 @@ namespace pxsim {
LargeMotor = 4,
GyroSensor = 5,
ColorSensor = 6,
UltrasonicSensor = 7
UltrasonicSensor = 7,
InfraredSensor = 8
}
export interface Node {

View File

@ -17,17 +17,17 @@
<stop offset="0.52" stop-color="#6a6a6a"/>
<stop offset="1" stop-color="#6a6a6a"/>
</linearGradient>
<linearGradient id="linear-gradient-green" x1="-382.07" y1="493.36" x2="-382.07" y2="494.25" gradientTransform="matrix(65.53, 0, 0, -48.84, 25091.11, 24228.69)" gradientUnits="userSpaceOnUse">
<linearGradient id="linear-gradient-green" x1="0" y1="0" x2="145" y2="48" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#6a6a6a"/>
<stop offset="0.52" stop-color="#8CE300"/>
<stop offset="1" stop-color="#6a6a6a"/>
</linearGradient>
<linearGradient id="linear-gradient-red" x1="-382.07" y1="493.36" x2="-382.07" y2="494.25" gradientTransform="matrix(65.53, 0, 0, -48.84, 25091.11, 24228.69)" gradientUnits="userSpaceOnUse">
<linearGradient id="linear-gradient-red" x1="0" y1="0" x2="145" y2="48" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#6a6a6a"/>
<stop offset="0.52" stop-color="#D02E26"/>
<stop offset="1" stop-color="#6a6a6a"/>
</linearGradient>
<linearGradient id="linear-gradient-orange" x1="-382.07" y1="493.36" x2="-382.07" y2="494.25" gradientTransform="matrix(65.53, 0, 0, -48.84, 25091.11, 24228.69)" gradientUnits="userSpaceOnUse">
<linearGradient id="linear-gradient-orange" x1="0" y1="0" x2="145" y2="48" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#6a6a6a"/>
<stop offset="0.52" stop-color="#F8D039"/>
<stop offset="1" stop-color="#6a6a6a"/>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,6 +1,7 @@
namespace pxsim.visuals {
export const EV3_SVG = `<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 110.73 170.04">
export const EV3_SVG = `
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 110.73 170.04">
<defs>
<linearGradient id="linear-gradient" x1="-374.89" y1="432.9" x2="-374.89" y2="432.82" gradientTransform="matrix(110.73, 0, 0, -106.94, 41567.45, 46425.3)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f1f1f1"/>
@ -19,17 +20,17 @@ namespace pxsim.visuals {
<stop offset="0.52" stop-color="#6a6a6a"/>
<stop offset="1" stop-color="#6a6a6a"/>
</linearGradient>
<linearGradient id="linear-gradient-green" x1="-382.07" y1="493.36" x2="-382.07" y2="494.25" gradientTransform="matrix(65.53, 0, 0, -48.84, 25091.11, 24228.69)" gradientUnits="userSpaceOnUse">
<linearGradient id="linear-gradient-green" x1="0" y1="0" x2="145" y2="48" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#6a6a6a"/>
<stop offset="0.52" stop-color="#8CE300"/>
<stop offset="1" stop-color="#6a6a6a"/>
</linearGradient>
<linearGradient id="linear-gradient-red" x1="-382.07" y1="493.36" x2="-382.07" y2="494.25" gradientTransform="matrix(65.53, 0, 0, -48.84, 25091.11, 24228.69)" gradientUnits="userSpaceOnUse">
<linearGradient id="linear-gradient-red" x1="0" y1="0" x2="145" y2="48" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#6a6a6a"/>
<stop offset="0.52" stop-color="#D02E26"/>
<stop offset="1" stop-color="#6a6a6a"/>
</linearGradient>
<linearGradient id="linear-gradient-orange" x1="-382.07" y1="493.36" x2="-382.07" y2="494.25" gradientTransform="matrix(65.53, 0, 0, -48.84, 25091.11, 24228.69)" gradientUnits="userSpaceOnUse">
<linearGradient id="linear-gradient-orange" x1="0" y1="0" x2="145" y2="48" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#6a6a6a"/>
<stop offset="0.52" stop-color="#F8D039"/>
<stop offset="1" stop-color="#6a6a6a"/>
@ -104,5 +105,6 @@ namespace pxsim.visuals {
<path id="ev3_e" data-name="ev3 e" d="M19.39,156.1a.34.34,0,0,1,.38.3v1.17a.33.33,0,0,1-.38.3H14.34c-.11,0-.2.06-.2.14h0v.82h0c0,.08.09.14.2.14h5.05a.33.33,0,0,1,.38.3v1.15a.33.33,0,0,1-.35.3H12.67a.35.35,0,0,1-.38-.3v-6.89a.34.34,0,0,1,.38-.3h6.75a.31.31,0,0,1,.35.28v1.17a.31.31,0,0,1-.33.3H14.36c-.11,0-.22,0-.22.13V156c0,.08.09.14.19.14Z" transform="translate(0 0)" style="fill: #f1f1f1"/>
</g>
</g>
</svg>`;
</svg>
`;
}

View File

@ -6,7 +6,7 @@ namespace pxsim.visuals {
<path id="port_2" data-name="port 2" d="M4.48,0h50V58.93h-50Z" transform="translate(-4.48)" style="fill: #eaeaea"/>
<path id="port_1" data-name="port 1" d="M9.74,46.49V18.66H26.85V11.75h4.72V2.59H44.49v8.82h5.06V46.49h-8v7.43H38.9V46.41h-2v7.5H34.71v-7.5H32.55v7.5h-2.1v-7.5H28.6v7.5H26.5v-7.5H24.68v7.5H22.22v-7.5H20.54v7.5H18V46.46Z" transform="translate(-4.48)" style="fill: #a8aaa8"/>
<g id="text10060" style="isolation: isolate">
<text id="port_text" transform="translate(22.21 40.2)" style="isolation: isolate;font-size: 16px;fill: white;font-family: ArialMT, Arial">B</text>
<text id="port_text" class="user-select-none" transform="translate(22.21 40.2)" style="isolation: isolate;font-size: 16px;fill: white;font-family: ArialMT, Arial">B</text>
</g>
</g>
</svg>`;

View File

@ -0,0 +1,79 @@
namespace pxsim {
export const INFRARED_SVG = `<svg id="svg5190" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.53 35.14">
<defs>
<clipPath id="clip-path" transform="translate(0.04 -22.43)">
<circle cx="17.53" cy="40" r="6.98" style="fill: none"/>
</clipPath>
<clipPath id="clip-path-2" transform="translate(0.04 -22.43)">
<circle cx="65.92" cy="40" r="6.98" style="fill: none"/>
</clipPath>
</defs>
<title>ultra sonic</title>
<g id="ultra_sonic" data-name="ultra sonic">
<rect id="US_main_black2" data-name="US main black2" x="22.57" y="1.49" width="43.38" height="31.25" style="fill: #242424"/>
<rect id="US_main_black1" data-name="US main black1" x="30.16" y="8.47" width="25.33" height="17.59"/>
<g id="US_eye1" data-name="US eye1">
<g id="US_eye1_black" data-name="US eye1 black">
<circle cx="17.57" cy="17.57" r="17.44" style="stroke: #b3b3b3;stroke-miterlimit: 10;stroke-width: 0.25px"/>
<circle cx="17.57" cy="17.57" r="17.32" style="fill: none"/>
</g>
<circle id="US_eye1_red" data-name="US eye1 red" cx="17.57" cy="17.57" r="10.77" style="fill: #ab1919"/>
<circle id="US_eye1_gold_circle" data-name="US eye1 gold circle" cx="17.57" cy="17.57" r="8.04" style="fill: #aa7707"/>
<circle id="US_eye1_wh_in_gold" data-name="US eye1 wh in gold" cx="17.57" cy="17.57" r="6.98" style="fill: #f1f1f1"/>
<g id="US_eye1_net" data-name="US eye1 net">
<g style="clip-path: url(#clip-path)">
<g id="US_eye1_net_mask" data-name="US eye1 net mask">
<g id="US_eye1_net_total" data-name="US eye1 net total">
<rect id="US_eye1_net14" data-name="US eye1 net14" x="10.84" y="33.53" width="0.61" height="22.79" transform="translate(-20.93 -10.84) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net13" data-name="US eye1 net13" x="11.8" y="47.44" width="22.51" height="0.61" transform="translate(-20.75 -4.51) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net12" data-name="US eye1 net12" x="13.33" y="32.09" width="0.61" height="22.79" transform="translate(-19.88 -9.79) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net11" data-name="US eye1 net11" x="10.36" y="44.95" width="22.51" height="0.61" transform="translate(-19.7 -5.56) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net10" data-name="US eye1 net10" x="15.83" y="30.65" width="0.61" height="22.79" transform="translate(-18.82 -8.73) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net9" data-name="US eye1 net9" x="8.92" y="42.45" width="22.51" height="0.61" transform="translate(-18.64 -6.62) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net8" data-name="US eye1 net8" x="18.33" y="29.21" width="0.61" height="22.79" transform="translate(-17.77 -7.68) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net7" data-name="US eye1 net7" x="7.47" y="39.96" width="22.51" height="0.61" transform="translate(-17.59 -7.67) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net6" data-name="US eye1 net6" x="20.82" y="27.77" width="0.61" height="22.79" transform="translate(-16.72 -6.62) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net5" data-name="US eye1 net5" x="6.03" y="37.46" width="22.51" height="0.61" transform="translate(-16.53 -8.73) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net4" data-name="US eye1 net4" x="23.32" y="26.32" width="0.61" height="22.79" transform="translate(-15.66 -5.57) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net3" data-name="US eye1 net3" x="4.59" y="34.96" width="22.51" height="0.61" transform="translate(-15.48 -9.78) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net2" data-name="US eye1 net2" x="25.81" y="24.88" width="0.61" height="22.79" transform="translate(-14.61 -4.51) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye1_net1" data-name="US eye1 net1" x="3.15" y="32.47" width="22.51" height="0.61" transform="translate(-14.42 -10.84) rotate(-30)" style="fill: #aa7707"/>
</g>
</g>
</g>
</g>
</g>
<g id="US_eye2" data-name="US eye2">
<g id="US_eye2_black" data-name="US eye2 black">
<circle cx="65.96" cy="17.57" r="17.44" style="stroke: #b3b3b3;stroke-miterlimit: 10;stroke-width: 0.25px"/>
<circle cx="65.96" cy="17.57" r="17.32" style="fill: none"/>
</g>
<circle id="US_eye2_red" data-name="US eye2 red" cx="65.96" cy="17.57" r="10.77" style="fill: #ab1919"/>
<circle id="US_eye2_gold_circle" data-name="US eye2 gold circle" cx="65.96" cy="17.57" r="8.04" style="fill: #aa7707"/>
<circle id="US_eye2_wh_in_gold" data-name="US eye2 wh in gold" cx="65.96" cy="17.57" r="6.98" style="fill: #f1f1f1"/>
<g id="US_eye2_net" data-name="US eye2 net">
<g style="clip-path: url(#clip-path-2)">
<g id="US_eye2_net_mask" data-name="US eye2 net mask">
<g id="US_eye2_net_total" data-name="US eye2 net total">
<rect id="US_eye2_net14" data-name="US eye2 net14" x="59.23" y="33.53" width="0.61" height="22.79" transform="translate(-14.45 13.35) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net13" data-name="US eye2 net13" x="60.18" y="47.44" width="22.51" height="0.61" transform="translate(-14.27 19.69) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net12" data-name="US eye2 net12" x="61.72" y="32.09" width="0.61" height="22.79" transform="translate(-13.4 14.41) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net11" data-name="US eye2 net11" x="58.74" y="44.95" width="22.51" height="0.61" transform="translate(-13.21 18.63) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net10" data-name="US eye2 net10" x="64.22" y="30.65" width="0.61" height="22.79" transform="translate(-12.34 15.46) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net9" data-name="US eye2 net9" x="57.3" y="42.45" width="22.51" height="0.61" transform="translate(-12.16 17.58) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net8" data-name="US eye2 net8" x="66.71" y="29.21" width="0.61" height="22.79" transform="translate(-11.29 16.52) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net7" data-name="US eye2 net7" x="55.86" y="39.96" width="22.51" height="0.61" transform="translate(-11.1 16.52) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net6" data-name="US eye2 net6" x="69.21" y="27.77" width="0.61" height="22.79" transform="translate(-10.23 17.57) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net5" data-name="US eye2 net5" x="54.42" y="37.46" width="22.51" height="0.61" transform="translate(-10.05 15.47) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net4" data-name="US eye2 net4" x="71.71" y="26.32" width="0.61" height="22.79" transform="translate(-9.18 18.63) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net3" data-name="US eye2 net3" x="52.98" y="34.96" width="22.51" height="0.61" transform="translate(-8.99 14.41) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net2" data-name="US eye2 net2" x="74.2" y="24.88" width="0.61" height="22.79" transform="translate(-8.12 19.68) rotate(-30)" style="fill: #aa7707"/>
<rect id="US_eye2_net1" data-name="US eye2 net1" x="51.54" y="32.47" width="22.51" height="0.61" transform="translate(-7.94 13.36) rotate(-30)" style="fill: #aa7707"/>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>`;
}

View File

@ -230,6 +230,12 @@ namespace pxsim.visuals {
view = new DistanceSliderControl(this.element, this.defs, state, port);
break;
}
case NodeType.InfraredSensor: {
const state = ev3board().getInputNodes()[0] as InfraredSensorNode;
if (state.getMode() == InfraredSensorMode.Proximity)
view = new ProximitySliderControl(this.element, this.defs, state, port);
break;
}
case NodeType.GyroSensor: {
const state = ev3board().getInputNodes()[port] as GyroSensorNode;
view = new RotationSliderControl(this.element, this.defs, state, port);
@ -271,6 +277,8 @@ namespace pxsim.visuals {
view = new ColorSensorView(port); break;
case NodeType.UltrasonicSensor:
view = new UltrasonicSensorView(port); break;
case NodeType.InfraredSensor:
view = new InfraredView(port); break;
case NodeType.Brick:
//return new BrickView(0);
view = this.layoutView.getBrick(); break;
@ -305,11 +313,11 @@ namespace pxsim.visuals {
// Add EV3 module element
const brickCloseIcon = this.getCloseIconView();
brickCloseIcon.registerClick(ev => {
this.layoutView.unselectBrick();
brickCloseIcon.registerClick(ev => {
this.layoutView.unselectBrick();
this.resize();
});
const brick =new BrickView(-1);
const brick = new BrickView(-1);
brick.setSelected(EV3View.isPreviousBrickSelected());
this.layoutView.setBrick(brick, brickCloseIcon);

View File

@ -0,0 +1,138 @@
namespace pxsim.visuals {
export class ProximitySliderControl extends ControlView<InfraredSensorNode> {
private group: SVGGElement;
private gradient: SVGLinearGradientElement;
private slider: SVGGElement;
private reporter: SVGTextElement;
private static SLIDER_HANDLE_HEIGHT = 26;
private static SLIDER_SIDE_PADDING = 6;
getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) {
let gid = "gradient-slider-" + this.getId();
this.group = svg.elt("g") as SVGGElement;
this.gradient = createGradient(gid, this.getGradientDefinition());
this.gradient.setAttribute('x1', '0%');
this.gradient.setAttribute('y1', '0%');
this.gradient.setAttribute('x2', '0%');
this.gradient.setAttribute('y2', '100%');
// this.gradient.setAttribute('gradientTransform', 'matrix(50, 0, 0, -110, 21949.45, 46137.67)');
// this.gradient.setAttribute('gradientUnits', 'userSpaceOnUse');
globalDefs.appendChild(this.gradient);
this.group = svg.elt("g") as SVGGElement;
const reporterGroup = pxsim.svg.child(this.group, "g");
reporterGroup.setAttribute("transform", `translate(${this.getWidth() / 2}, 42)`);
this.reporter = pxsim.svg.child(reporterGroup, "text", { 'text-anchor': 'middle', 'x': 0, 'y': '0', 'class': 'sim-text number large inverted' }) as SVGTextElement;
const sliderGroup = pxsim.svg.child(this.group, "g");
sliderGroup.setAttribute("transform", `translate(${this.getWidth() / 2 - this.getSliderWidth() / 2}, ${this.getReporterHeight()})`)
const rect = pxsim.svg.child(sliderGroup, "rect", { 'x': ProximitySliderControl.SLIDER_SIDE_PADDING, 'y': 2, 'width': this.getSliderWidth() - ProximitySliderControl.SLIDER_SIDE_PADDING * 2, 'height': this.getSliderHeight(), 'style': `fill: url(#${gid})` });
this.slider = pxsim.svg.child(sliderGroup, "g", { "transform": "translate(0,0)" }) as SVGGElement;
const sliderInner = pxsim.svg.child(this.slider, "g");
pxsim.svg.child(sliderInner, "rect", { 'width': this.getSliderWidth(), 'height': ProximitySliderControl.SLIDER_HANDLE_HEIGHT, 'rx': '2', 'ry': '2', 'style': 'fill: #f12a21' });
pxsim.svg.child(sliderInner, "rect", { 'x': '0.5', 'y': '0.5', 'width': this.getSliderWidth() - 1, 'height': ProximitySliderControl.SLIDER_HANDLE_HEIGHT - 1, 'rx': '1.5', 'ry': '1.5', 'style': 'fill: none;stroke: #b32e29' });
const dragSurface = svg.child(this.group, "rect", {
x: 0,
y: 0,
width: this.getInnerWidth(),
height: this.getInnerHeight(),
opacity: 0,
cursor: '-webkit-grab'
})
let pt = parent.createSVGPoint();
let captured = false;
touchEvents(dragSurface, ev => {
if (captured && (ev as MouseEvent).clientY != undefined) {
ev.preventDefault();
this.updateSliderValue(pt, parent, ev as MouseEvent);
}
}, ev => {
captured = true;
if ((ev as MouseEvent).clientY != undefined) {
dragSurface.setAttribute('cursor', '-webkit-grabbing');
this.updateSliderValue(pt, parent, ev as MouseEvent);
}
}, () => {
captured = false;
dragSurface.setAttribute('cursor', '-webkit-grab');
}, () => {
captured = false;
dragSurface.setAttribute('cursor', '-webkit-grab');
})
return this.group;
}
getInnerHeight() {
return 192;
}
getInnerWidth() {
return 111;
}
private getReporterHeight() {
return 50;
}
private getSliderHeight() {
return 110;
}
private getSliderWidth() {
return 62;
}
updateState() {
if (!this.visible) {
return;
}
const node = this.state;
const percentage = node.getValue();
const y = this.getSliderHeight() * percentage / this.getMax();
this.slider.setAttribute("transform", `translate(0, ${y - ProximitySliderControl.SLIDER_HANDLE_HEIGHT / 2})`);
// Update reporter text
this.reporter.textContent = `${parseFloat((percentage).toString()).toFixed(0)}`;
}
private updateSliderValue(pt: SVGPoint, parent: SVGSVGElement, ev: MouseEvent) {
let cur = svg.cursorPoint(pt, parent, ev);
const height = this.getSliderHeight();
const bBox = this.content.getBoundingClientRect();
let t = Math.max(0, Math.min(1, (ProximitySliderControl.SLIDER_HANDLE_HEIGHT + height + bBox.top / this.scaleFactor - cur.y / this.scaleFactor) / height))
const state = this.state;
const v = Math.floor((1 - t) * (this.getMax()));
state.setPromixity(v);
}
private getMin() {
return 0;
}
private getMax() {
return 100;
}
private getGradientDefinition(): LinearGradientDefinition {
return {
stops: [
{ offset: 0, color: '#626262' },
{ offset: 100, color: "#ddd" }
]
};
}
}
}

View File

@ -0,0 +1,10 @@
/// <reference path="./moduleView.ts" />
namespace pxsim.visuals {
export class InfraredView extends ModuleView implements LayoutElement {
constructor(port: number) {
super(INFRARED_SVG, "infrared", NodeType.InfraredSensor, port);
}
}
}

View File

@ -18,7 +18,7 @@ namespace pxsim.visuals {
return `id="${this.normalizeId(id)}"`;
});
xml = xml.replace(/url\(#(.*?)\)/g, (m: string, id: string) => {
return `url(#${this.normalizeId(id)}`;
return `url(#${this.normalizeId(id)})`;
});
xml = xml.replace(/xlink:href=\"#(.*?)\"/g, (m: string, id: string) => {
return `xlink:href="#${this.normalizeId(id)}"`;