Week 12 Templates and Collections
Working with Meteor: implementing routing, templates, and geolocation.
Routing troubleshooting
As described last week, I’ve installed Iron:Router to handle URL and template routing for annotatAR. Last week, I ran into an issue where the new routing scheme seemed to break the Javascript that generated the AR elements. Upon testing and inspection, I determined that it was the template rendering that caused the issue - the AR code ran before the template had fully rendered and therefore had been attempting to act on parts of the DOM that didn’t exist yet. It was an easy fix once I realized this, I put the AR script inside of a call-back function:
Template.mytemplate.onRendered(function(){....})
I now have two routes for my site, the index (documentation) page and the AR page. Each has their own template.
Hashtag / Geolocation collection
I’ve also implemented the hashtag lookup functionality. There is now a collection that contains each lat/long and hashtag association. Also, the server publishes a number of versions of the tweet collection, one for each hashtag in the Hashtag collection. When the client loads the page, a script looks up the hashtag and subscribe to the appropriate publication. This should be quite secure, as the client doesn’t make a special request of the server – it simply subscribes to a different publication that the server is already making available.
I’ve run into a bug in implementing this system. On the server, I’d like to be able to iterate over all of the hashtags in the Hastags collection and automatically collect tweets for each one. To do so I’m using hashtags.map()
to call the fiber for the Twitter API. I need to be able to pass each hashtag to this fiber, and thus far I haven’t figured out how to do that without throwing an error.
var handleTweets = Meteor.bindEnvironment(function(err, data, response) {
console.log(data);
console.log("***********************", err, "***********************");
for(var i = 0; i < data.statuses.length; i++){
Meteor.call("addTweet", data.statuses[i].text, hashtag, data.statuses[i].created_at);
}
});
//**************************************************//
// ****** uncomment to turn the rest on: ****** //
hashtags.map(function(hashtag){
Twit.get('search/tweets',
{
q: hashtag,
count: 20
}, handleTweets);
})
In prior versions of the application, hashtag
was scoped within the containing function for both of these calls, but now it is not. Further research on fibers might be helpful.
Fullscreen
While I was taking a break from troubleshooting the templating issue, I also worked on fullscreen for AR. This has been a tricky problem to solve - there are built-in fullscreening styles for video
elements, but the AR canvas is actually a series of images that are taken from the cdevice input and rendered one frame every 100ms with the tweet text overlaid. I need to scale the image to fit the device viewport, and also slice the image to fill the screen.
The code needs to check if:
- check if the dimensions of the video are larger than the dimensions of the viewport
- check if the viewport is in portrait (height > width) or landscape (height < width)
- scale the image so that the shorter dimension matches the corresponding viewport dimension
- slice any extra parts from the scaled image to center it on the viewport
I’ve tried a few methods to do this, and nothing seems to work 100% of the time.
Next steps
I’ve solved some of the major problems with annotatAR but I’ve still got a long way to go in the next couple of weeks. After fixing the bugs with the Twitter fiber and with fullscreen, I can move on to:
- Styling the documentation page
- Adding a map to the documentation page
- Using accelerometer data to change the tweet positions
- Styling the tweets
- Deploying annotatAR on Digital Ocean