diff --git a/README.md b/README.md index ff37e0a9..4e531cf9 100644 --- a/README.md +++ b/README.md @@ -9,16 +9,11 @@ The Engaging Computing Group develops new technologies to enable learners—yout ## Status [![CircleCI](https://circleci.com/gh/engaging-computing/MYR.svg?style=shield)](https://circleci.com/gh/engaging-computing/MYR) -## Change Log - 2.2.0 -> 2.3.0 -- Adds Minecraft style flying controls - - Removes flying setting toggle -- Updates default scene to show helper grid by default -- MYR provided textures are now case insensitive -- Textures can be tiled -- Fixes black flickering bug when entering VR mode on mobile -- Spelling fixes -- Updated AFrame to use v1.x.y - +## Change Log - 2.3.0 -> 2.3.1 +- Updated VR/AR buttons to be spaced out +- Fixed bug where colorshift would always choose white for it's initial color +- Updated autocompelete to put cursor in between parenthesis instead of after +- Fixed a bug where a pushable entity would not be able to be pushed (`makePushable`) ## Acknowledgments diff --git a/package.json b/package.json index 9e95f806..3b33e7f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "myr", - "version": "2.3.0", + "version": "2.3.1", "private": false, "engines": { "node": "12.18.2" diff --git a/src/components/editor/customCompleter.js b/src/components/editor/customCompleter.js index 44f0a381..438ad20f 100644 --- a/src/components/editor/customCompleter.js +++ b/src/components/editor/customCompleter.js @@ -213,7 +213,14 @@ export const customCompleter = { caption: word, value: word, meta: "MYR", - score: 2 + score: 2, + completer:{ + insertMatch: function(editor,data){ + editor.completer.insertMatch({value:data.value}); + let pos = editor.selection.getCursor(); + editor.gotoLine(pos.row+1,pos.column-1); + } + } }; })); diff --git a/src/components/structural/View.js b/src/components/structural/View.js index f14ea02b..9f47bbbf 100644 --- a/src/components/structural/View.js +++ b/src/components/structural/View.js @@ -139,7 +139,7 @@ class View extends Component { if (ent.tube) { return ; } - return ; + return ; } } //return elements that contains necessary configuration for light indicator based on light's type and properties diff --git a/src/css/App.css b/src/css/App.css index cf31d21b..4c4e7025 100644 --- a/src/css/App.css +++ b/src/css/App.css @@ -320,11 +320,20 @@ div#reference-drawer>div { margin-right: 10px; } -/************************************ -********THIS IS THE VR BUTTON******** -************************************/ +/* Overwrites default A-Frame behavior for embedded + * buttons to behave as if scene was located within + * an iframe */ .a-enter-vr { - position: "relative"; + position: absolute; + bottom:20px !important; + right:20px !important; + z-index: 1 !important; +} + +.a-enter-ar { + position: absolute; + bottom:20px !important; + right:80px !important; z-index: 1 !important; } diff --git a/src/myr/Myr.js b/src/myr/Myr.js index 8b231cf6..8b6daa47 100644 --- a/src/myr/Myr.js +++ b/src/myr/Myr.js @@ -1775,23 +1775,21 @@ class Myr { //if the element is light if(String(el.id).includes("lgt")){ let split = el.light.state.split(/\s|;/).filter(Boolean); - let colorIndex = split.indexOf("color:"); - let baseCol = split[colorIndex+1]; + let colorIndex = split.indexOf("color:")+1; + let baseCol = split[colorIndex]; if(this.colourNameToHex(baseCol)!==false){ baseCol = this.colourNameToHex(baseCol); } if(this.colourNameToHex(color) !== false){ color = this.colourNameToHex(color); } - let anim = ` - property: light.color; + let anim = `property: light.color; from: ${baseCol}; to: ${color}; dur: ${this.cursor.duration}; dir: alternate; loop: ${Boolean(this.cursor.loop)}; - type: color; - `; + type: color;`; el.animation__color = anim; return outerElId; } @@ -1801,31 +1799,29 @@ class Myr { let innerEl = el.els[i]; //innerEl.material.split(/\s|;/) returns an array of strings separated by " " and ";", //color is always its first attribute (after "color: ") - let anim = ` - property: components.material.material.color; - from: ${(innerEl.material.split(/\s|;/))[1]}; - to: ${color}; - dur: ${this.cursor.duration}; - dir: alternate; - loop: ${Boolean(this.cursor.loop)}; - isRawProperty: true; - type: color; - `; + let anim = `property: components.material.material.color; + from: ${(innerEl.material.split(/\s|;/))[1]}; + to: ${color}; + dur: ${this.cursor.duration}; + dir: alternate; + loop: ${Boolean(this.cursor.loop)}; + isRawProperty: true; + type: color;`; innerEl.animation__color = anim; } return outerElId; } - let anim = ` - property: components.material.material.color; - from: ${(el.material.split(/\s|;/))[2]}; - to: ${color}; - dur: ${this.cursor.duration}; - dir: alternate; - loop: ${Boolean(this.cursor.loop)}; - isRawProperty: true; - type: color; - `; + + const mat = el.material.split(/\s|;/); + let anim = `property: components.material.material.color; + from: ${mat[mat.indexOf("color:")+1]}; + to: ${color}; + dur: ${this.cursor.duration}; + dir: alternate; + loop: ${Boolean(this.cursor.loop)}; + isRawProperty: true; + type: color;`; el.animation__color = anim; return outerElId; } diff --git a/src/tests/Myr.test.js b/src/tests/Myr.test.js index d9f7378a..030f075d 100644 --- a/src/tests/Myr.test.js +++ b/src/tests/Myr.test.js @@ -389,8 +389,119 @@ describe("Component Renders", () => { }); }); +describe("MYR light functionality", () => { + it("ambientLight", ()=>{ + myr.reset(); + myr.els = []; + let id = myr.ambientLight({position: {x:1,y:1,z:1}}); + let ambientLight = myr.els[id]; + expect(ambientLight).toBeDefined(); + expect(ambientLight.light.state).toEqual(` + type: ambient; + color: red; + intensity: 1;`); + expect(ambientLight.position).toEqual({x:1,y:1,z:1}); + //light's scale sohuld not change + expect(ambientLight.scale).toEqual({x:1,y:1,z:1}); + }); + + it("directionalLight", ()=>{ + myr.els = []; + let id = myr.directionalLight({position: {x:1,y:1,z:1}}); + let directionalLight = myr.els[id]; + expect(directionalLight).toBeDefined(); + expect(directionalLight.light.state).toEqual(` + type: directional; + color: red; + intensity: 1;`); + expect(directionalLight.position).toEqual({x:1,y:1,z:1}); + expect(directionalLight.scale).toEqual({x:1,y:1,z:1}); + }); + + it("spotLight", ()=>{ + myr.els = []; + let id = myr.spotLight({position: {x:1,y:1,z:1}}); + let spotLight = myr.els[id]; + expect(spotLight).toBeDefined(); + expect(spotLight.light.state).toEqual(` + type: spot; + angle: 60; + decay: 1; + distance: 0; + intensity: 1; + penumbra: 0; + color: red;`); + expect(spotLight.position).toEqual({x:1,y:1,z:1}); + //light's scale sohuld not change + expect(spotLight.scale).toEqual({x:1,y:1,z:1}); + }); + + it("pointLight", ()=>{ + myr.els = []; + let id = myr.pointLight({position: {x:1,y:1,z:1}}); + let pointLight = myr.els[id]; + expect(pointLight).toBeDefined(); + expect(pointLight.light.state).toEqual(` + type: point; + angle: 60; + decay: 1; + distance: 0; + intensity: 1; + penumbra: 0; + color: red;`); + expect(pointLight.position).toEqual({x:1,y:1,z:1}); + //light's scale should not change + expect(pointLight.scale).toEqual({x:1,y:1,z:1}); + }); + + it("hemisphereLight", ()=>{ + myr.els = []; + let id = myr.hemisphereLight("blue",{position: {x:1,y:1,z:1}}); + let hemisphereLight = myr.els[id]; + expect(hemisphereLight).toBeDefined(); + expect(hemisphereLight.light.state).toEqual(` + type: hemisphere; + intensity: 1; + color: red; + groundColor: blue;`); + expect(hemisphereLight.position).toEqual({x:1,y:1,z:1}); + //light's scale should not change + expect(hemisphereLight.scale).toEqual({x:1,y:1,z:1}); + }); + + it("to Set Intensity", () => { + myr.setIntensity(5); + expect(myr.cursor.light.intensity).toEqual(5); + }); + + it("to Set BeamAngle", () => { + myr.setBeamAngle(30); + expect(myr.cursor.light.beamAngle).toEqual(30); + }); + + it("to Set Diffusion", () => { + myr.setDiffusion(1.25); + expect(myr.cursor.light.diffusion).toEqual(1.25); + }); + + it("to Set decay", () => { + myr.setDecay(1.87); + expect(myr.cursor.light.decay).toEqual(1.87); + }); + + it("to Set Distance", () => { + myr.setDistance(50); + expect(myr.cursor.light.distance).toEqual(50); + }); + + it("to Set Light Target", () => { + myr.setLightTarget(4,5,10); + expect(myr.cursor.light.target).toEqual({x:4, y: 5, z: 10}); + }); +}); + describe("Component Animations", () => { - it("Should add the animate animation", () => { + it("should add the animate animation", () => { myr.reset(); let bId = myr.box(); myr.animate(bId); @@ -412,7 +523,7 @@ describe("Component Animations", () => { `); }); - it("Should add the spin animation", () => { + it("should add the spin animation", () => { myr.reset(); let bId = myr.box(); myr.spin(bId); @@ -568,129 +679,69 @@ describe("Component Animations", () => { expect(el).toHaveProperty("animation__shrink"); }); - -}); - -describe("MYR light functionality", () => { - it("ambientLight", ()=>{ + it("should add the color_shift animation",()=>{ myr.reset(); - myr.els = []; - let id = myr.ambientLight({position: {x:1,y:1,z:1}}); - let ambientLight = myr.els[id]; - expect(ambientLight).toBeDefined(); - expect(ambientLight.light.state).toEqual(` - type: ambient; - color: red; - intensity: 1;`); - expect(ambientLight.position).toEqual({x:1,y:1,z:1}); - //light's scale sohuld not change - expect(ambientLight.scale).toEqual({x:1,y:1,z:1}); - }); - - it("directionalLight", ()=>{ - myr.els = []; - let id = myr.directionalLight({position: {x:1,y:1,z:1}}); - let directionalLight = myr.els[id]; - expect(directionalLight).toBeDefined(); - expect(directionalLight.light.state).toEqual(` - type: directional; - color: red; - intensity: 1;`); - expect(directionalLight.position).toEqual({x:1,y:1,z:1}); - expect(directionalLight.scale).toEqual({x:1,y:1,z:1}); - }); - - it("spotLight", ()=>{ - myr.els = []; - let id = myr.spotLight({position: {x:1,y:1,z:1}}); - let spotLight = myr.els[id]; - expect(spotLight).toBeDefined(); - expect(spotLight.light.state).toEqual(` - type: spot; - angle: 60; - decay: 1; - distance: 0; - intensity: 1; - penumbra: 0; - color: red;`); - expect(spotLight.position).toEqual({x:1,y:1,z:1}); - //light's scale sohuld not change - expect(spotLight.scale).toEqual({x:1,y:1,z:1}); - }); - - it("pointLight", ()=>{ - myr.els = []; - let id = myr.pointLight({position: {x:1,y:1,z:1}}); - let pointLight = myr.els[id]; - expect(pointLight).toBeDefined(); - expect(pointLight.light.state).toEqual(` - type: point; - angle: 60; - decay: 1; - distance: 0; - intensity: 1; - penumbra: 0; - color: red;`); - expect(pointLight.position).toEqual({x:1,y:1,z:1}); - //light's scale should not change - expect(pointLight.scale).toEqual({x:1,y:1,z:1}); - }); - - it("hemisphereLight", ()=>{ - myr.els = []; - let id = myr.hemisphereLight("blue",{position: {x:1,y:1,z:1}}); - let hemisphereLight = myr.els[id]; - expect(hemisphereLight).toBeDefined(); - expect(hemisphereLight.light.state).toEqual(` - type: hemisphere; - intensity: 1; - color: red; - groundColor: blue;`); - expect(hemisphereLight.position).toEqual({x:1,y:1,z:1}); - //light's scale should not change - expect(hemisphereLight.scale).toEqual({x:1,y:1,z:1}); - }); - - it("to Set Intensity", () => { - myr.setIntensity(5); - expect(myr.cursor.light.intensity).toEqual(5); - }); - - it("to Set BeamAngle", () => { - myr.setBeamAngle(30); - expect(myr.cursor.light.beamAngle).toEqual(30); - }); + let id = myr.box(); + myr.colorShift(id,"blue"); + let el = myr.getEl(id); + expect(el).toHaveProperty("animation__color"); - it("to Set Diffusion", () => { - myr.setDiffusion(1.25); - expect(myr.cursor.light.diffusion).toEqual(1.25); + expect(el.animation__color).toEqual(`property: components.material.material.color; + from: ${defaultCursor.color}; + to: blue; + dur: ${defaultCursor.duration}; + dir: alternate; + loop: ${defaultCursor.loop}; + isRawProperty: true; + type: color;`); }); - it("to Set decay", () => { - myr.setDecay(1.87); - expect(myr.cursor.light.decay).toEqual(1.87); - }); - - it("to Set Distance", () => { - myr.setDistance(50); - expect(myr.cursor.light.distance).toEqual(50); + it("should add the color_shift animation to the light",()=>{ + myr.reset(); + let id = myr.directionalLight(); + myr.colorShift(id,"green"); + let el = myr.getEl(id); + expect(el).toHaveProperty("animation__color"); + expect(el.animation__color).toEqual(`property: light.color; + from: #ff0000; + to: #008000; + dur: ${defaultCursor.duration}; + dir: alternate; + loop: ${defaultCursor.loop}; + type: color;`); }); - it("to Set Light Target", () => { - myr.setLightTarget(4,5,10); - expect(myr.cursor.light.target).toEqual({x:4, y: 5, z: 10}); + it("should add the color_shift animation to the group",()=>{ + myr.reset(); + let id = myr.group(); + id.add(myr.box()); + id.add(myr.box()); + id.add(myr.box()); + myr.colorShift(id,"purple"); + let el = myr.getEl(id); + el.els.forEach(e=>{ + expect(e).toHaveProperty("animation__color"); + expect(e.animation__color).toEqual(`property: components.material.material.color; + from: ${defaultCursor.color}; + to: purple; + dur: ${defaultCursor.duration}; + dir: alternate; + loop: ${Boolean(defaultCursor.loop)}; + isRawProperty: true; + type: color;`); + }); }); }); describe("Other Myr functionality", () => { - it("Should add a model", () => { + it("should add a model", () => { myr.reset(); myr.assets = []; myr.addCModel(); expect(myr.assets).toContainEqual({ id: "c-obj", src: "/img/c.obj" }); }); - it("Should drop", () => { + it("should drop", () => { myr.reset(); let el = myr.box({ material: "color: blue;", position: { x: 1, y: 1, z: 1 } }); myr.drop(el); @@ -1082,7 +1133,7 @@ describe("Other Myr functionality", () => { expect(response).toEqual({ "test1": 1, "test2": 3 }); }); - it("Should accept hex colors entered for setColor function", () => { + it("should accept hex colors entered for setColor function", () => { myr.setColor("#ff0000"); expect(myr.cursor.color).toEqual("#ff0000"); myr.setColor("#FF0000"); @@ -1094,7 +1145,7 @@ describe("Other Myr functionality", () => { }); // This is will test different variations of color - it("Should accept any caps or lowercase letters", () => { + it("should accept any caps or lowercase letters", () => { myr.setColor("Blue"); expect(myr.cursor.color).toEqual("blue"); myr.setColor("pURPle"); diff --git a/src/utils/AFramePhysics.js b/src/utils/AFramePhysics.js index 5172cb3a..d9bb8782 100644 --- a/src/utils/AFramePhysics.js +++ b/src/utils/AFramePhysics.js @@ -3,7 +3,10 @@ const THREE = AFRAME.THREE; AFRAME.registerComponent("force-pushable", { schema: { - force: { default: 10 } + force: { + type: "number", + default: 10 + } }, init: function () { this.pStart = new THREE.Vector3(); @@ -13,12 +16,11 @@ AFRAME.registerComponent("force-pushable", { forcePush: function () { let force, el = this.el, - pStart = this.pStart.copy(this.sourceEl.getAttribute("position")); - + pStart = this.pStart.copy(this.sourceEl.children[0].getAttribute("position")); // Compute direction of force, normalize, then scale. force = el.body.position.vsub(pStart); force.normalize(); - force.scale(this.data.force, force); + force.scale(this.nextData.force, force); el.body.applyImpulse(force, el.body.position); }