Passing texture map from user input to A-Frame Component - aframe

Got this thing working already with THREE.js and now want to add the same functionality to my A-Frame component. I have an user image input dialog and the below script runs when the image changes. The question is how do I pass this data through the component? Schema seems to modify the data somehow since the console.log output from inside the document versus component is different!
In HTML document:
n {uuid: "6682DFA3-78C6-4BC6-9C5C-C2430A046D73", name: "", sourceFile: "", image: img, mipmaps: Array[0]…
Inside the component:
String {0: "e", 1: "m", 2: "p", 3: "t", 4: "y", 5: "T", 6: "e", 7: "x", 8: "t", 9: "u", 10: "r", 11: "e", uuid: "6682DFA3-78C6-4BC6-9C5C-C2430A046D73", name: "", sourceFile: "", image: img, mipmaps: Array[0]…
$("#userImage").change(function () {
var image = document.createElement( 'img' );
var texture = new THREE.Texture( image );
image.onload = function() {
texture.needsUpdate = true;
// Helper is entity which has component with the shader
helper.setAttribute('myComponent', {
texture: texture
});
};
userImage = $("#userImage")[0];
if (userImage.files && userImage.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
image.src = e.target.result;
};
reader.readAsDataURL(userImage.files[0]);
}
});
var texture above returns similar data as var texture below.
var loader = new THREE.TextureLoader(manager);
var texture = loader.load( 'img/image.jpg' );

If you wish to pass just a big object, you can modify the schema to take JSON.
js
AFRAME.registerComponent('foo', {
schema: {
parse: JSON.parse
}
});
Then you can pass in as JSON. Or if you do .setAttribute, A-Frame won't do parsing (.setAttribute('foo', {yourData})).

Related

Here maps :load multiples KML files on differents map on same page and enable events on each

On the same page, i have differents maps loaded with Here maps API for each map i have loaded a specific kml file.
When i try to click, it works only on the last kml loaded and not others one, so how to make working event on each map ? This my code, it's taken from the example but a little bit modified :
function renderSchoenefeldAirport(map, ui, renderControls, kmlfile) {
// Create a reader object, that will load data from a KML file
var reader = new H.data.kml.Reader(kmlfile);
// Request document parsing. Parsing is an asynchronous operation.
reader.parse();
reader.addEventListener('statechange', function () {
// Wait till the KML document is fully loaded and parsed
if (this.getState() === H.data.AbstractReader.State.READY) {
var parsedObjects = reader.getParsedObjects();
// Create a group from our objects to easily zoom to them
var container = new H.map.Group({objects: parsedObjects});
// So let's zoom to them by default
map.setViewBounds(parsedObjects[0].getBounds());
// Let's make kml ballon visible by tap on its owner
// Notice how we are using event delegation for it
container.addEventListener('tap', function (evt) {
var target = evt.target, position;
// We need to calculated a position for our baloon
if (target instanceof H.map.Polygon || target instanceof H.map.Polyline) {
position = target.getBounds().getCenter();
} else if (target instanceof H.map.Marker) {
position = target.getPosition();
}
if (position) {
// Let's use out custom (non-api) function for displaying a baloon
showKMLBallon(position, target.getData(), ui);
}
});
// Make objects visible by adding them to the map
map.addObject(container);
}
});
}
/**
* Boilerplate map initialization code starts below:
*/
// Step 1: initialize communication with the platform
var platform = new H.service.Platform({
'app_id': 'myappid',
'app_code': 'myappcode',
useHTTPS: true
});
var pixelRatio = window.devicePixelRatio || 1;
var defaultLayers = platform.createDefaultLayers({
tileSize: pixelRatio === 1 ? 256 : 512,
ppi: pixelRatio === 1 ? undefined : 320
});
// Step 2: initialize a map
// Please note, that default layer is set to satellite mode
var map = new H.Map(document.getElementById('mapcontainer1'), defaultLayers.satellite.map, {
zoom: 1,
pixelRatio: pixelRatio
});
var map_secondary = new H.Map(document.getElementById('mapcontainer2'), defaultLayers.satellite.map, {
zoom: 1,
pixelRatio: pixelRatio
});
// Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
var behavior_secondary = new H.mapevents.Behavior(new H.mapevents.MapEvents(map_secondary));
// Template function for our controls
function renderControls(buttons) {
var containerNode = document.createElement('div');
containerNode.setAttribute('style', 'position:absolute;top:0;left:0;background-color:#fff; padding:10px;');
containerNode.className = "btn-group";
Object.keys(buttons).forEach(function (label) {
var input = document.createElement('input');
input.value = label;
input.type = 'button';
input.onclick = buttons[label];
input.className="btn btn-sm btn-default"
containerNode.appendChild(input);
});
map.getElement().appendChild(containerNode);
}
function showKMLBallon(position, data, ui) {
var content = data.balloonStyle.text;
if (content) {
// Styling of the balloon text.
// The only supported wilde cards are $[text] and $[description].
content = content
.replace('$[name]', data.name || '')
.replace('$[description]', data.description || '');
// Note how we are caching our infoBubble instance
// We create InfoBubble object only once and then reuse it
var bubble = showKMLBallon.infoBubble;
if (!bubble) {
bubble = new H.ui.InfoBubble(position, {content: content});
ui.addBubble(bubble);
bubble.getContentElement().style.marginRight = "-24px";
// Cache our instance for future use
showKMLBallon.infoBubble = bubble;
} else {
bubble.setPosition(position);
bubble.setContent(content);
bubble.open();
}
}
}
// Step 4: create the default UI component, for displaying bubbles
var ui = H.ui.UI.createDefault(map, defaultLayers);
var ui_secondary = H.ui.UI.createDefault(map_secondary, defaultLayers);
// Step 5: main logic goes here
renderSchoenefeldAirport(map, ui, renderControls, 'path/to/file1.kml');
renderSchoenefeldAirport(map_secondary, ui_secondary, renderControls, 'path/to/file2.kml');
Thanks by advance
In the provided snippet there is a line 106: var bubble = showKMLBallon.infoBubble; where the info bubble is "cached", the problem is that when the user clicks on one of the maps the infobubble is created and cached, and when somebody clicks on the second map the the info bubble from the first is used.
In the simplest case this line should be:
var bubble = ui.infoBubble;
so the bubble for each map instance in cached. In general, depending on the desired outcome, the proper caching strategy should be devised.
Hope this helps.

Compress .xls/xlsx files into .zip files jsZip

I'm a newbie to the field of javascript/angularJS, so please bear with me.I need a way to convert .xls/.xlsx files into .zip files by using jsZip library. I'm making use of alasql for generating the .xls file. I've looked all over for any possible solutions to create zip file of all xls files, but haven't come across any demo. (.txt and .doc files generate just fine, but .xls files does not open if jsZip is used). Any help would be appreciated!!
What I need is an xls file to be generated dynamically, and the same file to be compressed as zip
EDIT :-
Here's some of the code which I tried (but with no success)
var newExcelData = {'Name':'abc'};
//var res = alasql("SELECT * INTO XLSX('Summary.xlsx',{headers:true}) FROM ? ", [newExcelData]);
var zip = new JSZip();
zip.file(alasql("SELECT * INTO XLSX('Summary.xlsx',{headers:true}) FROM ? ", [newExcelData]));
zip.generateAsync({ type: "blob" })
.then(function (content) {
saveAs(content, "example.zip");
});
PS:- I'm able to make it work in case of generating .xls file.
Please refer below code:-
var newExcelData = {'Name':'abc', 'Age':'12'};
var zip = new JSZip();
zip.file("test.xls", [newExcelData]);
zip.generateAsync({ type: "blob" })
.then(function (content) {
saveAs(content, "example.zip");
});
But although excel sheet is generated, on opening excel sheet is blank.
Please help!!
Hi, here's an update :-
I've tried to make use of js-xlsx library - https://github.com/SheetJS/js-xlsx - to generate xls file and then zip it. Please refer the below code..
function Create_Zip() {
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = { v: data[R][C] };
if (cell.v === null) continue;
var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n'; cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
var data = [[1, 2, 3], [true, false, null, "sheetjs"], ["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"], ["baz", null, "qux"]];
var ws_name = "SheetJS";
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'binary' });
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
var jsonse = JSON.stringify([s2ab(wbout)]);
var testblob = new Blob([jsonse], { type: "application/json" });
console.log(testblob);
var zip = new JSZip();
zip.file("trial.xls", testblob);
var downloadFile = zip.generateAsync({ type: "blob" });
saveAs(downloadFile, 'test.zip');
}
But, the problem here is that I keep getting this error: 'The data of 'trial.xls' is in an unsupported format !' in the console :(. Is there any way I can make this work?
I'm at my wits end now :(
Not an answer (see below) but an explanation of what's going on:
To add a file, JSZip needs its binary content (as Blob, Uint8Array, etc). The line zip.file("test.xls", [newExcelData]); can't work for example: [newExcelData] is not a binary content but an array of js object.
What you need to figure out is how to get the content of the xlsx file. SELECT * INTO XLSX('Summary.xlsx') will trigger a download and return 1, it's not what you want. I searched on my side but can't find a way to do it with alasql.
Once/if you find the solution, the JSZip part looks correct.
Edit, following your switch to js-xlsx:
You use JSZip v2 (needed by js-xlsx) which doesn't support Blob inputs. However, wbout is a binary string which is supported:
zip.file("trial.xls", wbout, {binary: true});
Then, replace zip.generateAsync (added in JSZip v3):
var downloadFile = zip.generate({type: "blob" });
saveAs(downloadFile, 'test.zip');
Here is the solution I found using JSZip, XLSX and File Saver libraries.
Import:
import * as XLSX from "xlsx";
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
Here is an example of compressing a .xlsx inside a zip:
let zip = new JSZip();
const jsonData = [
{
"Product": "Red Velvet Cupcake",
"Price": "6",
"GluttenFree": "Yes",
},
{
"Product": "Cheesecake",
"Price": "15",
"GluttenFree": "No",
}
];
const workBook: XLSX.WorkBook = XLSX.utils.book_new();
const workSheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(jsonData);
XLSX.utils.book_append_sheet(workBook, workSheet, 'Bakery');
const workBookBuffer = XLSX.write(workBook, { bookType: 'xlsx', type: 'array' });
const fileData = new Blob([workBookBuffer], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'});
zip.file('Products.xlsx', fileData);
zip.generateAsync({type:"blob"}).then(function (blob) {
saveAs(blob, "WorkBooks.zip");
});
This code generates a zip file named 'WorkBooks.zip' that contains the file 'Products.xlsx'. This is how the excel looks like:
Some file-saver examples: https://www.tabnine.com/code/javascript/modules/file-saver.
Here is the JSZip method used:
https://stuk.github.io/jszip/documentation/api_jszip/file_data.html

ydn-db: how to make any query more complex than getting a single record by id?

Using the packaged ydn-db library from here: http://git.yathit.com/ydn-db/downloads/ydn.db-jquery-0.7.12.js . Same happens with https://storage.cloud.google.com/download.yathit.com/ydn-db/build/zsk-ydn.db-dev-0.7.15.js .
var db = new ydn.db.Storage("mydb");
var clog = function(r) { console.log(r); }
db.put({name: "store1", keyPath: "id"}, {id: "id1", value: "value1"});
db.put({name: "store1", keyPath: "id"}, {id: "id2", value: "value2"});
db.get("store1", "id1").done(clog); // works fine
// Example as mentioned in the docs here: http://dev.yathit.com/ydn-db/getting-started.html
var reverse = false, limit = 10;
db.values(new ydn.db.Cursors("store1", "id", null, reverse), limit).done(clog)
// TypeError: Cannot call method 'getName' of null
// Also adapted from docs:
db.values(ydn.db.IndexValueCursors.where("store1", "id", "=", "id1")).done(clog)
// TypeError: Cannot call method 'getName' of null
// Also adapted from docs:
var iter = new ydn.db.ValueCursors("store1", ydn.db.KeyRange.starts("a"))
db.open(iter, clog, "readwrite")
// ydn.error.ArgumentException: Second argument must be cursor range iterator.
The functionality of the packaged library just doesn't seem to align with the docs. Any tips?
Actually, your schema don't have index name id, so the correct code should be as follow.
var db = new ydn.db.Storage("mydb");
var clog = function(r) { console.log(r); }
db.put({name: "store1", keyPath: "id"}, {id: "id1", value: "value1"});
db.put({name: "store1", keyPath: "id"}, {id: "id2", value: "value2"});
db.get("store1", "id1").done(clog); // works fine
// Example as mentioned in the docs here: http://dev.yathit.com/ydn-db/getting-started.html
var reverse = false, limit = 10;
db.values(new ydn.db.KeyCursors("store1", null, reverse), limit).done(clog)
// TypeError: Cannot call method 'getName' of null
// Also adapted from docs:
db.values(ydn.db.ValueCursors.where("store1", "=", "id1")).done(clog)
// TypeError: Cannot call method 'getName' of null
// Also adapted from docs:
var iter = new ydn.db.ValueCursors("store1", ydn.db.KeyRange.starts("i"))
var pnt = function(r) {console.log(r.getValue())}
db.open(pnt, iter, "readwrite")
Error message is definitely not informative. I push a patch, so next time, it gives index not found error.
There is api changes in open method, as well. Documentation need to be update.
Edit: more complex query can be found in http://dev.yathit.com/ydn-db/nosql-query.html
Ok, finally got it from the link in the previous answer:
// Equivalent to: SELECT * FROM store1 where value = 'value1':
var keyRange = ydn.db.KeyRange.only("value1");
var cursor = new ydn.db.IndexValueCursors("store1", "value", keyRange);
db.get(cursor, keyRange).then(function(record) {
console.log("record:", record);
}, function(err) {
throw err;
});

Kendo UI adding row at Runtime(Client Side)

I am able to add a row at runtime using .js file into Kendo Data Source, but I havent seen from the form(UI), I followed the below steps
var vgrid = $("#grdEntitys").data("kendoGrid");
var datasource = vgrid.dataSource;
var newRecord = { No: "8164",ModellNo: "147",ID: "Test01", Name: "TEST"}
datasource.insert(newRecord);
then It throws an error "TypeError: Cannot read property 'AttributeValue' of undefined",
if we look at the console log, I am able to see the incrmented rows count as well as the newly inserted record. But in UI there is no change(UI Grid).
could you please anyone let me know, how to add row at client side?
Thanks in advance
For insert you have to specify index (Insert) :
var dataItem = dataSource.insert(0, { name: "John Doe" });
Alternatively you could use Add where you don't have to specify the index:
<script>
var dataSource= new kendo.data.DataSource({
data: [
{ name: "Jane Doe", age: 30 }
]
});
dataSource.add({ name: "John Doe", age: 33 });
you can use the script in you event to add item in your grid.
var dataSource = $("#CustomerPackageChannelKendoGridAdd").data("kendoGrid").dataSource;
// Get value from another field
var _JV_ACCOUNT_ID = $('#JV_ACCOUNT_ID').val();
var _JV_ACCOUNT_NAME = $('#JV_ACCOUNT_NAME').val();
var _JV_ACCOUNT_CODE = $('#JV_ACCOUNT_CODE').val();
var _JV_NOTES = $('#JV_NOTES').val();
var _JV_DATE = $('#JV_DATE').val();
var type = $('#JV_Transaction_TYPE').val();
// You can set condition if required for you
if (CheckExistingData(gridDataAdd, _JV_ACCOUNT_ID) == false) {
currentId += 1;
dataSource.add(
{
id: currentId,
JV_ACCOUNT_ID: _JV_ACCOUNT_ID,
JV_ACCOUNT_NAME: _JV_ACCOUNT_NAME
, JV_ACCOUNT_CODE: _JV_ACCOUNT_CODE
, JV_NOTES: _JV_NOTES
, JV_DATE: _JV_DATE
, JV_DEBIT_AMOUNT: _JV_DEBIT_AMOUNT
, JV_CREDIT_AMOUNT: _JV_CREDIT_AMOUNT
});
}
For more you can also see this:

Cannot access property of Ember.js model

I have a problem accessing model properties in Ember.js
Model:
App.Page = DS.Model.extend({
title: DS.attr('string'),
parent: DS.attr('number'),
});
Controller:
App.BlocksController = Ember.ArrayController.extend({
pages: function() {
return App.Page.find();
}.property(),
pageTree: function() {
var pages = this.get('pages.content'),
pageTree = new Tree();
for(var i = 0; i < pages.length; i++) {
console.log( pages[i], pages[i].id, pages[i].parent );
}
pageTree.insertList(pages);
return pageTree;
}.property('pages.#each'),
});
I use the pageTree property in a template/view. The console.log does print me objects that have been retrieved from the API (incl. id), however, I cannot access its properties (parent giving me undefined, but it's in the API response).
One console.log lines looks like this:
Object {id: "5", clientId: 19, type: function, data: Object, prematerialized: Object…}
"5"
undefined
I assume that using pages.#each as a property, the pageTree property should be bound to the (loaded) pages array.
Yes, pages is not the model that is controlled by the ArrayController, but a secondary set of models.
When I use {{#each pages}}{{parent}}{{/each}} in the template, it works! So I guess, the problem has to do with the data bindings?
For reference, I'm on Ember 1.0.0-rc.6.1, ember-data 0.13, ember-data-django-rest-adapter 0.13
Okay, thanks to the IRC:
pageTree: function() {
var pages = this.get('pages'),
pageTree = new Tree();
pages.forEach(function(page) {
//console.log(page, page.get('parent'));
pageTree.insertAt(page.get('parent'), page );
});
return pageTree;
}.property('pages.#each'),
So, no .content, but forEach and .get().

Resources