├── .gitignore ├── examples ├── main.js ├── index.html └── basic │ └── index.html ├── index.js ├── src ├── matrix.js └── edit.js ├── tests ├── index.test.js ├── karma.conf.js ├── __init.test.js └── helpers.js ├── README.md ├── LICENSE └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log -------------------------------------------------------------------------------- /examples/main.js: -------------------------------------------------------------------------------- 1 | require('aframe'); 2 | require('../index.js'); 3 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('aframe-dev-components'); 2 | 3 | window.AFRAME = require('aframe'); 4 | 5 | AFRAME.registerComponent('matrix', require('./src/matrix')); 6 | AFRAME.registerComponent('edit', require('./src/edit')); 7 | -------------------------------------------------------------------------------- /src/matrix.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | schema: {type: 'array'}, 3 | 4 | update: function () { 5 | var object3D = this.el.object3D; 6 | var data = this.data; 7 | object3D.matrix.fromArray(data); 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /tests/index.test.js: -------------------------------------------------------------------------------- 1 | /* global assert, setup, suite, test */ 2 | require('aframe'); 3 | require('../index.js'); 4 | var entityFactory = require('./helpers').entityFactory; 5 | 6 | suite('dev component', function () { 7 | var component; 8 | var el; 9 | 10 | setup(function (done) { 11 | el = entityFactory(); 12 | el.addEventListener('componentinitialized', function (evt) { 13 | if (evt.detail.name !== 'dev') { return; } 14 | component = el.components['dev']; 15 | done(); 16 | }); 17 | el.setAttribute('dev', {}); 18 | }); 19 | 20 | suite('foo property', function () { 21 | test('is good', function () { 22 | assert.equal(1, 1); 23 | }); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /tests/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration. 2 | module.exports = function (config) { 3 | config.set({ 4 | basePath: '../', 5 | browserify: { 6 | debug: true, 7 | paths: ['./'] 8 | }, 9 | browsers: ['Firefox', 'Chrome'], 10 | client: { 11 | captureConsole: true, 12 | mocha: {ui: 'tdd'} 13 | }, 14 | envPreprocessor: ['TEST_ENV'], 15 | files: [ 16 | // Define test files. 17 | {pattern: 'tests/**/*.test.js'}, 18 | // Serve test assets. 19 | {pattern: 'tests/assets/**/*', included: false, served: true} 20 | ], 21 | frameworks: ['mocha', 'sinon-chai', 'chai-shallow-deep-equal', 'browserify'], 22 | preprocessors: {'tests/**/*.js': ['browserify', 'env']}, 23 | reporters: ['mocha'] 24 | }); 25 | }; 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## aframe-vreditor-component 2 | 3 | A VR editor for [A-Frame](https://aframe.io). 4 | 5 | ### Installation 6 | 7 | #### Browser 8 | 9 | Install and use by directly including the [browser files](dist): 10 | 11 | ```html 12 | 13 | My A-Frame Scene 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ``` 24 | 25 | ### Components 26 | 27 | #### edit 28 | 29 | Make children of any entity editable in VR. 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | ### npm 36 | 37 | Install via npm: 38 | 39 | ```bash 40 | npm install aframe-vreditor-component 41 | ``` 42 | 43 | Then require and use. 44 | 45 | ```js 46 | require('aframe'); 47 | require('aframe-vreditor-component'); 48 | ``` 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Casey Yee <caseyyee.ca@gmail.com> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /tests/__init.test.js: -------------------------------------------------------------------------------- 1 | /* global sinon, setup, teardown */ 2 | 3 | /** 4 | * __init.test.js is run before every test case. 5 | */ 6 | window.debug = true; 7 | var AScene = require('aframe').AScene 8 | 9 | navigator.getVRDisplays = function () { 10 | var resolvePromise = Promise.resolve(); 11 | var mockVRDisplay = { 12 | requestPresent: resolvePromise, 13 | exitPresent: resolvePromise, 14 | getPose: function () { return {orientation: null, position: null}; }, 15 | requestAnimationFrame: function () { return 1; } 16 | }; 17 | return Promise.resolve([mockVRDisplay]); 18 | }; 19 | 20 | setup(function () { 21 | this.sinon = sinon.sandbox.create(); 22 | // Stubs to not create a WebGL context since Travis CI runs headless. 23 | this.sinon.stub(AScene.prototype, 'render'); 24 | this.sinon.stub(AScene.prototype, 'resize'); 25 | this.sinon.stub(AScene.prototype, 'setupRenderer'); 26 | }); 27 | 28 | teardown(function () { 29 | // Clean up any attached elements. 30 | var attachedEls = ['canvas', 'a-assets', 'a-scene']; 31 | var els = document.querySelectorAll(attachedEls.join(',')); 32 | for (var i = 0; i < els.length; i++) { 33 | els[i].parentNode.removeChild(els[i]); 34 | } 35 | this.sinon.restore(); 36 | }); 37 | -------------------------------------------------------------------------------- /tests/helpers.js: -------------------------------------------------------------------------------- 1 | /* global suite */ 2 | 3 | /** 4 | * Helper method to create a scene, create an entity, add entity to scene, 5 | * add scene to document. 6 | * 7 | * @returns {object} An `` element. 8 | */ 9 | module.exports.entityFactory = function (opts) { 10 | var scene = document.createElement('a-scene'); 11 | var assets = document.createElement('a-assets'); 12 | var entity = document.createElement('a-entity'); 13 | scene.appendChild(assets); 14 | scene.appendChild(entity); 15 | 16 | opts = opts || {}; 17 | 18 | if (opts.assets) { 19 | opts.assets.forEach(function (asset) { 20 | assets.appendChild(asset); 21 | }); 22 | } 23 | 24 | document.body.appendChild(scene); 25 | return entity; 26 | }; 27 | 28 | /** 29 | * Creates and attaches a mixin element (and an `` element if necessary). 30 | * 31 | * @param {string} id - ID of mixin. 32 | * @param {object} obj - Map of component names to attribute values. 33 | * @param {Element} scene - Indicate which scene to apply mixin to if necessary. 34 | * @returns {object} An attached `` element. 35 | */ 36 | module.exports.mixinFactory = function (id, obj, scene) { 37 | var mixinEl = document.createElement('a-mixin'); 38 | mixinEl.setAttribute('id', id); 39 | Object.keys(obj).forEach(function (componentName) { 40 | mixinEl.setAttribute(componentName, obj[componentName]); 41 | }); 42 | 43 | var assetsEl = scene ? scene.querySelector('a-assets') : document.querySelector('a-assets'); 44 | assetsEl.appendChild(mixinEl); 45 | 46 | return mixinEl; 47 | }; 48 | 49 | /** 50 | * Test that is only run locally and is skipped on CI. 51 | */ 52 | module.exports.getSkipCISuite = function () { 53 | if (window.__env__.TEST_ENV === 'ci') { 54 | return suite.skip; 55 | } else { 56 | return suite; 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A-Frame VR Editor Component 4 | 5 | 22 | 23 | 24 |

A-Frame VR Editor component

25 | Basic 26 |

This is a basic example.

27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aframe-vreditor-component", 3 | "version": "1.0.0", 4 | "description": "VR Editor for A-Frame.", 5 | "main": "index.js", 6 | "cdn": "dist/aframe-vreditor-component.min.js", 7 | "scripts": { 8 | "build": "browserify examples/main.js -o examples/build.js", 9 | "dev": "budo examples/main.js:build.js --dir examples --port 8000 --live --open", 10 | "dist": "webpack index.js dist/aframe-vreditor-component.js && webpack -p index.js dist/aframe-vreditor-component.min.js", 11 | "lint": "semistandard -v | snazzy", 12 | "prepublish": "npm run dist", 13 | "preghpages": "npm run build && shx rm -rf gh-pages && shx mkdir gh-pages && shx cp -r examples/* gh-pages", 14 | "ghpages": "npm run preghpages && ghpages -p gh-pages", 15 | "start": "npm run dev", 16 | "test": "karma start ./tests/karma.conf.js", 17 | "test:firefox": "karma start ./tests/karma.conf.js --browsers Firefox", 18 | "test:chrome": "karma start ./tests/karma.conf.js --browsers Chrome" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/caseyyee/aframe-vreditor-component.git" 23 | }, 24 | "keywords": [ 25 | "aframe", 26 | "aframe-component", 27 | "aframe-vr", 28 | "vr", 29 | "mozvr", 30 | "webvr", 31 | "dev" 32 | ], 33 | "author": "Casey Yee ", 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/caseyyee/aframe-vreditor-component/issues" 37 | }, 38 | "homepage": "https://github.com/caseyyee/aframe-vreditor-component#readme", 39 | "devDependencies": { 40 | "aframe": "^0.5.0", 41 | "browserify": "^13.0.0", 42 | "budo": "^8.2.2", 43 | "chai": "^3.4.1", 44 | "chai-shallow-deep-equal": "^1.3.0", 45 | "ghpages": "^0.0.8", 46 | "karma": "^0.13.15", 47 | "karma-browserify": "^4.4.2", 48 | "karma-chai-shallow-deep-equal": "0.0.4", 49 | "karma-chrome-launcher": "2.0.0", 50 | "karma-env-preprocessor": "^0.1.1", 51 | "karma-firefox-launcher": "^0.1.7", 52 | "karma-mocha": "^0.2.1", 53 | "karma-mocha-reporter": "^1.1.3", 54 | "karma-sinon-chai": "^1.1.0", 55 | "mocha": "^2.3.4", 56 | "randomcolor": "^0.4.4", 57 | "semistandard": "^8.0.0", 58 | "shelljs": "^0.7.0", 59 | "sinon": "^1.17.5", 60 | "sinon-chai": "^2.8.0", 61 | "shx": "^0.1.1", 62 | "snazzy": "^4.0.0", 63 | "webpack": "^1.13.0" 64 | }, 65 | "semistandard": { 66 | "ignore": [ 67 | "examples/build.js", 68 | "dist/**" 69 | ] 70 | }, 71 | "dependencies": { 72 | "aframe-dev-components": "git://github.com/caseyyee/aframe-dev-components.git" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /examples/basic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A-Frame A-Frame developer tools Component - Basic 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |