logolomo http://www.logolomo.com Infinity & Creativity Mon, 07 Feb 2011 16:12:49 +0000 en hourly 1 http://wordpress.org/?v=3.0.4 关于UI设计你需要自问的12个问题 http://www.logolomo.com/2010/10/design/ui-questions.html http://www.logolomo.com/2010/10/design/ui-questions.html#comments Thu, 28 Oct 2010 04:01:32 +0000 Eric Tsui http://www.logolomo.com/?p=1708   UI 设计的魅力在于,你不仅需要适当的技巧,更要理解用户与程序的关系。一个有效的用户界面关注的是用户目标的实现,包括视觉元素与功能操作在内的所有东西都 需要完整一致。为了实现这个目标,你需要问自己 10 个最基本的问题。

1. 你的 UI 是否高度一致?
 

 
  用户来到你的站点,脑子里会保持着一种思维习惯,你的 UI 需要保持一致,以免用户的思维方向被打乱。比如,如果你的某个品目下的产品可以拖放到购物车,那你站点中所有产品都应该可以这样操作。将按钮放到不同页面 相似的位置,使用相契合的配色,使用一致的语法和书写习惯,同时,让你的页面拥有一致的结构。
 
2.用户能自由掌控自己的操作吗?
 
 
  你应当分析一下,自己的站点是否容易导航。用户应当可以自由掌控自己的浏览行为,确保他们能从某个地点跳出,能够毫无障碍地退出。那些在用户离开前 弹出窗口的行为是 UI 易用性的一个大问题。
 
3.你知道谁是你的用户群吗?
 
 
  要设计有效的 UI,必须对你的用户群有所了解,不同的用户阶层对不同的设计元素有不同的理解,17~25 岁年龄段的人,和 40~55 年龄断的人有不同的喜好。你的 UI 设计必须针对你的用户群进行设计。
 
4.你是否有足够的预防错误的措施?
 
 
  应该尽可能检查程序中的错误和 BUG,虽然你可以弹出一个窗口告诉用户发生了什么,但为了更好的用户体验,最好减少这些东西。Beta 测试是消减错误的最好方法。
 
 
5.你是否首先将最重要的东西展示给用户?
 
 
  将重点放在重要的内容上面,首先为用户展示最重要的内容,以便用户更好地理解你的内容。
 
6.你的设计是否简约?
 
 
  很多站点的设计十分简约,简约设计可以增强 UI 的易用性,可以让用户不必关心那些无关的信息。你的 UI 应该是这样的,它的功能很强大,但设计很简约,拥挤的界面,不管功能多么强大,都会吓跑用户。
 
7.你是否使用了视觉提示?
 
 
  如果你使用了 Ajax, Flash 一类的技术,当内容在加载的时候,应当提供视觉提示,应当始终让用户知道目前在做什么。
 
8.你的 UI 是否有操作提示?
 
 
  你的用户是否靠自己研究或 FAQ 文档学习如何操作?你应当在 UI 现场提供简单的操作提示,比如,使用 jQuery 在你的各个 UI 元素上显示操作提示。
 
 
9.你的内容是否清晰?
 
  确保你的文本准确,清晰,易懂。
 
10.你如何使用色彩?
 
 
  色彩是 UI 的重要元素,不同的颜色代表不同的情绪,你对色彩的使用应当和站点以及主题相契合。还应注意,有的用户是色盲,你应当考虑到他们的感受。色彩的使用应该一 致,一旦选定了某种配色,就应该在整个站点一致使用这种配色。
 
11.你的 UI 是否大象无形?
 
 
  UI Engineering 曾经说过,”最好的设计不是用来看的,是用来体验的”。这意味着,你的 UI 应该让用户去体验,而不是放一些花哨的东西给用户看。UI 设计越简单,用户体验越好,不要滥用设计元素,不要使用拥挤的界面。
 
12.你的 UI 是否有良好的结构?
 
 
 
  你的 UI 中,各个元素应当放在他们应当放的位置,总体结构应当清晰,一致,相互关联,那些不相关的东西应当单独放置。
 
  本文国际来源:spyrestudios.comDiving Into The User Interface With Fundamental Questions(原文作者:Joel Reyes)
      转载自: 优艾网
]]>
http://www.logolomo.com/2010/10/design/ui-questions.html/feed 0
开发基于FLARToolKit的增强现实(AR)基础教程(七) http://www.logolomo.com/2010/10/interactive/ar7.html http://www.logolomo.com/2010/10/interactive/ar7.html#comments Mon, 11 Oct 2010 12:27:58 +0000 Eric Tsui http://www.logolomo.com/?p=1703 Setting Up A Webcam(建立摄像头)

 

建立一个可以提供数据的摄像头比你想象得简单得多。在我们构建利用摄像头的文件的同时,我们将会提出如何切换debug模式开闭让我们从添加下面的方法开始:

/**
 * Creates a camera or emulator to use as the src for the ARDetector
 * to analyze for markers.
 *
 */
protected function createCamera():void
{
 	if(debug || !Camera.getCamera())
 	{
  		createEmulatorCard();
  	}
 	else
 	{
  		webcam = Camera.getCamera();
  		webcam.setMode(arDetector.width, arDetector.height, 30);
  		video = new Video(arDetector.width, arDetector.height);
  		video.attachCamera(webcam);
  	}
}

 

这个是用来检查debug模式是否激活或者是否有摄像头被检测到并且创建了CardEmulator。如果debug模式没被激活,我们创建了一个新的Camera实例并实例化了。video将会显示从摄像头来的视频流,所以我们将它匹配ARDetector的canvas的分辨率(320*240)并且将摄像头的实例附加给video。

声明的变量和导入的类包:

protected var debug:Boolean = false;
protected var webcam:Camera;
protected var video:Video;
import flash.media.Camera;
import flash.media.Video;

 

下一步在我们的init方法中将createEmulatorCard();替换为

createCaptureSource();
createCamera();

 

现在我们需要做的是移除cardEmulator.render()

public function renderViewport(event:Event = null):void
{
 	updateCaptureBitmap();

 	try
 	{
  		if (arDetector.detectMarker()) {
   			arDetector.calculateTransformMatrix(resultMat);
   			baseNode.setTransformMatrix(resultMat);
   			active();
   		}
  		else
  		{
   			inactive();
   		}
  	}
 	catch(errObject:Error) {
    		trace(errObject.message);
  	}

 	renderer.renderScene(scene, camera, viewport);
}

 

