十年前有值得分享的图片我都存在Flickr上,可惜yahoo收购了Flickr之后堕落好多年,最近yahoo在梅姐带领下Flickr团队终于恢复了生机,个人免费存储空间扩充到了1T,界面用户体验也有了很大改进,图片归类及设置Tag比以前易用很多,不过我还是不满意传统改良的Web方式操作图片,我还是喜欢更有交互感的图片操作体验,借助hightopo的HT for Web的拓扑图组件写了个自己满意的搜查Flickr图片例子。
Flickr提供了OpenAPI的搜索方式,到网页输入http://api.flickr.com/services/feeds/photos_public.gne?tags=hightopo&format=json的链接,基本原理就一目了然,通过修改url的tags=内容,即可实现搜索不同tag图片的结果。这个url返回的是个jsonp的函数回调jsonFlickrFeed({…}),关于jsonp主要就是用来解决跨域访问的安全问题,我们只需要实现处理数据jsonFlickrFeed等着flickr服务器下发回调即可,jsonp的文章已经很多再次不再详述。
输入框每次输入关键字后我构建了个document.createElement(‘script’),同时避免DOM无限制增长删除了上次查询的结果,当然也不删也问题不大,只不过对我这种有代码洁癖者,看到DOM上有没用的元素我就很不爽。
searchJS = document.createElement('script'); searchJS.setAttribute('src', 'http://api.flickr.com/services/feeds/photos_public.gne?tags=' + tag + '&format=json'); document.getElementsByTagName('head')[0].appendChild(searchJS);
剩下就很简单了,在jsonFlickrFeed函数里面遍历Flickr返回的图片数组信息,每个元素的title就是图片名称,media.m就是图片路径,根据这些信息创建每个相应的图元,然后通过new ht.layout.ForceLayout(g2d).start()构建一个弹力布局器去自动布局就完事了。
这个视频搜索了hightopo、girl和cr7关键字的效果,再有两个小时西甲的重头戏皇马和巴萨就要开展了,明天还要工作我只能洗洗睡吧,在此祝我喜欢的CR7能进球。
以下为本例子的所有js代码
function init(){ input = ht.Default.createElement('input', null, null, 'hightopo'); input.onkeypress = function(e){ if (e.keyCode === 13){ search(); } }; items = [ { element: input }, { label: 'Clear', action: function(){ dataModel.clear(); } } ]; dataModel = new ht.DataModel(); g2d = new ht.graph.GraphView(dataModel); toolbar = new ht.widget.Toolbar(items); borderPane = new ht.widget.BorderPane(); borderPane.setTopView(toolbar); borderPane.setCenterView(g2d); view = borderPane.getView(); view.className = 'main'; document.body.appendChild(view); window.addEventListener('resize', function (e) { borderPane.invalidate(); }, false); forceLayout = new ht.layout.ForceLayout(g2d); forceLayout.start(); } function search() { if (window.searchJS) { document.getElementsByTagName('head')[0].removeChild(searchJS); } var tag = input.value; searchJS = document.createElement('script'); searchJS.setAttribute('src', 'http://api.flickr.com/services/feeds/photos_public.gne?tags=' + tag + '&format=json'); document.getElementsByTagName('head')[0].appendChild(searchJS); root = new ht.Node(); root.s({ 'shape': 'circle', 'shape.gradient': 'radial.center', 'shape.background': '#E74C3C', 'label': tag, 'label.background': 'yellow', 'select.width': 0 }); root.setSize(30, 30); dataModel.add(root); return root; } function jsonFlickrFeed(datas) { datas.items.forEach(function(item){ var node = new ht.Node(); node.a(item); node.setName(item.title); node.s({ 'label.background': 'yellow' }); node.setImage(item.media.m); dataModel.add(node); var edge = new ht.Edge(root, node); edge.s({ 'edge.3d': true, 'edge.width': 4, 'edge.color': '#1ABC9C' }); dataModel.add(edge); }); }