2015年3月15日星期日

How to create and test a webpage meant for Retina display?

We can write a responsive webpage using Media Queries to provide an optimal viewing experience—easy reading and navigation with a minimum of resizing, panning, and scrolling—across a wide range of devices from desktop computer monitors to mobile phones.
<!-- show this div when the display is not a retina display -->
<div class="box box-non-retina">
   <h2>Non-Retina</h2>
</div><!-- end desktop -->

<!-- show this when it is a retina display -->  
<div class="box box-retina">
   <h2>Retina</h2>
</div><!-- end tablet -->
Next, we need to write some Media Queries in the css file to display the div responsively according the attribute of display devices.
/* Media Queries */
@media only screen and (-webkit-min-device-pixel-ratio: 2),
    only screen and (   min--moz-device-pixel-ratio: 2),
    only screen and (   -moz-min-device-pixel-ratio: 2),
    only screen and (     -o-min-device-pixel-ratio: 2/1),
       only screen and (        min-device-pixel-ratio: 2),
       only screen and (                min-resolution: 192dpi),
       only screen and (                min-resolution: 2dppx) { 
           
           .box-non-retina {
               display: none;
           }
           
           .box-retina {
               display: block;
           }
}
See? It is easy. But how can we check if it works? The simplest way is to test it with Firefox.
  • In the Firefox address bar, type about:config and press the Enter key. 
  • Search for the layout.css.devPixelsPerPx preference.
  • Change it to your desired ratio ( 1 for normal, 2 for retina)
After setting the ratio,  you can verify if the css code works. You can also test your other responsive design with Firefox Responsive Design View by selecting "Responsive Design View" from the Web Developer submenu in the Firefox Menu.

2015年3月9日星期一

The Shapes of CSS

Sometimes, we need some shapes in our html pages. For instance, you would like to put a left triangle shape to link to the previous page and a right triangle to link to the next page. There are some simple css tricks with which you can make it. I found a great website gave out many examples. See CSS Tricks

The html code below have 3 elements in it, 2 button and 1 image. We want the button in triangle shape.

 <button class="btn_prev">Previous Slide</button>  
 <img src="images/vancouver_01.jpg" alt="Vancouver" class="slide" />  
 <button class="btn_next">Next Slide</button>  

We can make it with some css code:

 .btn_prev {
 /* triangle code from: 
 http://css-tricks.com/examples/ShapesOfCSS/
 */
 border-top: 25px solid transparent;
 border-right: 25px solid #000000;
 border-bottom: 25px solid transparent;
 left: 0; 
}

Can you write css code for the Next button?

2015年3月8日星期日

Make Simple Animation With JavaScript

Step 1, make a simple html file to show pictures.

<div class="container_slide_show">

<img class="slide" src="images/kittens_01.jpg" alt="Kittens" />
<p class="slide_description">Orange kitten</p>
</div>

Step 2, prepare some pictures you want to display animatedly. For example, you can save kittens_02.jpg, kittens_03.jpg,kittens_04.jpg in the ./images directory.

Step 3, write script to animate the pictures:

var $slide = $('.slide');
var $slideDescription = $('.slide_description');
var kittenPics = [];
var imageCache = [];

kittenPics[0] = ['images/kittens_01.jpg', 'Orange kitten'];
kittenPics[1] = ['images/kittens_02.jpg', 'Brown striped kitten'];
kittenPics[2] = ['images/kittens_03.jpg', 'Three kittens'];
kittenPics[3] = ['images/kittens_04.jpg', 'Orange kitten on the grass'];

// Cache images
for(var i = 0; i < kittenPics.length; i++){
 var image = new Image;
 image.src = kittenPics[i][0];
 image.alt = kittenPics[i][1];
 imageCache.push(image); 
}

// Start slide show
var imageCounter = 0;
setInterval(changeSlide, 2000);

function changeSlide(){
    var icounter = imageCounter % imageCache.length;
    console.log("icounter = " + icounter);
    var image = imageCache[icounter];
    
    $slide.attr('src', image.src);
    $slide.attr('alt', image.alt);
    $slideDescription.text ( image.alt);
    imageCounter++;
}