并改变我们的updateCaptureBitmap:

protected function updateCaptureBitmap():void
{
 	if(debug || !video)
 	{
  		cardEmulator.render();
  		capturedSrc.bitmapData.draw(cardEmulator.viewport);
  	}
 	else
 	{
  		capturedSrc.bitmapData.draw(video);
  	}
}

 

现在如果你编译你的程序你会被询问是否使用摄像头,点击确认之后就大功告成啦!!!

use_webcam
]]>
http://www.logolomo.com/2010/10/interactive/ar7.html/feed 0
开发基于FLARToolKit的增强现实(AR)基础教程(六) http://www.logolomo.com/2010/10/interactive/ar6.html http://www.logolomo.com/2010/10/interactive/ar6.html#comments Mon, 11 Oct 2010 12:27:01 +0000 Eric Tsui http://www.logolomo.com/?p=1699

Connecting The ARDetector To A Source

 

Connecting The ARDetector To A Source

下面的这几步会更快一些,你做得非常好,所以坚持下去因为这是我们最后的障碍。让我们向我们的渲染循环中添加标记检测逻辑。改变renderViewport方法:

public function renderViewport(event:Event = null):void
{
 	cardEmulator.render();
 	updateCaptureBitmap();

 	try
 	{
  		if (arDetector.detectMarker()) {
   			arDetector.calculateTransformMatrix(resultMat);
   			baseNode.setTransformMatrix(resultMat);
   			active();
   		}
  		else
  		{
   			inactive();
   		}
  	}
 	catch(errObject:Error) {
    		trace(errObject.message);
  	}



 	renderer.renderScene(scene, camera, viewport);
}

/**
 * Displays the base node when a marker has been found.
 */
protected function active():void
{
 	if(!isActive)
 	{
  		isActive = true;
  		baseNode.visible = true;
  	}
}

/**
 * Hides the base node when a marker can't be found.
 */
protected function inactive():void
{
 	if(isActive)
 	{
  		baseNode.visible = false;
  		isActive = false;
  	}
}
 

声明的变量和导入的类包:

protected var resultMat:FLARTransMatResult = new FLARTransMatResult();
protected var isActive:Boolean = false;
protected var baseNode:FLARBaseNode;
import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
import org.libspark.flartoolkit.pv3d.FLARBaseNode;

 

所以让我们来看一下发生了什么事情。每次我们调用renderViewport的时候我们会测试ARDetector是否检测到了标记,如果检测到了,那么我们要求ARDetector更新将要适用于baseNode的矩阵。baseNode将会显示主要的对象,并添加所有的papervision3d对象。下一步我们更新baseNode的图形信息(orientation)来匹配检测到的标记的图形信息。这些都是我们在使用FLARToolKit时该注意到的。如果这个标记仍然被探测到我们会调用active方法。Active简单地显示了baseNode。如果没有标记我们通过调用inactive来隐藏baseNode。

让我们通过改变setupPapervision方法来构建baseNode。

public function setupPapervision():void
{
 	scene = new Scene3D();
 	camera = new FLARCamera3D(arDetector.flarParam);

 	// Create the Viewport
 	viewport = new Viewport3D(stage.stageWidth, stage.stageHeight, true);
 	addChild(viewport);

 	// The base node is where all PV3D object should be attached to.
 	baseNode = new FLARBaseNode();
 	scene.addChild(baseNode);

 	create3dObjects();

 	renderer = new BasicRenderEngine();
}

这里我们创建了baseNode并把它添加到了scene中,同时,我们将摄像头改变成了FLARCamera3D,它需要一个flarParam属性来自于我们的ARDetector并将其放到正确的位置。

导入的类包:

import org.libspark.flartoolkit.pv3d.FLARCamera3D;
 

FlarParam是一个匹配检测到的标记的图形信息的矩阵,FLARCamera3d是由FLARToolKit继承下来的一个自定义类,它会用来更容易地通过flarParam的阈值来调整摄像头。

下一步我们需要更新我们的默认的Plane,让他附加到baseNode上,调整它的rotation以使他以正确的角度面对摄像头。改变create3dObjects方法:

protected function create3dObjects():void
{
 	var plane:Plane = new Plane( new WireframeMaterial(0xff0000), 80, 80 );
 	plane.rotationX = 180;
 	baseNode.addChild(plane);
}

 

我们做出来了!我们的ARDetector现在从CardEmulator正确地看到了我们的标记。你可以通过移动鼠标来体验!

flarvision_preview_3

注意到plane有时会消失么?这个是检测器失去标记然后使得baseNode不可见。为了便于举例我们如何将这个3d对象映射到仿真器的显示列表中,我们使captureSrc匹配了viewPort的大小。

protected function configureStage():void

{
stage.quality = StageQuality.HIGH;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(Event.RESIZE, onStageResize);
}

protected function onStageResize(event:Event = null):void
{
if(capturedSrc)
resize(capturedSrc, stage.stageWidth, stage.stageHeight);
if(viewport)
resize(viewport, stage.stageWidth, stage.stageHeight);
}

/**
* A function to resize any DisplayObject.
*
* @param target
* @param areaWidth
* @param areaHeight
* @param aspectRatio
*
*/
public function resize(target : DisplayObject, areaWidth : Number, areaHeight : Number, aspectRatio : Boolean = true, autoCenter:Boolean = true) : void {

if(aspectRatio) {

var sw : Number = areaWidth;
var sh : Number = areaHeight;
var tw : Number = target.width;
var th : Number = target.height;

var si : Number;
//
if(sw > sh) {
si = sw / tw;
if(th * si > sh)
si = sh / th;
}else {
si = sh / th;
if(tw * si > sw )
si = sw / tw;
}

var wn : Number = tw * si;
var hn : Number = th * si;

target.width = wn;
target.height = hn;
}else {
target.width = areaWidth;
target.height = areaHeight;
}

if(autoCenter)
{
target.x = ((areaWidth * .5) - (target.width * .5));
target.y = ((areaHeight * .5) - (target.height * .5));
}
}
导入的类包:
import flash.display.DisplayObject;

将下面的这条语句添加到createCaptureSource方法的最下方:

onStageResize();
 

下一步我们会用来自摄像头的video替换captureSrc,我们要做的一件事便是偏移viewport使得pv3d对象正确地布局在标记上。

