这是该系列教程的第四篇——钢笔工具的运用。
本教程的第一篇:http://www.jianshu.com/p/109aac030ded
本教程的第二篇:http://www.jianshu.com/p/80b606f87f53
本教程的第三篇:http://www.jianshu.com/p/410f2ef8b424
本教程的第四篇:http://www.jianshu.com/p/7acc514dc2e3
本教程的第五篇:http://www.jianshu.com/p/84235319ca6a
系统偏好设置是Sketch新用户一般会容易忽视的地方,实际上系统偏好设置的一些设置会对设计产生较大的影响,和所有的Mac软件一样,系统偏好设置位于顶部菜单的软件名称一栏,在Sketch中打开系统偏好设置只需要点击菜单Sketch——Preferences...即可打开,快捷键为command+,键,如下图所示。
打开系统偏好设置后,可以看到如下图所示的窗口,顶部分成四个选项卡——General(通用)、Canvas(画布)、Layers(图层)和Plugins(插件)。每个选项卡都有相关的选项可以进行设置,下面对各选项卡的内容做一个详细介绍。
上图所示为General选项卡的界面,需要注意的是,随着Sketch的升级,每个选项卡的内容可能会发生一些小变化。
Auto Save(自动保存),勾选该选项,即可开启自动保存功能,开启该功能后,系统会每过一段时间自动保存一次当前的文档,相当于手动执行一次command+S的功能,开启该功能会占用一小部分的硬盘空间,但是一般情况下建议大家勾选。
Pixel Fitting(像素适应),我们知道Sketch是一款矢量绘图软件,但是计算机屏幕以及我们输出的位图都是由像素组成,在我们设计界面时,系统会根据我们设计的内容自动的对图形进行一些像素的填充,使之显示更加平滑,避免虚化的出现。但是计算机毕竟是根据特殊的算法进行处理,并不能保证每次都能填充到最合适,勾选该选项,可以让图层和锚点的和像素边界对齐,如下图所示,上部分是未勾选的效果,下部分是勾选该选项的效果,在该选项下方还有两个选项——Pixel-fit when resizing layers(在缩放图层时应用像素适应)和Pixel-fit when aligning layers(在对齐图层时应用像素适应),该选项中建议所有选项勾选。
Vector Import(矢量图导入),若勾选该选项,则导入PDF和EPS格式的文件时会作为一个位图文件进行导入,一般情况下建议不要勾选,若在设计中偶尔希望导入时自动转化为位图,则可以在导入时按下option键执行相反的效果。
Sketch Mirror,关于Mirror在后续文章会介绍,在此不做展开。在未勾选状态,移动设备打开Mirror链接后,会显示该Sketch文件中的第一个画板,若勾选该选项,则始终显示当前正在编辑的画板。
系统偏好设置中的第二个选项卡Canvas(画布)选项卡内容如下图所示,该选项卡用于一些和画布相关的设置。
Font Rendering(字体渲染),Sketch调用的是OS X的字体渲染引擎进行渲染,所以若设计Mac软件或者web网页时建议勾选该选项,若进行iOS和Apple Watch界面设计时,因取消勾选,但是在进行安卓界面设计时,最好是勾选。实际上,随着屏幕分辨率的提升,字体的渲染引擎带来的差异已经在不断缩小,但是大家在进行iOS和Apple Watch设计时,最好还是应取消勾选。
Retina,勾选该选项,则在Retina屏幕的Mac上Sketch的画布在相同尺寸下可以看到更多的细节,目前有Retina屏幕的Mac设备有Retina Macbook Pro,全新Macbook和4K/5K的iMac。在这些设备上,建议勾选该选项。
Zoom(缩放),Animate zoom(缩放动效),勾选该选项,在进行缩放时会有缩放动效;Zoom in on selection(以选中图层为中心进行缩放),勾选该选项,则进行画布缩放时,始终以当前选中图层为中心进行缩放,若未勾选,则以当前屏幕上画布为中心进行缩放;Zoom back to previous Canvas position(将画布缩放至之前的位置),勾选该选项时,当缩放至实际尺寸时,无论之前以谁为中心进行的缩放都将回到缩放前画布的位置,否则回到画布中心。
Colors(颜色),点击该处色块,可以设置参考线的颜色。
系统偏好设置中第三个选项卡Layers(图层)选项卡内容如下图所示,该选项卡中内容用于和图层相关的设置。
New Groups(新的编组),勾选该选项的效果和图层组检查器中勾选Click-through when selecting效果一致,只是在此勾选会对所有的图层组生效。可以根据个人习惯进行选中,但是笔者建议不要勾选,因为若需要直接选中组内图层而非图层组,可以在点击组内图层时,按住键盘上的command键进行点选,同样可直接选中该图层。
Duplicating(复制),Offset duplicated layers(移动复制的图层),勾选该选项,则在进行图层复制时,复制的图层会相对于原图层有10px的位移,如下图所示,左侧为未勾选该选项时复制图层的效果,右侧为勾选该选项时复制图层的效果。Rename duplicated layers(对复制的图层重命名),勾选该选项时,在对图层进行复制时(command+D),复制的图层命名为“原图层名+Copy+次数”,如“Oval Copy 2”,若取消勾选,则复制图层的名字和原图层一致。
Text Layers(文本图层),勾选该选项,则进行文本粘贴时不带任何文本样式,此处的文本样式不仅包括Sketch文本图层复制过来的文字,还包括从Sketch之外的如网页等粘贴过来的文字。
Flatten Bitmaps(拼合位图),此处可以选择当将图层转化为位图时,是转化为1倍尺寸大小还是2倍尺寸大小,若我们用1倍尺寸设计Retina设备上的界面时,建议设置为2x尺寸,避免模糊。
系统偏好设置中第四个选项卡Plugins(图层)选项卡内容和插件内容相同,具体请看本教程第五篇:http://www.jianshu.com/p/84235319ca6a
屏幕的显示机制和帧动画类似,也是一帧一帧的连环画,只不过刷新频率很高,感觉像连续的。为了显示一帧,需要经历计算和渲染两个过程,CPU 先计算出这一帧的图像数据并写入内存,然后调用 OpenGL 命令将内存中数据渲染成图像存放在 GPU Buffer 中,显示设备每隔一定时间从 Buffer 中获取图像并显示。上述过程中的计算,对于View来说,就好比在主线程遍历 View树 以决定视图画多大(measure),画在哪(layout),画些啥(draw),计算结果存放在内存中,SurfaceFlinger 会调用 OpenGL 命令将内存中的数据渲染成图像存放在 GPU Buffer 中。每隔16.6ms,显示器从 Buffer 中取出帧并显示。所以自定义 View 可以通过重载onMeasure()、onLayout()、onDraw()来定义帧内容,但不能定义帧刷新频率。
SurfaceView可以突破这个限制。而且它可以将计算帧数据放到独立的线程中进行。下面是自定义SurfaceView的模版代码:
public abstract class BaseSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
public static final int DEFAULT_FRAME_DURATION_MILLISECOND = 50
//用于计算帧数据的线程
private HandlerThread handlerThread
private Handler handler
//帧刷新频率
private int frameDuration = DEFAULT_FRAME_DURATION_MILLISECOND
//用于绘制帧的画布
private Canvas canvas
private boolean isAlive
public BaseSurfaceView(Context context) {
super(context)
init()
}
protected void init() {
getHolder().addCallback(this)
//设置透明背景,否则SurfaceView背景是黑的
setBackgroundTransparent()
}
private void setBackgroundTransparent() {
getHolder().setFormat(PixelFormat.TRANSLUCENT)
setZOrderOnTop(true)
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
isAlive = true
startDrawThread()
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stopDrawThread()
isAlive = false
}
//停止帧绘制线程
private void stopDrawThread() {
handlerThread.quit()
handler = null
}
//启动帧绘制线程
private void startDrawThread() {
handlerThread = new HandlerThread(“SurfaceViewThread”)
handlerThread.start()
handler = new Handler(handlerThread.getLooper())
handler.post(new DrawRunnable())
}
private class DrawRunnable implements Runnable {
@Override
public void run() {
if (!isAlive) {
return
}
try {
//1.获取画布
canvas = getHolder().lockCanvas()
//2.绘制一帧
onFrameDraw(canvas)
} catch (Exception e) {
e.printStackTrace()
} finally {
//3.将帧数据提交
getHolder().unlockCanvasAndPost(canvas)
//4.一帧绘制结束
onFrameDrawFinish()
}
//不停的将自己推送到绘制线程的消息队列以实现帧刷新
handler.postDelayed(this, frameDuration)
}
}
protected abstract void onFrameDrawFinish()
protected abstract void onFrameDraw(Canvas canvas)
}
用HandlerThread作为独立帧绘制线程,好处是可以通过与其绑定的Handler方便地实现“每隔一段时间刷新”,而且在Surface被销毁的时候可以方便的调用HandlerThread.quit()来结束线程执行的逻辑。
DrawRunnable.run()运用模版方法模式定义了绘制算法框架,其中帧绘制逻辑的具体实现被定义成两个抽象方法,推迟到子类中实现,因为绘制的东西是多样的,对于本文来说,绘制的就是一张张图片,所以新建BaseSurfaceView的子类FrameSurfaceView:
逐帧解析 &及时回收
public class FrameSurfaceView extends BaseSurfaceView {
public static final int INVALID_BITMAP_INDEX = Integer.MAX_VALUE
private List bitmaps = new ArrayList<>()
//帧图片
private Bitmap frameBitmap
//帧索引
private int bitmapIndex = INVALID_BITMAP_INDEX
private Paint paint = new Paint()
private BitmapFactory.Options options = new BitmapFactory.Options()
//帧图片原始大小
private Rect srcRect
//帧图片目标大小
private Rect dstRect = new Rect()
private int defaultWidth
private int defaultHeight
public void setDuration(int duration) {
int frameDuration = duration / bitmaps.size()
setFrameDuration(frameDuration)
}
public void setBitmaps(List bitmaps) {
if (bitmaps == null || bitmaps.size() == 0) {
return
}
this.bitmaps = bitmaps
//默认情况下,计算第一帧图片的原始大小
getBitmapDimension(bitmaps.get(0))
}
private void getBitmapDimension(Integer integer) {
final BitmapFactory.Options options = new BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeResource(this.getResources(), integer, options)
defaultWidth = options.outWidth
defaultHeight = options.outHeight
srcRect = new Rec
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)