├── README.md ├── aframe-persist-component.js ├── index.html └── preview.gif /README.md: -------------------------------------------------------------------------------- 1 | # aframe-persist-component 2 | Use localStorage to make data persist over experiences. 3 | 4 | Tro try the example http://vatelier.net/MyDemo/aframe-persist-component/ move the camera around then refresh. You can also move the cube around using the inspector. 5 | 6 | ![preview](https://utopiah.github.io/aframe-persist-component/preview.gif) 7 | 8 | ## Properties 9 | 10 | | Property | Description | Default Value | 11 | | -------- | -------------------------------------------------------------------- | ------------- | 12 | |attribute | specify which attributes of an entity should be saved | position | 13 | |debug | console.log() when attributes are loaded, saved and with what values | true | 14 | 15 | ## Installation 16 | 17 | ### Browser 18 | 19 | Install and use by directly including the component: 20 | ```html 21 | 22 | ``` 23 | ## Basic usage 24 | ```html 25 | 26 | 27 | 28 | ``` 29 | ## Example 30 | ```html 31 | 32 | local state save 33 | 34 | 35 | 36 | 37 | 38 | 40 | 43 | 46 | 47 | 48 | 49 | ``` 50 | 51 | ## Limitations 52 | - There is no traversal, each attribute to be saved has to be explicitely defined as such. 53 | - Each entity *requires* to have its unique ID, if not a warning message will de displayed then nothing will be saved. 54 | - Simple attributes like visible work but composed attributes (e.g. color or material) do not work. 55 | -------------------------------------------------------------------------------- /aframe-persist-component.js: -------------------------------------------------------------------------------- 1 | AFRAME.registerSystem('persist', { 2 | schema: { 3 | savekey: { 4 | type: 'int', 5 | default: 0 // 13 = enter, cf https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Value_of_keyCode 6 | }, 7 | }, 8 | init: function () { 9 | this.entities = []; 10 | window.addEventListener("unload", saveAll); 11 | 12 | if (this.data.savekey) document.addEventListener("keydown", keyDown, false); 13 | var entities = this.entities; 14 | var savekey = this.data.savekey; 15 | 16 | function saveAll(){ 17 | for (var i = 0; i < entities.length; i++) { 18 | document.getElementById(entities[i].id).components[entities[i].attrName].saveValue(); 19 | } 20 | } 21 | 22 | function forgetAll(){ 23 | for (var i = 0; i < entities.length; i++) { 24 | document.getElementById(entities[i].id).components[entities[i].attrName].forgetValue(); 25 | } 26 | } 27 | 28 | function keyDown(e) { 29 | var keyCode = e.keyCode; 30 | if(keyCode==savekey) { 31 | console.log("Manual save"); 32 | saveAll(); 33 | } 34 | } 35 | 36 | }, 37 | registerMe: function (el) { 38 | this.entities.push(el); 39 | } 40 | }); 41 | 42 | 43 | AFRAME.registerComponent('persist', { 44 | multiple: true, 45 | // arguably could have been better to accept a list of attributes to save 46 | schema: { 47 | attribute: { 48 | type: 'string', 49 | default: 'position' 50 | }, 51 | debug: { 52 | type: 'boolean', 53 | default: false 54 | } 55 | }, 56 | 57 | init: function () { 58 | if (!this.el.id){ 59 | console.log("error", this.attrName, "requires an element id on your entity"); 60 | return; 61 | } 62 | this.data.storageName = this.attrName+'_'+this.el.id+'_'+this.data.attribute; 63 | this.loadValue(); 64 | if (this.data.debug) console.log(this.data.storageName); 65 | this.system.registerMe({attrName: this.attrName, id: this.el.id}) 66 | }, 67 | 68 | loadValue: function(){ 69 | let savedValue = localStorage.getItem(this.data.storageName); 70 | if (savedValue){ 71 | if (this.data.debug) console.log('Previous value of', this.data.attribute, 'for', savedValue, 72 | 'saved from', this.data.storageName, ', using it'); 73 | this.el.setAttribute(this.data.attribute, savedValue); 74 | } 75 | }, 76 | 77 | saveValue: function(){ 78 | let attributeValue = this.el.getAttribute(this.data.attribute); 79 | if ((this.data.attribute == "position") || (this.data.attribute == "rotation")) 80 | localStorage.setItem(this.data.storageName, AFRAME.utils.coordinates.stringify(attributeValue)); 81 | else 82 | localStorage.setItem(this.data.storageName, attributeValue); 83 | 84 | if (this.data.debug) console.log(this.data.storageName, 'saved', this.data.attribute, 'of value', attributeValue); 85 | }, 86 | 87 | forgetValue: function(){ 88 | if (this.data.debug) console.log(this.data.storageName, 'deleted'); 89 | localStorage.removeItem(this.data.storageName); 90 | } 91 | 92 | }); 93 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | local state save 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Utopiah/aframe-persist-component/7fd7ababa5ec9f378a1064dc40f674e55b765a9a/preview.gif --------------------------------------------------------------------------------