flarvision_preview_4

]]>
http://www.logolomo.com/2010/10/interactive/ar6.html/feed 0
开发基于FLARToolKit的增强现实(AR)基础教程(五) http://www.logolomo.com/2010/10/interactive/ar5.html http://www.logolomo.com/2010/10/interactive/ar5.html#comments Mon, 11 Oct 2010 12:07:58 +0000 Eric Tsui http://www.logolomo.com/?p=1695 Creating a Capture Source(创建一个CaptureSource方法)

 

ARDetector将会扫描BitmapData来决定现在是否是有效的标记。我们在onActivate方法后添加下面的方法:

/**
 * Creates a Bitmap for us to scan for valid markers.
 *
 */
protected function createCaptureSource():void
{
 	capturedSrc = new Bitmap(new BitmapData(arDetector.width, arDetector.height, false, 0), PixelSnapping.AUTO, true);
 	arDetector.src = capturedSrc.bitmapData;
 	addChild(capturedSrc);
}

 

声明的变量和导入的类包:

protected var capturedSrc:Bitmap;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.PixelSnapping;

 

下一步我们将会在我们调用init之前调用这个方法。改变onActivate方法:

protected function onActivate(event:Event):void
{
 	createCaptureSource();
 	init();
}

 

下一个方法将会对我们的cardEmulator处理更新captureSrc的bitmapData。在renderViewport方法后添加如下代码:

/**
 * Updates the capturedSrc with new bitmap data.
 *
 */
protected function updateCaptureBitmap():void
{
 	capturedSrc.bitmapData.draw(cardEmulator.viewport);
}

 

注意到我们是如何由cardEmulator的viewport到capturedSrc画BitmapData了么?这种构建将会允许我们用用户的摄像头置换出cardEmulator。目前我们还有一些东西要添加来使得它工作起来。让我们继续在我们的渲染循环中调用updateCaptureBitmap。改变renderViewport方法:

public function renderViewport(event:Event = null):void
{
 	cardEmulator.render();
 	updateCaptureBitmap();
 	renderer.renderScene(scene, camera, viewport);
}

 

我们需要做的最后一件事情就是告诉仿真器它不用向它的显示列表添加viewport了,在构造函数中的第四个参数默认为false,所以让我们来改变createEmulatorCard方法中的一条line:

cardEmulator = new CardEmulator("images/flarlogo.gif", 320, 240, true);
变为:

 

cardEmulator = new CardEmulator("images/flarlogo.gif");

 

记住captureSrc现在直接从仿真器的viewport中取样BitmapData,所以不需要在CardEmulator中显示viewport,如果你现在正在运行,所有的都应该看上去一样除了仿真器正在绘制我们的captureSrc的bitmap。为了确保我们仅有一个显示对象被渲染你可以试着将captureSrc的x属性平移360px。如果你既看到了CardEmulator又看到了captureSrc,那么这个是错误的。

double_src_render_problem

非常好,我们现在已经捕捉到了源,我们的仿真器正在运行所以让我们将它连接到ARDetector.

]]>
http://www.logolomo.com/2010/10/interactive/ar5.html/feed 0
开发基于FLARToolKit的增强现实(AR)基础教程(四) http://www.logolomo.com/2010/10/interactive/ar4.html http://www.logolomo.com/2010/10/interactive/ar4.html#comments Mon, 11 Oct 2010 12:07:11 +0000 Eric Tsui http://www.logolomo.com/?p=1692

当我们在FLARVision文件类里构建这个类的时候我会重温重要的public function,这些方法需要你筹备和运行。其他的方法拥有注释来解释功能。在我们的FLARVision类中会用以下的两个方法来初始化我们的ARDetector。

/**
 * Creates the AR Detector class and have it load in the camera.data
 * and pattern.pat files.
 *
 */
protected function createFlarDetector():void
{
 	arDetector = new ARDetector();
 	arDetector.addEventListener(Event.COMPLETE, onActivate);
 	arDetector.setup('data/camera_para.dat', 'data/flarlogo.pat');
}

/**
 *
 */
protected function onActivate(event:Event):void
{
 	init();
}

 

同时添加变量声明和类包导入:

protected var arDetector:ARDetector;
import com.insideria.flar.ARDetector;

 

到目前为止,我们创建了一个ARDetector的实例,然后添加了一个事件监听器来监听camera.data和pattern.pat加载完成的事件。我们也添加了一个onActivate方法来调用init。在我们想要运行之前我们需要稍微改变一下我们的构造:

public function FLARVision()
{
 	configureStage();
 	createFlarDetector();
}

 

现在如果你运行了,并查看浏览器中的链接你会看到除了两个附加的文件被加载,没有任何事情发生。

files_loading

下一步我们连接到ARDetector。

]]>
http://www.logolomo.com/2010/10/interactive/ar4.html/feed 0
开发基于FLARToolKit的增强现实(AR)基础教程(三) http://www.logolomo.com/2010/10/interactive/ar3.html http://www.logolomo.com/2010/10/interactive/ar3.html#comments Mon, 11 Oct 2010 12:02:11 +0000 Eric Tsui http://www.logolomo.com/?p=1690 Creating An AR Detector(创建一个AR检测器)

 

当尝试了其他的一些关于FLARToolKit的例子后很容易忘记它是如何工作的。当我一行一行地分析代码才发现了它是如何构建的。我经常努力地去创建简单的,独立的类,并且可以轻松地重用和扩展。这就是我将FLARToolKit的构建密封到我们自己的叫做ARDetector类中的原因。让我们一同来创建这个类。

/**
 * Original Author:  Jesse Freeman
 * Class File: ARDetector.as
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * Revisions
 * 		1.0  Initial version April 29, 2009
 *
 */

