让Compass支持sourcemap选项

使用Sass或Less的同学都知道sourcemap这个选项,编译时开启该选项后将生成map文件,非常利于我们调试Sass代码。

看一个浏览器调试sourcemap debugging效果:

 

可以看到,右侧的代码位置会直接定位到相应的Sass代码。

如何开启sourcemap?

Sass/Less: 在Koala中勾选sourcemap选项即可。

 

Compass: 目前还不支持Sass的sourcemap选项,需要安装额外一个库。
首先需要在本地安装好ruby, Sass, Compass.

下载并安装ruby: https://www.ruby-lang.org/zh_cn/downloads/

安装Sass & Compass

$ gem install sass
$ gem install compass

安装compass-sourcemaps

$ gem install compass-sourcemaps --pre

在Compass项目配置文件config.rb中增加enable_sourcemaps配置

# enable sourcemaps
enable_sourcemaps = true
sass_options = {:sourcemap => true}

Koala设置:
因为需要调用本地的compass-sourcemaps库,所以需设置Koala调用系统组件。
Koala设置 –> Compass –> 使用系统组件

 

现在已经为Compass项目开启sourcemap选项了,编译一个SASS文件试试,你将在CSS输出目录看到相应的map文件。

如果还看不到上面第一个图片上的调试效果,请检查你是否在Chrome浏览器中开启“Enable CSS source maps”选项。
Chrome设置:打开Devtools, 点击右上角的settings图标,找到“Sources”, 勾选“Enable CSS source maps”.

推荐使用前端工具Koala: http://koala-app.com/

<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> Koala | <span class="entry-utility-prep entry-utility-prep-tag-links">Tagged</span> , | Leave a comment

HTML5游戏开发实战分享

现在越来越多的人开始尝试使用html5开发游戏应用,随着设备性能的提高,以及硬件API支持度的完善,这些条件让使用html5开发出一个媲美原生体验的游戏应用变得可能,或许你已经是迫不及待了。Web的优势不言而喻,跨平台特性可以大大降低应用的开发成本;知道地址就够了,服务器端更新,这些同时又能降低用户的获取成本。 但目前来说,使用html5技术还是会碰到不少挑战,本文主要分享手机QQ中一款html5游戏的实战经验,我们在开发的过程中,做了一些创新的地方,希望能给大家打开更多思路。

首先让来大家来玩一款游戏。在手机QQ的好友聊天对话框中,按右下角的“+”号键,即会出现“一起玩”的黄色Logo,点击Logo,即可进入“一起玩”平台选择游戏。

一起玩中的两款游戏都是html5应用,下面是开发过程中的一些要点。

技术选型:Canvas 还是 DOM (html+css+js)

看了很多介绍html5游戏开发的文章,大多数案例都是使用Canvas来制作,目前已有不少优秀的游戏引擎了。但我并没有选择Canvas,我们这次需要做的是一个轻量级小游戏,我不想使用那些笨重的框架。并且Canvas也有一些缺点,比如没有实现动画的API,你必须依靠定时器和其他事件来更新Canvas,对文本的渲染支持也是比较差,由于Canvas里面没有dom节点,当某个元素需要执行交互事件(如click)的时候只能是通过坐标来判断。
那如果以传统的DOM页面形式来制作会怎么样呢?事实上我们可以发现传统页面制作的方式有很多优点,比如元素布局使用css控制, 动画可以用css3 的animation与transition,以及屏幕尺寸适配可以使用media query,最关键的是,我们对这些技术非常熟悉。所以“捏泡泡”游戏我最后选择了使用html+css +js来开发。

巧妙地使用css3动画

一款游戏肯定包含非常多的动画元素。在jQuery横行的时代,我们用$.fn.animate函数用得不亦乐乎。css3出来后,我们可以更方便简单地编写动画。Css3动画与js结合使用,基本上能完成游戏中的各种动画。

这个是泡泡爆炸动画UI,每个泡泡爆炸效果共有4帧,使用css3 animation属性我们很容易就制作出一个类似gif的动画,并且还能使用js进行控制。

参考代码:

.bubble s {
    background-image: url(../img/game/bubble.png);
}

.bubble.cleared s {
    opacity: 0;
    -webkit-transition: opacity 50ms 200ms;
    -webkit-animation: blowup 250ms step-end;
}