Now, it works. The page will change a picture every 2,000ms. We can add more functions to it: stop animation when the mouse hover on it.

$slide.hover( function(ev){
    clearInterval(timer);
}, function(ev){
    timer = setInterval(changeSlide, 500);
});

2015年3月5日星期四

Add Theme Assets in Tumblr Template

You can customize your Tumblr posts using Tumblr custom theme. Check documents in this address to see how to create your own theme(How to create a custom HTML theme).

A problem is how can you include a css file in this HTML theme if you want to stylize your post in Tumblr. Fortunately, Tumblr provided a way with which you can include css files into your HTML theme.

In your Tumblr homepage, click 'Customize' -> 'Edit HTML', then click the little cog in the upper left corner, select 'Theme assets' in the popup menu, then you can upload your css files from file system to Tumblr.  Place the mouse cursor on the place where you want to link css, then click 'insert' in the 'Theme assets' menu, there will add a line in the html, like this:

http://static.tumblr.com/jij4rw2/0Jpnket8k/skeleton.css
"  />
the code in red color was generated by Tumblr.

2015年3月2日星期一

调用google map API的两个小 问题

任务如下:设计一个网页,提供输入框,由用户输入起始地址。目的地址是一个下拉框,里面是BCIT的5个校区。界面上还有1个“get directions”的按钮。用户输入起始、目的地址后,点击按钮,界面就显示地图和路线说明。如图:


实现起来也比较容易:
1、在html文件中包含jQuery和google MAP。



2、调用google.maps.Geocoder()方法获取用户输入起始地址的经纬度。目标地址的经纬度可以事先查好,写到下拉列表的value中去。调用可参考谷歌地图定位服务编程接口

3、使用起始、目的地址为参数,调用google map的direction service,来获取路线图和路线说明。调用可参考谷歌地图路线服务编程接口

然后就可以了。但出现了2个问题:1)选取不同的起始地、目的地,重新获取路线时,以前地路线图和路线说明没有清除,仍旧留在地图上。看上去很乱。2)刷新页面,第一次点击“获取路线”按钮时,系统仅绘出2个地标,却没有绘制路线图和路线说明。此后再点击则是正常的。

问题1 的原因在于把语句directionsDisplay = new google.maps.DirectionsRenderer()放入了点击获取路线按钮所调用的函数中,把它放入到页面的初始化函数中仅调用一次。得以解决。

问题2 的原因是调用Geocode方法时,对它的返回值处理不当。因为Ajax是异步调用,获取起始地址的经纬度还没有从服务器端得到响应时,程序就继续向下处理了。所以后面调用获取路线时,服务器就会抱怨没有提供起始地址。解决起来也简单:把调用路线服务的代码放入到调用Geocode方法的callback中就可以了。即:

 geocoder.geocode({'address': address}, function(results, status) {
        
        var location = results[0].geometry.location;
        var startLatlng = new google.maps.LatLng(location.lat(), location.lng());
        addMarker(startLatlng);
             
        // Create a new Marker object for destination.
        var endAddress = $( "#selectCampus").val();
        var endLat = endAddress.substring(0, endAddress.indexOf(','));
        var endLng = endAddress.substring(endAddress.indexOf(',') + 1); 
        endLatlng = new google.maps.LatLng(endLat, endLng);
        addMarker(endLatlng);

        var request = {
            origin:startLatlng,
            destination:endLatlng,
            travelMode: google.maps.TravelMode.DRIVING
        };

        directionsService.route(request, function(result, status) {
            if (status == google.maps.DirectionsStatus.OK) {
              directionsDisplay.setDirections(result);
            }
            else {
                alert('Directions Service was not successful for the following reason: ' + status);
            }
        });
    });

代码中标示为绿色的部分代码就是调用路线服务所用。如果把这部分代码移到这个函数之外,就会出现异步调用的问题。