package com.insideria.flar{



 	import flash.display.BitmapData;
 	import flash.events.Event;
 	import flash.events.EventDispatcher;
 	import flash.events.IEventDispatcher;
 	import flash.events.IOErrorEvent;
 	import flash.events.SecurityErrorEvent;
 	import flash.net.URLLoader;
 	import flash.net.URLLoaderDataFormat;
 	import flash.net.URLRequest;

 	import org.libspark.flartoolkit.core.FLARCode;
 	import org.libspark.flartoolkit.core.param.FLARParam;
 	import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
 	import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
 	import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;

 	/**
 	 * The ARDetector is a manager for the FLARToolKit and helps facilitate
 	 * the setup, configuration, and detection of markers while using the
 	 * FLARToolKit's underlining core classes.
 	 *
 	 * This class is a modification of an example on
 	 * http://saqoosha.net/en/flartoolkit/start-up-guide
 	 *
 	 *
 	 * @author Jesse Freeman
 	 *
 	 */
 	public class ARDetector extends EventDispatcher{

  		protected var cameraURL:String;
  		protected var markerURL:String;
  		protected var codeWidth:int;
  		protected var _flarParam:FLARParam;
  		protected var code:FLARCode;
  		protected var raster:FLARRgbRaster_BitmapData;
  		protected var detector:FLARSingleMarkerDetector;

  		public var width:int;
  		public var height:int;
  		public var markerWidth:Number = 16;
  		public var markerHeight:Number = 16;

  		/**
  		 *
  		 * This is the ARDetector consturctor. By default we set the width and
  		 * height to 320 x 240 to match our video source.
  		 *
  		 * @param canvasWidth set to 320 by default
  		 * @param canvasHeight set to 240 by default
  		 * @param codeWidth set to 80 by default. This represents the width of the marker.
  		 *
  		 */
  		public function ARDetector(canvasWidth:int = 320, canvasHeight:int = 240, codeWidth:int = 80) {
   			width = canvasWidth;
   			height = canvasHeight;
   			this.codeWidth = codeWidth;
   		}

  		/**
  		 * This will return an instance of the FLARParam.
  		 *
  		 */
  		public function get flarParam():FLARParam
  		{
   			return _flarParam;
   		}

  		/**
  		 * This sets the BitmapData src to be monitored for patterns.
  		 *
  		 */
  		public function set src(target:BitmapData):void
  		{
   			// setup ARToolkit
   			raster = new FLARRgbRaster_BitmapData(target);
   			detector = new FLARSingleMarkerDetector(_flarParam, code, codeWidth);
   		}

  		/**
  		 * @private
  		 *
  		 * Loads in the camera.dat file. This file contains information about
  		 * the webcam.
  		 *
  		 * @param url path to camera.dat file.
  		 *
  		 */
  		protected function loadCameraFile(url:String):void
  		{
   			var camLoader:URLLoader = new URLLoader();
   				camLoader.dataFormat = URLLoaderDataFormat.BINARY;

   			camLoader.addEventListener(Event.COMPLETE, onCameraFileLoad, false, 0, true);
   			addErrorListeners(camLoader);

   			camLoader.load(new URLRequest(url));	

   		}

  		/**
  		 * @private
  		 *
  		 * Triggered on a successful camera.dat file load. Once a complete
  		 * event is received we remove the listeners, create a new FLARParam,
  		 * and set it's screen size. Finally we load the marker.
  		 *
  		 * @param event
  		 *
  		 */
  		protected function onCameraFileLoad(event:Event):void
  		{
   			event.stopImmediatePropagation();

   			var target:URLLoader = event.target as URLLoader;

   			target.removeEventListener(Event.COMPLETE, onCameraFileLoad);
   			removeErrorListeners(target);

   			_flarParam = new FLARParam();
   			_flarParam.loadARParam(target.data);
   			_flarParam.changeScreenSize(width, height);

   			loadMarkerFile(markerURL);
   		}

  		/**
  		 * @private
  		 *
  		 * This loads the marker.pat file. The marker represents the image we
  		 * look for from the src BitmapData.
  		 *
  		 */
  		protected function loadMarkerFile(url:String):void
  		{
   			var patLoader:URLLoader = new URLLoader();
   				patLoader.dataFormat = URLLoaderDataFormat.TEXT;

   			patLoader.addEventListener(Event.COMPLETE, onMarkerFileLoad, false, 0, true);
   			addErrorListeners(patLoader);

   			patLoader.load(new URLRequest(url) );
   		}

  		/**
  		 * @private
  		 *
  		 * Triggered when a marker.pat file is loaded. We remove the listeners
  		 * create a new 16x16 FLARCode instance, and pass in the pattern. This
  		 * represents the resolution of your marker. By default 16x16 works for
  		 * lower detailed patterns. After this the ARDetector is configured and
  		 * dispatches a Complete event.
  		 *
  		 * @param event
  		 *
  		 */
  		protected function onMarkerFileLoad(event:Event):void
  		{
   			event.stopImmediatePropagation();

   			var target:URLLoader = event.target as URLLoader;

   			target.removeEventListener(Event.COMPLETE, onCameraFileLoad);
   			removeErrorListeners(target);

   			code = new FLARCode(markerWidth, markerHeight);
   			code.loadARPatt(target.data);

   			dispatchEvent(new Event(Event.COMPLETE, true, true) );
   		}

  		/**
  		 * @private
  		 *
  		 * Adds error event listeners and re-dispatches them once received.
  		 *
  		 */
  		protected function addErrorListeners(target:IEventDispatcher):void
  		{
   			target.addEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);
   			target.addEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);
   		}

  		/**
  		 * @private
  		 *
  		 * Removes error event listeners.
  		 *
  		 */
  		protected function removeErrorListeners(target:IEventDispatcher):void
  		{
   			target.removeEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);
   			target.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);
   		}

  		/**
  		 * In order to set up the FLARDetector we will need two things: the
  		 * camera.dat and the marker.pat files. The camera.dat
  		 *
  		 * @param cameraURL this is the path to the camera.dat file.
  		 * @param markerURL this is the path to the marker.pat file.
  		 *
  		 */
  		public function setup(cameraURL:String, markerURL:String):void {
   			this.cameraURL = cameraURL;
   			this.markerURL = markerURL;
   			loadCameraFile(cameraURL);
   		}

  		/**
  		 *
  		 * This calculates the transformation Matrix to match the found
  		 * marker's coordinates.
  		 *
  		 * @param resultMat - a type of matrix that can be used to store values
  		 * of the detected marker's orientation.
  		 *
  		 */
  		public function calculateTransformMatrix(resultMat:FLARTransMatResult):void
  		{
   			detector.getTransformMatrix(resultMat);
   		}

  		/**
  		 *
  		 * This validates if we have found a marker from the set src (raster).
  		 * It returns a true/false based on the supplied values. You must supply
  		 * a source for this to work correctly.
  		 *
  		 * @param threshold The threshold value to be used for detecting the marker.
  		 * @param confidence This is how confident the detector is that it found
  		 * a marker.
  		 *
  		 */
  		public function detectMarker(threshold:int = 90, confidence:Number = .5):Boolean
  		{
   			return (detector.detectMarkerLite(raster,threshold) && detector.getConfidence() > confidence)
   		}

  	}
}
]]>
http://www.logolomo.com/2010/10/interactive/ar3.html/feed 0
开发基于FLARToolKit的增强现实(AR)基础教程(二) http://www.logolomo.com/2010/10/interactive/ar2.html http://www.logolomo.com/2010/10/interactive/ar2.html#comments Mon, 11 Oct 2010 12:00:55 +0000 Eric Tsui http://www.logolomo.com/?p=1687 FLAR Pattern Emulator(模型仿真)

 