@-webkit-keyframes blowup {
    30% {background-position:-70px  0}
    60% {background-position:-140px  0}
    100% {background-position:-210px  0}
}

上面的代码,只需要给泡泡元素添加一个类名.cleared, 就能触发爆炸效果。
Css3动画主要有transition与animation两个属性,transition可控制元素变形、缩放、透明度等属性的变化,animation则是一个动画帧的概念,允许创建多个帧组合成一个动画,以达到更精细的动画控制。Css动画的另一个优势是可以与js完美结合,我们完全可以用css编写一个复杂的动画,再使用js非常简单地控制。

一些css动画教程:
Using CSS transitions:https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Using CSS animations:https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations
这里推荐一个css动画库,包含很多常见的动画效果,供做参考。
Animate.css: http://daneden.github.io/animate.css/

多终端分辨率适配

先看不同设备下的界面自适应。

iPhone4s

Samsung Galaxy Note II

对应移动端应用来说,分配率适配是个逃不过的问题。我不知道传统的手机游戏是如何处理这个问题的,但是我这次很轻松就完成了适配。这是web的一个优势,相对于Canvas来说,这也是css的一个优势。使用百分比布局以及media query,我们很容易就能控制元素位置与可视区域。比如上面的两个画面,在不同的屏幕尺寸下,首先是可视区域不一样,更大的屏幕将看到更宽的内容,其实也只是修饰性内容更完整而已,游戏主要操作区域在所有屏幕下都是保证可见的;其次可以看到中间的弹窗间距以及泡泡排列间距,都很好地适应了不同的屏幕尺寸。在游戏的设计上,我们是以iPhone4s(960*640)尺寸为标准进行设计的。

设备功能API

在普通的浏览器环境中,浏览器对一些设备功能的支持还不够,各个浏览器也存在着很多兼容性问题,我们可能无法做到像原生游戏一样那么好的效果。
手机QQ团队的同学已经考虑到了这个问题,他们开发了一系列的api接口,只要是从手Q中的webview访问,就能调用这些api,比如媒体播放、麦克风、重力感应、震动等很酷的设备功能, 这对于html5应用来说无疑是很大的支持。

性能优化

所有人都在怀疑移动端网页的性能,但实际上并没有想像中的那么糟糕。目前手Q大部分用户已经是4.x安卓版本了,浏览器性能及api支持度都有了很大提高。在“捏泡泡”游戏中,我们也只是对比较常见的低端机型做降级处理,取消了一部分动画效果,不影响整个游戏的体验,其余的优化则跟传统的网页优化相似。
这里特别分享一下我们的图片压缩方式。一般的游戏都会大量地使用png图片,在PS中png图不像jpg,可以选择导出的质量,我们需要使用第三方压缩工具进行压缩处理。在对比了多款图片压缩类库后,我们最终选择了pngquant。这个库对png图压缩效率高的惊人,最高能减少70%多的体积。虽然采用的是有损压缩,但肉眼是无法看出差别的。

离线缓存

离线缓存是html5一个新特性,不仅可以让应用能够离线使用, 对于web应用,提升应用的载入速度对于用户体验来说也是非常重要的。
标准的html5 application cache目前的兼容性并不好,各种坑,目前业务上的使用基本还处在试用阶段。离线缓存是一种浏览器技术,对于hybrid app来说,我们可以自己实现它。
手Q目前已实现一套完整的离线缓存机制,支持离线包版本管理及更新。以“捏泡泡”游戏为例,大致的应用流程如下:
点击进入游戏 – 是否已存在该离线包?否,则第一次直接进入web页面, 后台自动下载离线包,第二次开始直接使用离线包资源;已存在,则直接使用离线包,后台请求服务器离线包版本是否变化,若有新版本则后台自动更新。
所以当你第二次打开游戏的时候,几乎是零等待的。

CSS动画,requestanimationframe, Canvas, 设备功能,离线缓存,这些已经满足开发一款游戏应用的基本要求了,相信会更多html5游戏出现。同样地,native + html5 也将是未来移动端最理想的开发模式。

<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> Koala, WEB技术 | <span class="entry-utility-prep entry-utility-prep-tag-links">Tagged</span> | Leave a comment

使用DNS Prefetching加速网页

什么是DNS Prefetching?

