20、社交地图开发全流程:从基础交互到个性化定制

社交地图开发全流程:从基础交互到个性化定制

在社交地图项目中,我们致力于为 Twitter 搜索结果增添更多细节,打造一个功能丰富、交互性强且视觉效果出色的社交地图。以下将详细介绍从构建高级交互标记到添加多推文显示,再到自定义标记外观的整个开发过程。

构建高级交互标记

为了让社交地图更加生动,我们需要在 Twitter 搜索结果出现时自动打开信息面板。这一过程涉及创建 Google Marker 的子类,并为其添加新的 InfoWindow,以便将实时 HTML 数据集成到地图中。

操作步骤
1. 替换标记 :在 showTweet 函数中,将新标记替换为 TwitterMarker 标记。

function showTweet(obj,latLng){
    if(!obj) obj = {text:'No tweet found in this area for this topic'};
    console.log(obj);   
    var marker = new TwitterMarker({
        map: map,
        position: latLng,
        tweet: obj,
        title:obj.text    
    });     
}
  1. 创建自定义标记 :定义 TwitterMarker 构造函数。
function TwitterMarker(opt){
    var strTweet = this.buildTwitterHTML(opt.tweet);
    this.infoWindow = new google.maps.InfoWindow({
        maxWidth:300,
        content:strTweet
    });
    this.setValues(opt);
    this.infoWindow.open(this.map,this);
    google.maps.event.addListener(this, 'click', this.onMarkerClick);
}
  1. 继承标记功能 :让 TwitterMarker 继承 google.maps.Marker 的所有特性。
TwitterMarker.prototype = new google.maps.Marker();
  1. 添加切换按钮 :在标记事件监听器中创建切换按钮,控制 InfoWindow 的打开和关闭。
TwitterMarker.prototype.onMarkerClick=function(evt){
    this.isOpen=!this.isOpen;
    if(this.isOpen)
        this.infoWindow.close();
    else
        this.infoWindow.open(this.map,this);
}
  1. 生成 Twitter 消息 HTML :实现 buildTwitterHTML 方法,根据 Twitter 对象生成 HTML 字符串。
TwitterMarker.prototype.buildTwitterHTML = function(twt){
    var str;
    if(twt.from_user_name){
        str =   
        "<span><img style='float: left' src='"+twt.profile_image_url+"' />"+
            "<b>" +twt.from_user_name + "</b><br/><a href ='http://twitter.com/"
            + twt.from_user + "'>@"+twt.from_user+"</a><br/> "
            + twt.location + "</span>"
            + "<p>"+twt.text+"</p>";
    }else{
        str="The 50 Kilometer radius around this point did not message this value";
    }
    return str;
}

工作原理
通过 JavaScript 的继承机制,我们可以在不影响原始对象的情况下扩展其功能。 TwitterMarker 继承了 google.maps.Marker 的所有特性,并添加了自定义行为。 buildTwitterHTML 方法将 Twitter 对象的数据转换为 HTML,用于在 InfoWindow 中显示。切换按钮的逻辑基于 isOpen 变量,通过点击标记来切换其状态,从而控制 InfoWindow 的打开和关闭。

添加多推文到 InfoWindow

为了在 InfoWindow 中显示多条推文,我们需要添加分页系统。

操作步骤
1. 修改搜索链接 :将 Twitter 搜索设置为每次返回最多 100 个结果。

var searchLink = 'http://search.twitter.com/search.json?q='+ searchKeyWord+ '&geocode=' + geocode +"&result_type=recent&rpp=100";
  1. 更新事件监听器 :将完整的推文数组传递给 TwitterMarker 构造函数。
google.maps.event.addListener(map, 'click', function(e) {
    var searchKeyWord = 'html5';
    var geocode=e.latLng.lat() + "," + e.latLng.lng()+",50km";
    var searchLink = 'http://search.twitter.com/search.json?q='+ searchKeyWord+ '&geocode=' + geocode +"&result_type=recent&rpp=100";
    $.getJSON(searchLink, function(data) {
        showTweet(data.results,e.latLng);
    });
});
function showTweet(a,latLng){
    if(!a) a = [{text:'No tweet found in this area for this topic'}];
    var marker = new TwitterMarker({
        map: map,
        position: latLng,
        tweet: a,
        title:a[0].text    
    }); 
}
  1. 更新构造函数 :在 TwitterMarker 构造函数中添加推文数量和当前推文索引的信息,并为每个标记分配唯一的 ID。