在我们被构建摄像机和FLARToolKit搞疯之前,我们需要创建一个测试的环境。这个有很多好处:

1、我们构建一个预测的环境是我们的创意原型显示。

2、通过创建一个测试环境我们可以非常容易地协调我们的程序而不用任何的从属关系。

3、有一个可靠地debug模式可以辅助验证我们代码的稳定性,并在做实时测试时排除了表面错误。

4、用摄像头测试是个痛苦的过程。每次你重新编译你的工程拟不得不接收使用摄像头的许可。用debug模式你可以建立出任何事物,当你知道所有都正常的时候你可以进行最后的摄像头测试。

所以仿真器将做什么?像我们前面讨论的一样,我们需要一个标记去解析。这个仿真器将会用我们的测试标记创建一个简单的3d plane。我们也会使用鼠标在3d空间内来旋转我们的虚拟卡片来模仿用户通过摄像头将做的交互。所以让我们来创建一个叫做CardEmulator的类。

/**
 * Original Author:  Jesse Freeman
 * Class File: CardEmulator.as
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * Revisions
 * 		1.0  Initial version April 29, 2009
 *
 */

package com.insideria.flar
{
 	import flash.display.Sprite;

 	import org.papervision3d.cameras.Camera3D;
 	import org.papervision3d.materials.BitmapFileMaterial;
 	import org.papervision3d.objects.primitives.Plane;
 	import org.papervision3d.render.BasicRenderEngine;
 	import org.papervision3d.scenes.Scene3D;
 	import org.papervision3d.view.BitmapViewport3D;

 	/**
 	 *	The CardEmulator represent a simple system for testing an AR Marker with
 	 * needing to use a webcam as a source. This class creates an instance of a
 	 * Papervision 3D renderer, viewport and scene with a simple 3d plane skinned
 	 * with a texture of your marker. When render is called the mouse is tracked
 	 * and the plane is adjusted to test your pattern at different angles.
 
 	 *
 	 * This since this class requires a reference to stage for the mouse
 	 * calculations you must attach it to the stage or another display object.
 	 * In cases when you don't want to see the viewport you can optionally toggle
 	 * addViewportToDisplay in the constructor.
 	 *
 	 * @author Jesse Freeman
 	 *
 	 */
 	public class CardEmulator extends Sprite
 	{

  		protected var _width:Number = 0;
  		protected var _height:Number = 0;
  		protected var testMarkerURL:String;
  		protected var emulatorViewport:BitmapViewport3D;
  		protected var emulatorRenderer:BasicRenderEngine;
  		protected var emulatorScene:Scene3D;
          protected var emulatorCamera:Camera3D;
          protected var testCard:Plane;
  		protected var addViewportToDisplay:Boolean = false;

          /**
           * Returns an instance of the viewport as a BitmapViewport3d object.
           *
           * @return BitmapViewport3D and can be used to sample BitmapData from.
           *
           */
          public function get viewport():BitmapViewport3D
          {
           	return emulatorViewport;
           }

  		/**
  		 *  Constructs the emulator environment. We need a url to the test
  		 * marker, a width and a height.
  		 *
  		 * @param testMarkerURL loads in a sample test marker image.
  		 * @param w width of the emulators display - default 320.
  		 * @param h height of the emulators display - default 240.
  		 * @param addViewportToDisplay tells the emulator if it should attach
  		 * the viewport to the display or not. In most cases you would not want
  		 * to set this to true unless you are testing that the Emulator is
  		 * actually displaying and working.
  		 *
  		 */
  		public function CardEmulator(testMarkerURL:String, w:Number = 320, h:Number = 240, addViewportToDisplay:Boolean = false)
  		{
   			this.testMarkerURL = testMarkerURL;
   			_width = w;
   			_height = h;
   			this.addViewportToDisplay = addViewportToDisplay;
   			init();
   		}

  		/**
  		 * @private
  		 *
  		 * On init we create the emulators viewport, render scene and camera.
  		 * We also attach a testCard (plane) to the scene to act as our sample
  		 * pattern.
  		 *
  		 */
  		protected function init():void
  		{
   			// Setup PV3D
   			emulatorViewport = new BitmapViewport3D(_width, _height);
              	emulatorRenderer = new BasicRenderEngine();
               emulatorScene = new Scene3D();
               emulatorCamera = new Camera3D();

   			// Create test pattern plane
   			var bmpMaterial:BitmapFileMaterial = new BitmapFileMaterial(testMarkerURL, true);
   				bmpMaterial.doubleSided = true;

   			testCard = new Plane(bmpMaterial, 300, 300, 4, 4);

   			// Make the camera face the testCard
   			emulatorCamera.target = testCard;
   			emulatorScene.addChild( testCard );

   			// Make sure we should add this to the display
   			if(addViewportToDisplay)
   				addChild(emulatorViewport);
   		}

  		/**
  		 *
  		 * Here we take the mouse's movement and rotate the camera
  		 * accordingly. This assumes that the CardEmulator instance has a
  		 * reference to the stage.
  		 *
  		 */
  		protected function calculateMouseMovement():void
  		{
   			if(stage)
   			{
    				var rotY: Number = (mouseY-(stage.stageHeight/2))/(stage.height/2)*(2200);
    				var rotX: Number = (mouseX-(stage.stageWidth/2))/(stage.width/2)*(-2200);
    				emulatorCamera.x = emulatorCamera.x + (rotX - emulatorCamera.x) / 2;
    				emulatorCamera.y = emulatorCamera.y + (rotY - emulatorCamera.y) / 2;
    			}
   		}

  		/**
  		 *
  		 * When a render is called we calculate the mouseMovement then render
  		 * out the scene.
  		 *
  		 */
  		public function render():void
  		{
   			calculateMouseMovement();
   			emulatorRenderer.renderScene(emulatorScene, emulatorCamera, emulatorViewport);
   		}
  	}
}

 