在网站性能优化方面,大家都知道可以使用多个域名加载静态资源文件,解决一个域名下并发请求数的限制,同时也不会附带不必要的cookie. 但也并非域名越多越好,多个域名将增加DNS的解析时间。另外,在你的站点中,链接出去的也可能是其他域名。DNS解析所花费的时间变化很大,延时范围从大约1毫秒到以常见的几秒钟时间。DNS Prefetching就是为了加速DNS解析时间,它实现了预解析功能,从而减少后面资源的加载时间。

如何使用?

<link rel="dns-prefetch" href="//host_name_to_prefetch.com">

非常简单,在网页头部增加rel属性为”dns-prefetch”的link标签,并在href中指定想要预解析的域名。

Example:

<html>
	<head>
		<link rel="dns-prefetch" href="//www.domain1.com">
		<link rel="dns-prefetch" href="//www.domain2.com">
	</head>
	<body>
		<img src="www.domain1.com/image1.jpeg">
		<script src="www.domain2.com/script1.js">
	</body>
</html>

当你网站包含多个域名时,这个是一个非常实用的功能,现在就开始使用吧。

浏览器支持:

Firefox 3.5+, Chrome, Safari 5+ and IE 9+

参考链接:
The Chromium Projects – DNS Prefetching
Controlling DNS prefetching

<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> WEB技术, 性能优化 | Leave a comment

IE下创建style标签出现未知错误的问题

动态创建一个style标签并设置css内容:

var style = document.createElement('style');
style.type = "text/css";
style.innerHTML = "..css content here..";
document.getElementsByTagName('head')[0].appendChild(style);

上面的代码看起来没有问题,但在IE6/7/8下访问你会发现提示出现未知错误。测试后发现问题出现在style.innerHTML这句上面,换成innerText依然报错。
解决方法是使用IE独有属性styleSheet.cssText,修改后是这样:

var style = document.createElement('style');
style.type = "text/css";
if (style.styleSheet) { //IE
	style.styleSheet.cssText = '/*..css content here..*/';
} else { //w3c
	style.innerHTML = '/*..css content here..*/';
}
document.getElementsByTagName('head')[0].appendChild(style);
<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> 前端开发 | <span class="entry-utility-prep entry-utility-prep-tag-links">Tagged</span> | Leave a comment

使用JavaScript实现media queries检测

最近在做一个项目,项目中需要根据用户的设备来加载不同的样式,比如同一个页面,如果是PC访问,则显示PC版样式,手机访问则显示mobile样式。这个是一个不完全属于响应式的设计。QQ会员下面有大量的活动页面,不同的活动页面结构会随主题而改变,不像首页之类的频道页。为了使手机用户也能获得更好的体验,我们专门设计了一套移动模版样式。

开始的时候我们直接使用css media query加载样式:

总体还Ok,各个浏览器都能兼容。此时产品观察到了一个问题,在PC下如果缩小浏览器窗口,则会切换到mobile.css,由于mobile.css是一套固定风格的样式,突然变换了风格,用户感觉起来将会很怪。于是我们就想区分PC与手机设备。

media: min-width 指的是浏览器窗口宽度,等价于document.documentElement.clientWidth;min-device-width 是设备宽度,等价于window.screen.width。 我们想到使用min-device-width进行判断,很显然这个行不通,很多设备的device-width比PC分辨率还宽。

最后也没能找到使用CSS控制的办法,只能是让JS来检测了。

最简单的方法是使用window.matchMedia:

var mq = window.matchMedia( "(min-width: 500px)" );
if (mq.matches) {
        // window width is at least 500px
}
else {
        // window width is less than 500px
}

但可惜目前在移动设备上支持度还不够。

换一个思路,先通过检测UA来区分移动设备与PC:


移动设备UA正则:/Mobile|iP(hone|od)|Android|BlackBerry|IEMobile/,这个正则可以匹配90%的移动设备。

下一步就是实现类似css media 检测。思路大致是向页面中插入一端带media规则的css代码,设置某个元素的css属性,然后在通过脚本获取这个属性进行对比。

完整检测代码如下:

(function () {
        var UA           = window.navigator.userAgent,
                detectStyle  = '<style type="text/css">@media (max-width: 640px) {#MobileDetect {color: rgb(12, 34, 56)}}</style>',
                detectDiv    = '<div id="MobileDetect"></div>';

        if (/Mobile|iP(hone|od)|Android|BlackBerry|IEMobile/.test(UA)) {
                //判断device width是否小于640
                var style = createElement(detectStyle),
                        div = createElement(detectDiv);
                document.head.appendChild(style);
                document.head.appendChild(div);

                //alert(getStyle(div, "color"))
                init(getStyle(div, "color") === 'rgb(12, 34, 56)');

                style.remove();
                div.remove();
        } else {
                init(false);
        }

        //初始化函数
        function init(flag) {
                if (!window.zDevice) window.zDevice = {};

                if (flag) {
                        window.isMobile = true;
                        window.zDevice.isSmallScreen = true;
                }
                //alert(window.isMobile);
        }

        //get element style
        function getStyle(oElm, strCssRule){
                var strValue = "";
                if(document.defaultView &amp;&amp; document.defaultView.getComputedStyle){
                        strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
                }
                else if(oElm.currentStyle){
                        strCssRule = strCssRule.replace(/-(w)/g, function (strMatch, p1){
                                return p1.toUpperCase();
                        });
                        strValue = oElm.currentStyle[strCssRule];
                }
                return strValue;
        }
        //createElement
        function createElement(string) {
           var elem = document.createElement("div");
           elem.innerHTML = string;
           return elem.childNodes[0];
        }
})();

其中的detectStyle可以根据需要进行定义,或者抽出一个API,把需要检测的css属性做为变量。

案例展示:http://youxi.vip.qq.com/game/act/201304/nz.html

手机可以扫描二维码访问:

<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> 前端开发 | <span class="entry-utility-prep entry-utility-prep-tag-links">Tagged</span> , | Leave a comment

Koala v1.0.1发布

Koala v1.0.1 发布

下载地址:http://koala-app.com

更新日志:

  • Compass项目支持config.rb配置。
  • 支持文件批量操作,可以批量设置output path与删除文件。
  • 支持拖拽添加文件到当前项目。
  • 设置output path时弹出的文件(目录)选择窗口直接定位到相关目录。
  • 修复无法保存项目配置的问题。
  • 修改Mac OSX下无法启动的问题。

欢迎体验!

<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> Koala | <span class="entry-utility-prep entry-utility-prep-tag-links">Tagged</span> | Leave a comment

解决iScroll横向滚动区域无法拉动页面的问题

近期项目中使用iScroll遇到一个问题,在设定wrapper为横向滚动时,如果你手指放在该区域,将无法拉动页面,也就是说该区域取消了默认事件。这个体验是实在是无法接受,特别是页面中有多个横向滚动区域时,很容易触碰到这种区域,这时用户将觉得页面很卡。

Google搜了一下,看来很多人都为这个问题而烦恼。有高人给出了解决方案,在这里可以找到。

代码如下:


myScroll = new iScroll('scrollpanel', {
    // other options go here...
    vScroll: false,
    onBeforeScrollStart: function ( e ) {
        if ( this.absDistX &gt; (this.absDistY + 5 ) ) {
            // user is scrolling the x axis, so prevent the browsers' native scrolling
            e.preventDefault();
        }
    }
});

重写onBeforeScrollStart事件,判断touch的滑动距离,只在横向滑动距离大于竖向滑动距离时

(也就是左右滑动时)才取消默认事件,这样就不影响页面滚动了。看iScroll源码,onBeforeScrollStart: function (e) { e.preventDefault(); }, 它默认是直接取消默认事件。

到这里的时候感觉就不错了。但是不要高兴的太早。

上下滑动横向滚动区域,页面确实可以滚动了,但在多体验了几次页面之后,又出现了一个问题。

先左右滑动该区域,滚动停止后再按住该区域想滚动页面,你会发现它还是不能滚动页面,

这时你再点击一次该区域,这时可以了。这相对于你需要触摸2次才能滚动页面, 这样的行为还是让人无法接受。

经过多翻测试,我把问题锁定到absDistX/Y上。最后发现,在左右滑动之后absDistX/Y的值不会重置,第二次滑动该区域时执行onBeforeScrollStart事件,里面absDistX/Y值是上一次的值,所以程序还是阻止了页面滚动。

解决方法如下:


myScroll = new iScroll('scrollpanel', {
    // other options go here...
    hScroll: true,
    onBeforeScrollStart: function ( e ) {
        if ( this.absDistX &gt; (this.absDistY + 5 ) ) {
            // user is scrolling the x axis, so prevent the browsers' native scrolling
            e.preventDefault();
        }
    },
    //解决第一次无法滑动的问题
    onTouchEnd: function () {
	var self = this;
	if (self.touchEndTimeId) {
		clearTimeout(self.touchEndTimeId);
	}

	self.touchEndTimeId = setTimeout(function () {
		self.absDistX = 0;
		self.absDistY = 0;
	}, 600);
    }
});

在onTouchEnd里面做处理,每次滑动之后都重置absDistX/Y的值。为什么要使用setTimeout?其实是为了防止误判断,太敏感也不好,有时候你只是想左右滑动虽然滑动的角度有点朝上或朝下。

Ok,现在终于爽了,想怎么滑都行。体验一下!

<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> 前端开发 | <span class="entry-utility-prep entry-utility-prep-tag-links">Tagged</span> , , | Leave a comment

前端开发利器——Koala v1.0正式发布

koala是一款开发者工具,负责对less、sass、coffeescript的编译工作,帮助web开发者更高效地使用less、sass、coffeescript开发。

项目地址:http://koala-app.com

功能特性:
  • 多语言支持:支持less、sass、coffeescript 和 compass framework。
  • 实时编译:监听文件,当文件改变时自动执行编译,这一切都在后台运行,无需人工操作。
  • 编译选项:可以设置各个语言的编译选项。
  • 代码压缩:less & sass支持编译后自动代码压缩.
  • 错误提示:在编译时如果遇到语法的错误,koala将在右下角弹出错误信息,方便开发者定位代码错误位置。
  • 跨平台:windows、linux、mac都能完美运行。

 

项目当中越来越多地使用到less,现有的一些工具如winless、simpless功能都比较单一,无法满足开发要求,所以干脆就自己写了一个。

koala是基于nodejs + webkit开发而成,大部分人都无法想到nodejs也能用来开发桌面应用,事实告诉我们是可以的。

这里有一个非常棒的项目,它结合了node与webkit,使用node做为后端处理语言,webkit做为前端界面,这样简直是天作之合,现在前端开发者也能开发桌面应用了。node webkit项目地址:https://github.com/rogerwang/node-webkit

<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> WEB技术 | Leave a comment

如何调试less & sass

很多同学都已经开始在项目使用lesssass,它们用起来确实是很爽,大大提高效率呀。

less & sass 都无法在浏览器中直接执行,需要变成CSS。有时候想调试样式,我们看到的行号是css代码的行号,并不能直接对应到less&sass文件中,修改起来总是不方便。

看到less&sass这么受欢迎,热情的开发者们给firefox开发了一个插件 FireSass,后来chrome也跟上了,开启一个实验性功能支持sass调试。

具体设置如下:

编译时添加参数:

sass开启debug-info选项:sass demo.sass demo.css –debug-info

less开启line-numbers:lessc demo.less demo.css –line-numbers=comments

这样,编译后的css中将包含调试信息:

 

浏览器设置:

firefox执行安装FireSass即可。

chorme:地址栏打开chrome://flags/,启用开发者工具实验 (Developer Tools experiments.)。重启浏览器后,打开开发者工具的设置选项卡,Experiments -> Support for sass 勾选。

 

最终调试效果:

less & sass 在官网上只提供命令行的方式编译文件,这实在是太低效了。这里向大家推荐一款工具来帮助我们后台自动编译less & sass。

Koala项目地址:http://koala-app.com/index-zh.html

koala是一款开发者工具,负责对less、sass、coffeescript的编译工作,帮助web开发者更高效地使用less、sass、coffeescript开发。

功能特性:
多语言支持:支持less、sass、coffeescript 和 compass framework。
实时编译:监听文件,当文件改变时自动执行编译,这一切都在后台运行,无需人工操作。
编译选项:可以设置各个语言的编译选项。
代码压缩:less & sass支持编译后自动代码压缩.
错误提示:在编译时如果遇到语法的错误,koala将在右下角弹出错误信息,方便开发者定位代码错误位置。
跨平台:windows、linux、mac都能完美运行。

 

如何在Koala中开启调试信息参数:

点击文件元素,在右侧展开的面板中勾选debug info选项。

 

 

 

 

<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> Koala | <span class="entry-utility-prep entry-utility-prep-tag-links">Tagged</span> | Leave a comment