function TwitterMarker(opt){
    this.count = opt.tweet.length;
    this.crnt = 0;
    this.id = TwitterMarker.aMarkers.push(this);
    this.aTweets = opt.tweet;
    var strTweet = this.buildTwitterHTML(opt.tweet[0])
    this.infoWindow = new google.maps.InfoWindow({
        maxWidth:300,
        content:strTweet
    });
    this.setValues(opt);
    this.infoWindow.open(this.map,this);
    google.maps.event.addListener(this, 'click', this.onMarkerClick);
}
  1. 存储标记 :创建一个静态数组 TwitterMarker.aMarkers 来存储所有标记。
TwitterMarker.prototype = new google.maps.Marker();
TwitterMarker.aMarkers= [];
  1. 添加导航链接 :在 buildTwitterHTML 方法中添加前后导航链接。
TwitterMarker.prototype.buildTwitterHTML = function(twt){
    var str;
    if(twt.from_user_name){
        str =   
        "<span><img style='float: left' src='"+twt.profile_image_url+"' />"+
            "<b>" +twt.from_user_name + "</b><br/><a href ='http://twitter.com/"
            + twt.from_user + "'>@"+twt.from_user+"</a><br/> "
            + twt.location + "</span>"
            + "<p>"+twt.text+"</p>";
        if(this.count>1){
            str+="<span style='absolute; bottom: 0; right: 0px; width:80px'>";
            if(this.crnt!=0) str+="<a href='javascript:TwitterMarker.aMarkers["+(this.id-1)+"].prev();'>&lt;</a> ";
            str+= (this.crnt+1) + " of " + this.count;
            if(this.crnt<(this.count-1)) str+= "<a href='javascript:TwitterMarker.aMarkers["+(this.id-1)+"].next();'>&gt;</a> ";
            str+= "</span>" 
        }
    }else{
        str="The 50 Kilometer radius around this point did not message this value";
    }
    return str;
}
  1. 实现前后切换方法 :添加 next prev 方法,用于切换推文。
TwitterMarker.prototype.next =function(){
    this.infoWindow.close();
    this.infoWindow.content = this.buildTwitterHTML(this.aTweets[++this.crnt]);
    this.infoWindow.open(this.map,this);
    return false;   
}
TwitterMarker.prototype.prev =function(){
    this.infoWindow.close();
    this.infoWindow.content = this.buildTwitterHTML(this.aTweets[--this.crnt]);
    this.infoWindow.open(this.map,this);
    return false;   
}

工作原理
首先,我们修改了 Twitter 搜索 API 的返回结果数量,以获取更多推文。然后,将完整的推文数组传递给 TwitterMarker 构造函数。通过创建静态数组 TwitterMarker.aMarkers ,我们可以在 InfoWindow 中引用标记并实现前后导航功能。在 buildTwitterHTML 方法中,根据推文数量和当前索引添加导航链接,点击链接时调用 next prev 方法来切换推文。

以下是添加多推文到 InfoWindow 的流程图:

graph TD;
    A[修改搜索链接] --> B[更新事件监听器];
    B --> C[更新构造函数];
    C --> D[存储标记];
    D --> E[添加导航链接];
    E --> F[实现前后切换方法];

通过以上步骤,我们可以在社交地图的 InfoWindow 中显示多条推文,并实现分页导航功能,为用户提供更好的交互体验。

社交地图开发全流程:从基础交互到个性化定制(续)

自定义标记的外观和感觉

接下来,我们将对标记本身进行改造,使其更具特色。我们会把标记更新为类似 Twitter 鸟的样式,并且添加一个图形层来为 Twitter 标记添加阴影,阴影的不透明度将根据推文数量(最多 100 条推文)从 0 到完全不透明变化。

操作步骤
1. 更新 showTweet 函数

function showTweet(a,latLng){
    if(!a) a = [{text:'No tweet found in this area for this topic'}];
    var marker = new TwitterMarker({
        map: map,
        position: latLng,
        tweet: a,
        title:a[0].text,
        icon:"img/bird.png"    
    }); 
}
  1. TweeterMarker 构造函数中创建 MarkerCounter 对象实例
function TwitterMarker(opt){
    this.count = opt.tweet.length;
    this.mc = new MarkerCounter(opt);
    this.crnt = 0;
    // 其他代码...
}
  1. 创建 MarkerCounter 构造函数
function MarkerCounter(opt) {
    this.radius = 15;
    this.opacity = (opt.tweet.length) /100;
    this.opt = opt;
    this.setMap(opt.map);
}
  1. 创建 MarkerCounter 作为 google.maps.OverlayView 对象的子类
MarkerCounter.prototype = new google.maps.OverlayView();
  1. 创建 onAdd 方法 :当元素添加到地图时,该方法会自动调用,用于完成绘制的准备工作。