这个类和我们构建的文件类一样简单,值得注意的是我们使用一个BitmapViewport3D,使得我们今后可以很轻松地通过它加载BitmapData。同时,我们创建了一个Plane并添加了BitmapFileMaterial纹理。我们要做的最后一件事是render方法和calculateMouseMovement方法。注意到这两个方法为什么没有EnterFrame监听器来运行渲染?因为这个方法将要被FLARVision外部调用,而FLARVision有自己的render方法。通过这种方法我们保证渲染循环最简化。这种方法尤其适用于同时有两个papervision的实例的情况。

现在我们来在FLARVision文件类中构建,在create3dObjects方法后添加下列方法

/**
 * Creates the emulator card to use in debug mode.
 *
 */
protected function createEmulatorCard():void
{
 	cardEmulator = new CardEmulator("images/flarlogo.gif", 320, 240, true);
 	addChild(cardEmulator);
}

 

同时添加变量和导入类包:

protected var cardEmulator:CardEmulator;
import com.insideria.flar.CardEmulator;

 

在我们测试我们的仿真器工作之前,让我们改变我们的init方法:

protected function init():void {
 	createEmulatorCard();
 	setupPapervision();
 	addEventListener(Event.ENTER_FRAME, renderViewport);
}

 

同时改变我们的renderViewport来调用CardEmulator的render方法:

public function renderViewport(event:Event = null):void
{
 	cardEmulator.render();
 	renderer.renderScene(scene, camera, viewport);
}

 

在你编译之前需要注意到你应该拷贝一份data和images文件夹到FLARVision的html-template文件夹或者你存放你编译的swfs文件的地方。你可以从工程中获得资源包。一旦你这样做了,你可能需要清理你的工程(Project -> clean …)的bin目录。

如果你编译成功你将会在屏幕的左上角看到我们的测试仿真模拟器当移动出表的时候,这个测试仿真会跟随着旋转。

flarvision_preview_2

(这里有可能会遇到一个安全沙箱错误,不过我们都知道flex的debug模式不用理会沙箱问题,当你部署到服务器上才会遇到,我还没去做部署,所以先不翻译,有兴趣可看原文。)

需要注意的是我们仅仅使测试仿真达到320*240的分辨率。当我们更深入教程的时候我们会注意到当运行FLARToolKit的时候性能会降低。AR对与Flash来说仍然是新生的,不成熟的代码决定了仿真的大小需要受到限制。与之相对应的,我们经常以320*240的分辨率从video源取样。这将会提高性能并且得到可能最佳的结果。接下来我们会向未伸缩的源图片添加些代码,但是让我们先来看看如何构建FLARToolKit.

]]>
http://www.logolomo.com/2010/10/interactive/ar2.html/feed 0
开发基于FLARToolKit的增强现实(AR)基础教程(一) http://www.logolomo.com/2010/10/interactive/1683.html http://www.logolomo.com/2010/10/interactive/1683.html#comments Mon, 11 Oct 2010 11:59:26 +0000 Eric Tsui http://www.logolomo.com/?p=1683 转载至:

增强现实的基本解释是:在真实环境上实时地附加图形。在Flash中,经常使用一个摄像头和一个标记卡片来实现。当你将有标记的卡片对准摄像头的时候,Flash程序可以检测到这个卡片的基本图形信息并将一个3d模型附加之上。这个技术在flash中实现是非常令人兴奋地。尽管它仍然在开发初期,但随着时间的推移,AR将会很可能在我们体验web的过程中扮演重要的角色。现在是一个踏入这个领域的绝佳时期,最好了解它的工作原理。

围绕着AR有很多的Flash应用,随便在哪都有AR的入门教程(这个在贵国有待发展……)。事实上这篇文章是我用来作为起步学习的,对于初学者的好处在于这个教程已经准备好了一系列封装了FLARToolKit的类文件。同时我们创建了debug模式,当你不用摄像头时用来测试你的标记。对教程的大致浏览可能会令人畏缩,但是我会详细地讲解构建的每一个细节step by step。

然而,如果你不想读过长的教程或者你只想阅读教程的最后部分,我建议下载Final Demo文件来check out。我的代码注释可以使你知道这一切都是如何运做的。

在我们开始之前,有一些术语你需要熟悉:

FLARToolKit:我们将要在我们的工程中使用并实现AR的类库。这个类是由Saqoosha编写,以NyARToolKit 2.0.0为基础。现在它已经是开源的。

pv3d:papervision3d的缩写,这个是实时的3d引擎,也是开源项目。

FLARVision:我们将要创建的Demo的名字。

camera_para.dat是FLARToolKit将引用的一个二进制文件,其中记录了摄像头的设置和配置信息。

Marker or Pattern:FLAR将会分析和计算它的图形信息(orientation)。这个图形需要包含黑色边框和内侧的图形。你需要它来使AR工作起来。

CardEmulator:是一个简易的类,当你无法使用摄像头的时候(或者其他的情况下)用来模仿真实的标记卡片。我们将会通过鼠标移动来仿真一个人拿着卡片向着摄像头来回移动。

现在你已经熟悉了这些术语,现在让我们来看看最后的效果:

flarvision_demo

安装papervision3d和FLARToolKit(略)

当用svn检出http://www.libspark.org/svn/as3/FLARToolKit/trunk时,lib包内是大量的文件夹形式的文件,如果你建立的是flex工程,请下载.swc格式的papervision和。

Creating our Doc Class(创建我们的文件类):

 

现在我们要创建一个新的ActionScript工程叫做FLARVision。你需要将papervision和FLARToolKit工程添加到FLARVision的Library Path中。

我们要做的第一件事是构建一个简单的文件类。这个类将是你想要利用papervision和FLARToolKit创建的任何工程的基础。我已经构造了它,所以当你建立自己的FLAR工程的时候便会很容易通过重写核心的方法扩展它。让我们来看一看:

/**
 * Original Author:  Jesse Freeman
 * Class File: FLARVision.as
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * Revisions
 * 		1.0  Initial version April 29, 2009
 *
 */

package
{
 	import flash.display.Sprite;
 	import flash.display.StageAlign;
 	import flash.display.StageQuality;
 	import flash.display.StageScaleMode;
 	import flash.events.Event;

 	import org.papervision3d.cameras.Camera3D;
 	import org.papervision3d.materials.WireframeMaterial;
 	import org.papervision3d.objects.primitives.Plane;
 	import org.papervision3d.render.BasicRenderEngine;
 	import org.papervision3d.scenes.Scene3D;
 	import org.papervision3d.view.Viewport3D;

 	/**
 	 *
 	 * @author Jesse Freeman
 	 *
 	 */
 	public class FLARVision extends Sprite
 	{
  		protected var scene:Scene3D;
  		protected var camera:Camera3D;
  		protected var viewport:Viewport3D;
  		protected var renderer:BasicRenderEngine;

  		/**
  		 * Main Constructor for the class.
  		 *
  		 */
  		public function FLARVision()
  		{
   			configureStage();
   			init();
   		}

  		/**
  		 * Configures the stage and sets the scale mode to keep visuals from
  		 * distorting when resizing the browser window.
  		 *
  		 */
  		private function configureStage():void
          {
              	stage.quality = StageQuality.HIGH;
               stage.align = StageAlign.TOP_LEFT;
               stage.scaleMode = StageScaleMode.NO_SCALE;
           }

  		/**
  		 * Called at the construction of the class. Calls the setup Papervision
  		 * method and adds an event listener to the render the Viewport.
  		 *
  		 */
  		protected function init():void {
   			setupPapervision();
   			addEventListener(Event.ENTER_FRAME, renderViewport);
   		}

  		/**
  		 * Sets up and configures Papervision. This function can be overridden
  		 * to accommodate any custom set ups you may need for your project.
  		 *
  		 */
  		public function setupPapervision():void
  		{
   			scene = new Scene3D();
   			camera = new Camera3D();

   			// Create the Viewport
   			viewport = new Viewport3D(stage.stageWidth, stage.stageHeight);
   			addChild(viewport);

   			create3dObjects();

   			renderer = new BasicRenderEngine();
   		}

  		/**
  		 * This default function is where 3d Objects should be added to PV3D's
  		 * scenes.
  		 *
  		 */
  		protected function create3dObjects():void
  		{
   			var plane:Plane = new Plane( new WireframeMaterial(0xff0000) );
   			scene.addChild(plane);
   		}

  		/**
  		 * Renders the papervision scene.
  		 * @param event
  		 *
  		 */
  		public function renderViewport(event:Event = null):void
  		{
   			renderer.renderScene(scene, camera, viewport);
   		}

  	}
}
flarvision_preview_1

 

(这个类papervision已经构造好了叫做BasicView,相信经常做pv3d的朋友早就知道。而这个逐帧渲染的方法并不是一个很好的方法,由于pv3d非常占用资源,所以我们有时需要手工地stopRendering()和startRendering())。

(关于papervision3d的基础我不翻译,如果不熟悉的童鞋请移步)。

]]>
http://www.logolomo.com/2010/10/interactive/1683.html/feed 0
30个清新富有创意的wordpress主题设计欣赏 http://www.logolomo.com/2010/10/design/30wordpresstheme.html http://www.logolomo.com/2010/10/design/30wordpresstheme.html#comments Tue, 05 Oct 2010 13:29:08 +0000 Eric Tsui http://www.logolomo.com/?p=1649 wordpress社区是很多欧美网页设计师们经常光顾的地方,wordpress的追随者们也喜欢发布自己的设计,这其中不乏许多非常优秀的网页设计作品。wordpress的主题设计一般都是设计师们随心之作,所以不同于许多商业做作品的种种局限,wordpress主题很多在创意上都是有很多新意的。因此我们专门从国外网站上找了这么一篇文章,目的是给大家网页设计的创意提供一些有新思路的闪光的创意参考。

1. BEEW

wpress1 30个清新富有创意的wordpress主题设计欣赏

2. Dreams Media

wpress2 30个清新富有创意的wordpress主题设计欣赏

3. 

wpress3 30个清新富有创意的wordpress主题设计欣赏

4. 

wpress4 30个清新富有创意的wordpress主题设计欣赏

5. 

wpress5 30个清新富有创意的wordpress主题设计欣赏

6. 

wpress6 30个清新富有创意的wordpress主题设计欣赏

7. 

wpress7 30个清新富有创意的wordpress主题设计欣赏

8. 

wpress8 30个清新富有创意的wordpress主题设计欣赏

9. 

wpress9 30个清新富有创意的wordpress主题设计欣赏

10. 

wpress10 30个清新富有创意的wordpress主题设计欣赏

11. 

wpress11 30个清新富有创意的wordpress主题设计欣赏

12. 

wpress12 30个清新富有创意的wordpress主题设计欣赏

13. 

wpress13 30个清新富有创意的wordpress主题设计欣赏

14. 

wpress14 30个清新富有创意的wordpress主题设计欣赏

15. 

wpress15 30个清新富有创意的wordpress主题设计欣赏

16. 

wpress16 30个清新富有创意的wordpress主题设计欣赏

17. 

wpress17 30个清新富有创意的wordpress主题设计欣赏

18. 

wpress18 30个清新富有创意的wordpress主题设计欣赏

19. 

wpress19 30个清新富有创意的wordpress主题设计欣赏

20. 

wpress20 30个清新富有创意的wordpress主题设计欣赏

21. 

wpress21 30个清新富有创意的wordpress主题设计欣赏

22. 

wpress22 30个清新富有创意的wordpress主题设计欣赏

23. 

wpress23 30个清新富有创意的wordpress主题设计欣赏

24. 

wpress24 30个清新富有创意的wordpress主题设计欣赏

25. 

wpress25 30个清新富有创意的wordpress主题设计欣赏

26. 

wpress26 30个清新富有创意的wordpress主题设计欣赏

27. 

wpress27 30个清新富有创意的wordpress主题设计欣赏

28. 

wpress28 30个清新富有创意的wordpress主题设计欣赏

29. 

wpress29 30个清新富有创意的wordpress主题设计欣赏

30. 