MarkerCounter.prototype.onAdd = function() {
    var div = document.createElement('div');
    div.style.border = "none";
    div.style.borderWidth = "0px";
    div.style.position = "absolute";

    this.canvas = document.createElement("CANVAS");
    this.canvas.width = this.radius*2;
    this.canvas.height = this.radius*2;
    this.context = this.canvas.getContext("2d");
    div.appendChild(this.canvas);
    this.div_ = div;
    var panes = this.getPanes();
    panes.overlayLayer.appendChild(div);
}
  1. 重写 draw 方法 :在新创建的 canvas 元素中进行绘制,并定位 div 元素。
MarkerCounter.prototype.draw = function() {
    var radius = this.radius;
    var context = this.context;
    context.clearRect(0,0,radius*2,radius*2);
    context.fillStyle = "rgba(73,154,219,"+this.opacity+")";
    context.beginPath();
    context.arc(radius,radius, radius, 0, Math.PI*2, true);
    context.closePath();
    context.fill();
    var projection = this.getProjection();
    var point = projection.fromLatLngToDivPixel(this.opt.position);

    this.div_.style.left = (point.x - radius) + 'px';
    this.div_.style.top = (point.y - radius) + 'px';
};

工作原理
首先,我们通过在 showTweet 函数中传递 icon 参数,将标记的默认图形替换为 Twitter 鸟的图形。由于我们扩展了常规标记,所以可以使用其默认功能来交换图标。然后,我们创建了 MarkerCounter 类作为 google.maps.OverlayView 的子类,用于添加阴影层。在 onAdd 方法中,我们创建了一个 div 元素和一个 canvas 元素,并将 canvas 元素添加到 div 中,最后将 div 添加到地图的覆盖层。在 draw 方法中,我们根据推文数量设置阴影的不透明度,并使用 canvas 绘制圆形阴影。通过 getProjection 方法将经纬度转换为像素坐标,从而正确定位阴影层。

以下是自定义标记外观的操作步骤表格:
| 步骤 | 操作 |
| ---- | ---- |
| 1 | 更新 showTweet 函数,设置图标 |
| 2 | 在 TweeterMarker 构造函数中创建 MarkerCounter 实例 |
| 3 | 创建 MarkerCounter 构造函数 |
| 4 | 创建 MarkerCounter 作为 google.maps.OverlayView 的子类 |
| 5 | 创建 onAdd 方法,完成绘制准备 |
| 6 | 重写 draw 方法,进行绘制和定位 |

处理无结果情况

目前,我们假设世界上某个地方总是有推文,但实际情况并非如此。因此,我们需要重写行为,在没有结果时提供替代标记,并跳过所有自定义操作。

操作步骤
1. 更新 showTweet 函数

function showTweet(a,latLng){
    var marker = new TwitterMarker({
        map: map,
        position: latLng,
        tweet: a,
        title:a.length? a[0].text : 'No tweet found in this area for this topic',
        icon:"img/bird.png"    
    }); 
}
  1. 重写 TwitterMarker 构造函数
function TwitterMarker(opt){
    if(!opt.tweet || !opt.tweet.length){
        opt.icon = "img/x.png"; 
    }else{
        this.count = opt.tweet.length;
        this.mc = new MarkerCounter(opt);
        this.crnt = 0;
        this.id = TwitterMarker.aMarkers.push(this);
        this.aTweets = opt.tweet;
        var strTweet = this.buildTwitterHTML(opt.tweet[0])
        this.infoWindow = new google.maps.InfoWindow({
            maxWidth:300,
            content:strTweet
        });
        this.infoWindow.open(this.map,this);
        google.maps.event.addListener(this, 'click', this.onMarkerClick);
    }
    this.setValues(opt);
}

工作原理
showTweet 函数中,我们使用三元运算符根据推文数组的长度更新标记的标题。在 TwitterMarker 构造函数中,我们首先检查是否有推文,如果没有,则将图标更新为 img/x.png ;如果有推文,则继续执行正常的初始化操作。最后,无论是否有推文,都调用 setValues 方法来设置标记的属性。

以下是处理无结果情况的流程图:

graph TD;
    A[更新 `showTweet` 函数] --> B[重写 `TwitterMarker` 构造函数];
    B --> C{是否有推文};
    C -- 是 --> D[正常初始化];
    C -- 否 --> E[更新图标为 `img/x.png`];
    D --> F[调用 `setValues` 方法];
    E --> F;

通过以上步骤,我们完成了社交地图的开发,包括构建高级交互标记、添加多推文显示和自定义标记外观,并处理了无结果的情况。这个社交地图可以让用户更方便地查看特定区域的 Twitter 推文,并且提供了良好的交互体验。你还可以进一步扩展这个项目,例如更容易地更改搜索词,或者比较两个搜索结果等。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值