wpress30 30个清新富有创意的wordpress主题设计欣赏

]]>
http://www.logolomo.com/2010/10/design/30wordpresstheme.html/feed 0
Windows Phone 7 -UI设计入门 http://www.logolomo.com/2010/10/design/windows-phone-7-ui.html http://www.logolomo.com/2010/10/design/windows-phone-7-ui.html#comments Tue, 05 Oct 2010 04:35:47 +0000 Eric Tsui http://www.logolomo.com/?p=1640          在Windows Phone 7(简称WP7)开发环境与工具这篇文章中,介绍了使用Windows Phone Developer Tools Beta (WPDT Beta)来开发WP7的应用程序。不管是使用WPDT Beta开发Windows Phone应用程序,还是开发Windows Phone上的Silverlight应用程序和XNA 游戏程序,一个良好的用户界面(User Interface,UI)是开发Windows Phone应用程序的第一关。
         我们从未停止过追求美丽事物的步伐,也从未停止过设计出更美、更炫的产品出来。拿微软来说,从Dos6.2到Windows 3.1、Windows 98、Windows XP以及2009年发布的Windows 7,用户界面越来越美观、漂亮,颜色越来越丰富,操作越来越方便,功能也越来越强大。这是微软不断追求用户体验的结果。在这篇文章中,将给大家介绍Windows Phone 7 UI设计中的几个重要问题,分成三个部分来介绍:Windows Phone 7 UI设计特色、Windows Phone 7 UI设计原则、Windows Phone 7应用程序控件。
 

Windows Phone 7 UI设计特点
         在介绍WP7 UI设计特色之前,简单介绍一下UI设计及特点。
UI设计 (UI Design)是与交互设计(interactive design)、可用性研究(usability research)、人力因素(human factors)、信息结构工程师(information architect)相互联系又各有侧重的一些概念和职业,这里我们不去深究。UI设计着重体现人机交互、操作逻辑和界面美观三个方面。
UI设计更重要的是要理解用户与程序的关系。一个良好的用户界面关注的是用户目标的实现,包括视觉元素与功能操作在内的所有东西都需要完整一致。
         WP7 中的UI设计也着重体现人机交换、操作逻辑和界面美观三个方面,具体说来有以下几个特点:
         特点一:多种输入方式,为触摸而设计
         WP 7的用户界面有四种输入方式:触摸手势、虚拟键盘、WP 7的硬件按钮和传感器。触摸手势是单指或者多个指头在触摸屏上进行一些移动。触摸手势是用户和WP 7进行交互的主要方式,支持的触摸有两种:单点触摸和多点触摸,其中单点触摸的手势有:单击、双击、平移、划动、长按;多点触摸的手势有:缩放。
         特点二:三种屏幕方向
WP 7支持三种类型的屏幕方向:竖屏,向左的横屏和向右的横屏。向左横屏和向右横屏之间的区别是应用程序工具栏和系统托盘的方位不一样。应用程序不能指定只是支持向左横屏或者向右横屏的应用程序工具栏和系统托盘的方位,需要两种都同时支持。这可能是和在计算机上运行的程序UI很大不同的一个方面。
         特点三:独特的页面框架及布局
         WP 7的应用程序是基于 Silverlight 的页面浏览模式,用户可以在不同内容的屏幕上相互导向和浏览。WP 7的页面框架及布局如下图1所示:
图1 WP 7 页面框架及布局
 
         在图1中,WP 7的页面中,包含了一个称为Frame Control(框架)的顶层容器控件,其可以承载 Page Control(页面)。在应用程序中,页面可以实现内容的分离。WP 7提供框架和页面类,以方便导航到独立的内容章节中。其实这类似于ASP.Net应用程序中的Master Page(母版页)。
         特点四:使用主题
         这个特点类似于ASP.Net应用程序中的主题,使用主题的优点是保持与 Metro 设计原则的一致性和兼容性,能确保用户界面元素以及控件呈现的一致性,防止不和谐的用户体验开发人员可以使用主题,也可以在应用程序级别使用代码来改变主题。
 
Windows Phone 7 UI设计原则
         界面设计是一个复杂的有不同学科参与的工程,认知心理学、设计学、语言学等在此都扮演着重要的角色。用户界面设计的三大原则是:置界面于用户的控制之下;减少用户的记忆负担;保持界面的一致性。结合WP 7UI设计的特点,在WP7 UI设计中,应遵循以下原则:
         原则一:支持多种输入,包括触摸、虚拟键盘、按钮和传感器。WP7的用户界面是为了触摸交互而设计的,所有的导航通过一系列手指手势的移动组合而完成。在使用触摸时就需要设计点击区域的大小,每一个可以被触摸的 UI 元素应该可以被手指方便的点击,如下图2所示:
图2 WP 7的输入设计
 
         原则二:统一的配色、页面框架和整套文字
         在计算机上的程序中需要使用统一的配色、页面框架和文字设置,在WP 7设计中一样要遵循这一原则。在WP 7的页面设计中,考虑容器控件、导航控件和页面布局的一致性,考虑列表的多种展现形式,如以列表显示或者拆分屏幕以形象的图片显示。
         原则三:使用Metro主题控件作为交互元素
         推荐您在应用程序中使用的标准Metro主题控件。这些控件已经为支持触摸交互并基于WP7 UI设计及人机交互指南手册做了优化调整。Metro主题控件设计UI如下图3所示:
图3 Metro 主题
 
         除此之外,在《Windows Phone 7 UI设计及人机交换指南V1.0》中提到了一下三点需要注意的:
(1)要理解适当的利用语音语调可以创建一个更具吸引力的终端用户体验.开发人员应该精心开发应用程序,来提供清晰友好的用户界面。
(2)良好定义的标准化准则将使你的应用程序一致性,放置最终用户在使用时有粗糙的体验。
(3)UI设计中必须使用正确的标点符号,同样,在你的应用程序中要保持一致。
 
Windows Phone 7应用程序控件
         WP 7应用程序开发的控件包括两类:WP7 应用程序控件和WP7 系统控件。WP7 应用的程序控件如下图4中左图所示:
图4  WP 7 标准控件与VS.Net标准控件
上图中右侧是VS.Net所带的标准控件,由上图比较我们可以看出:WP 7的控件比VS.Net标准控件要少,但是也有一些手机开发中使用的一些很有特点的控件:如Ellipse(椭圆)、Progress Bar(进度条)、Slider(滑动条)、Border(边框)。
         除了应用控件,还有一些控件也属于WP 7的控件,这些控件是系统控件,包括:系统托盘和应用工具栏、上下文菜单、WP消息通知、进度显示器。
 
小结
在WP 7 UI设计过程中,我们一方面需要考虑屏幕的分辨率,另一方面还要考虑整体界面的风格,所幸WP 7提供了主题和metro标准控件来帮助我们设计风格统一并且支持个性化的UI。在UI设计的过程中,可以通过WPDT Beta以所见即所得的方式来进行UI的设计,还可以把UI设计与数据分离。

摘自

]]> http://www.logolomo.com/2010/10/design/windows-phone-7-ui.html/feed 0