1.uiå辨ç
2.ImageView设置backgroundåsrcçåºå«
3.UE4-Slate源码学习(六)slate渲染Part2-Paint控件绘制
4.unslider.js 插件 拉伸时 无法自适应
uiå辨ç
ä¸ãCocosç¼è¾å¨èªå¨å¸å±ç³»ç»ä¸»è¦æ¶ååºå®ä¸æ伸å±æ§ï¼
å¦å¾ï¼æ»å ±å¯ä»¥ä¿®æ¹æ§ä»¶çä¸ä¸å·¦å³å个å¾éåä¸é´ç两个æ伸æ¡å 个å±æ§ã
ææ
1.å½æå¼å ¶ä¸çä»»æä¸ä¸ªå¾éæ¶ï¼å½åèç¹ä¸ç¶èç¹ç对åºè¾¹çè·ç¦»å³è¢«åºå®ãå½ç¶èç¹ç大å°ä¿®æ¹æ¶ï¼å½åèç¹ä¸ç¶èç¹å¯¹åºè¾¹çè·ç¦»æ»æ¯ä¸åã
2.å½æå¼å ¶ä¸çä»»æ两个ç¸å¯¹çå¾éæ¶ï¼å½åèç¹ä¸ç¶èç¹å¯¹åºç两边çè·ç¦»æåºå®æ¯ä¾ãå³å½ä¿®æ¹ç¶èç¹ç大å°æ¶ï¼å½åèç¹å°ç¶èç¹å¯¹åºä¸¤æ¡è¾¹çè·ç¦»ä¹æ¯æ»æ¯ä¸åçã
3.å½å¼å¯ä¸é´ä»»æä¸æ¡æ伸æ¡ï¼å¦æ¨ªåæ伸æ¡ï¼èç¹ç宽度ä¸ç¶èç¹ç宽度ä¹æ¯åºå®ä¸åã
å ¶ä»
1. ä¸å¼å¯ä¸è¿°ä»»æå±æ§æ¶ï¼å¯¹è±¡é»è®¤ç¸å¯¹å·¦ä¸è§ä½ç½®ä¸åã
2. å½åä» æ§ä»¶å¯¹è±¡ï¼ææ¬ãFNTåä½ä¹æ²¡æï¼å容å¨ä¸¤ç§ç±»åææ伸æ¡å±æ§ã
äºãCocos 2d-x(Cocos Framework)ä¸çç¸å ³æ¦å¿µå代ç 设置
设计å辨çåå±å¹å辨çï¼
é¦å æ们éè¦äºè§£ä¸¤ä¸ªæ¦å¿µï¼å¨Cocos2d-xä¸æ两ç§å辨çï¼è®¾å¤å辨çãå±å¹å辨çã设å¤å辨çå³å½å游ææè¿è¡å¹³å°çå®é å辨çï¼è®¾è®¡å辨çå°±æ¯æ们设计ç游æçå辨çã
设计å辨çæ¯å¯è®¾ç½®çï¼æ¯æ们ç游æç¨åºè½å¤âæç¥å°âçå辨ç大å°ï¼æ们ççé¢è¶ è¿è¿ä¸ªåºåçé¨åé½ä¸ä¼æ¾ç¤ºã
设计å辨çä¸è¬å¨å¯å¨æ¶è¿è¡è®¾ç½®
AppDelegate::applicationDidFinishLaunching
ä¸è¿è¡ï¼ä»£ç å¦ä¸ï¼
director->getOpenGLView()->setDesignResolutionSize(,任意任意,ResolutionPolicy::FIXED_HEIGHT);
(è¿å¥ä»£ç ä¸è¾¹è¿æä¸å¥createWithRectè¿ä¸ªæ¯å¨æ¡é¢ç³»ç»ä¸ï¼å建游æ模æå¨ç¨çãå¯ä»¥ä¿®æ¹éè¾¹çRectçå边两个å¼æ¥ä¿®æ¹è®¾å¤å辨çï¼ä½è¿ä¸ªå¼å¨ç§»å¨è®¾å¤ä¸æ¯æ æçã)
è¿å¥ä»£ç ä»ä¹ææå¢ï¼
è¿éæ设计å辨ç设置为ï¼ï¼å¹¶æ游æçé¢è°æ´æ¹æ¡è®¾ç½®ä¸ºåºå®å®½åº¦ãä½è¿ä¹è®¾ç½®ä¹åï¼æ们åè¾¹åè·å设计å辨çæ¶å¾å°ç大å°å´ä¸ä¸å®æ¯ï¼ãè¿åæ¯ä¸ºä»ä¹å¢ï¼
ççæºç ï¼
转å°setDesignResolutionSizeçå®ä¹ççãéè¾¹åäºä¸äºå¤æåèµå¼ï¼æç»è°ç¨äºupdateDesignResolutionSizeï¼ç»§ç»è½¬å°updateDesignResolutionSizeéè¾¹ï¼è¿ä¸ªå½æ°çé¨å代ç å¦ä¸ï¼
//1.计ç®æ¸¸æçé¢å¨ç¼©æ¾è³å 满å±å¹çæ åµä¸XãYè½´ç缩æ¾ç:_scaleX= (float)_screenSize.width/ _designResolutionSize.width;
_scaleY= (float)_screenSize.height/ _designResolutionSize.height;//2.æ ¹æ®è®¾é çç¥ï¼è°æ´ç¼©æ¾çå设计å辨ç:if(_resolutionPolicy== ResolutionPolicy::NO_BORDER){ //å°XãY轴缩æ¾å¼è®¾ç½®ä¸ºå ¶ä¸çæ大è
_scaleX = _scaleY = MAX(_scaleX,_scaleY);
}else if(_resolutionPolicy== ResolutionPolicy::SHOW_ALL){ //å°XãY轴缩æ¾å¼è®¾ç½®ä¸ºå ¶ä¸çæå°è
_scaleX = _scaleY = MIN(_scaleX,_scaleY);
}else if( _resolutionPolicy == ResolutionPolicy::FIXED_HEIGHT) {
_scaleX = _scaleY;//å°XãY轴缩æ¾å¼åºå®ä¸ºY轴缩æ¾å¼ï¼è°æ´è®¾è®¡å辨çç宽度ï¼ä½¿è®¾è®¡å辨çç宽度å¨ç¼©æ¾åä¾ç¶è½å¤å 满å±å¹ã
_designResolutionSize.width= ceilf(_screenSize.width/_scaleX);
}else if( _resolutionPolicy == ResolutionPolicy::FIXED_WIDTH) {
_scaleY= _scaleX;//å°XãY轴缩æ¾å¼åºå®ä¸ºX轴缩æ¾å¼ï¼è°æ´è®¾è®¡å辨ççé«åº¦ï¼ä½¿è®¾è®¡å辨ççé«åº¦å¨ç¼©æ¾åä¾ç¶è½å¤å 满å±å¹ã
_designResolutionSize.height= ceilf(_screenSize.height/_scaleY);
}//å ¶ä»ç¼©æ¾çç¥ï¼EXACT_FITä¸ä½è°æ´
è¿æ®µä»£ç 主è¦åäºä¸¤ä»¶äºï¼
1.æ ¹æ®è®¾å¤å辨çå设计å辨ç计ç®æ¸¸æçé¢ç缩æ¾çï¼
2.è°æ´è®¾è®¡å辨çã
æ ¹æ®ä»¥ä¸æºç æ们åºè¯¥å¾å®¹æå°±è½å¤ç解å ç§ç¼©æ¾çç¥çæä¹ï¼
·NO_BORDERå°±æ¯å¨ä¿æ设计å辨ç大å°ä¸åçæ åµä¸ï¼å°æ¸¸æçé¢ææ¯ä¾ç¼©æ¾è³å 满å±å¹ã游æçä¸ä¸æè å·¦å³ä¸¤è¾¹å¯è½ä¼è¢«è£åªã
·SHOW_ALL(Cocos 2d-xé»è®¤æ¹æ¡)å°±æ¯å¨ä¿æ设计å辨ç大å°ä¸åçæ åµä¸ï¼å°æ¸¸æçé¢ææ¯ä¾ç¼©æ¾è³è®¾è®¡å辨ççå ¶ä¸ä¸è¾¹é¡¶ä½å±å¹ã游æä¸ä¸æè å·¦å³ä¸¤è¾¹å¯è½ä¼æé»è¾¹ã
·FIXED_HEIGHTå°±æ¯åºå®è®¾è®¡å辨ççé«åº¦ï¼è°æ´è®¾è®¡å辨çç宽度ï¼ä½¿è®¾è®¡å辨ççé¿å®½æ¯ä¸è®¾å¤å辨ççé¿å®½æ¯ç¸åï¼ç¶å缩æ¾æ¸¸æçé¢è³å 满å±å¹ã
·FIXED_WIDTHåä¸ï¼ä¸åçæ¯ä¿æ宽度ä¸åã
·EXACT_FITæ¯æç²æ´çæ¹å¼ï¼ç´æ¥å°æ¸¸æçé¢ç¼©æ¾å°å 满æ´ä¸ªå±å¹ï¼Xè½´Y轴缩æ¾æ¯çä¸ä¸å®ä¸è´ã
é£ä¹ï¼æ们åºè¯¥éæ©åªä¸ªæ¹æ¡å¢ï¼å¿ ç¶çæ们åºè¯¥éæ©FIXED_HEIGHTæè FIXED_WIDTHãå 为åªæè¿ä¸¤ä¸ªæ¹æ¡ä¸ï¼çé¢æ¯ä¼èªå¨æ ¹æ®è®¾å¤å辨çè°æ´è®¾è®¡å辨çç大å°å¹¶ä¸å 满å±å¹ã
æ¥ä¸æ¥å è½½çé¢ã
å è½½çé¢å¨HelloWorld::initä¸è¿è¡ï¼
auto rootNode= CSLoader::createNode("MainScene.csb");
auto size= Director::getInstance()->getVisibleSize();
rootNode->setContentSize(size);
ui::Helper::doLayout(rootNode);
addChild(rootNode);
è¿éé¤äºç¨createNodeæçé¢å è½½åºæ¥ï¼å¹¶æ·»å å°HelloWorldä¹å¤ï¼è¿åäºä¸¤ä»¶äºæ ï¼
• 设置å è½½åºæ¥ççé¢çContentSizeï¼è°ç¨å¯¹rootNodeè°ç¨äºui::Helper::doLayout对å è½½åºæ¥ççé¢è¿è¡å¤çã
• 为ä»ä¹è¦è¿ä¹è®¾è®¡å¢ï¼åæèªå¨çå¤å¥½åï¼
第ä¸ä¸ªçç±ï¼è·ç¼è¾å¨ä¸ä¸è´ï¼ç¬¬äºä¸ªçç±æ¯ï¼èªå¨è°æ´çé¢è¢«è®¾è®¡ä¸ºæ¯è¢«å¨çï¼å¦ææ¯ä¸»å¨è¿è¡çè¯ï¼å¯è½ä¼é æ大éçæ§è½æ失ââå¦ææ¯æ¬¡è®¾ç½®å¤§å°é½è¦éæ°éå计ç®ææçåèç¹çä½ç½®ï¼é£å¾æµªè´¹å¤å°CPUæ¶é´åã
ææï¼
设å¤å辨çX/Yç¸å¯¹è®¾è®¡å辨çX/Yè¾å¤§ï¼è®¾é çç¥ä¸ºåºå®é«åº¦
请ç¹å»è¾å ¥å¾çæè¿°
设å¤å辨çX/Yç¸å¯¹è®¾è®¡å辨çX/Yè¾å¤§ï¼è®¾é çç¥ä¸ºåºå®å®½åº¦
请ç¹å»è¾å ¥å¾çæè¿°
设å¤å辨çX/Yç¸å¯¹è®¾è®¡å辨çX/Yè¾å°ï¼è®¾é çç¥ä¸ºåºå®é«åº¦
请ç¹å»è¾å ¥å¾çæè¿°
设å¤å辨çX/Yç¸å¯¹è®¾è®¡å辨çX/Yè¾å°ï¼è®¾é çç¥ä¸ºåºå®é«åº¦
请ç¹å»è¾å ¥å¾çæè¿°
PSï¼æ举类åResolutionPolicyæ¯æ¡æ¶æä¾ç»æ们çæ¹ä¾¿çé»è®¤æ¹æ¡ãå ¶å®æ们å¨è®¾ç½®è®¾è®¡å辨çä¹åå¯ä»¥è·å设å¤å辨çï¼ç¶åèªå·±æ ¹æ®è®¾å¤å辨çè°æ´è®¾è®¡å辨çã
ImageView设置backgroundåsrcçåºå«
ä»å¤©å¼åçæ¶åéå°ä¸ä¸ªå°é®é¢ï¼å¨ç»ä¸ä¸ªImageViewæ´æ¢å¾ççæ¶åï¼æ使ç¨çæ¯javaçæ¹å¼æ´æ¢ï¼ä½¿ç¨çæ¹æ³æ¯setBackgroundResourceï¼ï¼,ä½å¥æªçæ¯æ»æ¯æ²¡æææã
æåæ¥æåå æ¯ï¼æå¨ç¼åxmlæ件çæ¶åï¼ä¸ºäºæ¥çææï¼ç»è¿ä¸ªImageView设置äºsrcï¼è¿æ¶åå设置backgroundçæ¶åååçéå ã
解å³æ¹æ³ï¼å°xmlä¸çsrcå é¤å³å¯ã
é®é¢å»¶ä¼¸ï¼
ä¸ãImageView设置backgroundåsrcçåºå«ã
1.srcæ¯å¾çå 容ï¼åæ¯ï¼ï¼bgæ¯èæ¯ï¼å¯ä»¥åæ¶ä½¿ç¨ã
2.backgroundä¼æ ¹æ®ImageViewç»ä»¶ç»å®çé¿å®½è¿è¡æ伸ï¼èsrcå°±åæ¾çæ¯åå¾ç大å°ï¼ä¸ä¼è¿è¡æ伸 ã
3.scaleTypeåªå¯¹srcèµ·ä½ç¨ï¼bgå¯è®¾ç½®éæ度ã
äºãImageViewå ç§ä¸åç设置å¾ççæ¹å¼ã
设置backgroundï¼
1.image.setBackground(getResources().getDrawable(R.drawable.blackk));//åå½¢
2.image.setBackgroundResource(R.drawable.blackk);//åå½¢ 3.image.setBackgroundDrawable(getResources().getDrawable(R.drawable.blackk));////åå½¢
æºç ï¼è¿ä¸ç§æ¹æ³çå®è´¨é½æ¯è°ç¨æ¹æ³3setBackgroundDrawable()ã
设置src:
1.image.setImageDrawable(getResources().getDrawable(R.drawable.blackk)); //ä¸ä¼åå½¢
2.Stringpath=Environment.getExternalStorageDirectory()+File.separator+âtest1.jpgâ;
Bitmap bm = BitmapFactory.decodeFile(path);
image.setImageBitmap(bm);//ä¸ä¼åå½¢
3.image.setImageResource(R.drawable.blackk);//ä¸ä¼åå½¢
æºç ï¼ å ¶ä¸æ¹æ³2å°±æ¯å°bitmap转æ¢ä¸ºdrawableç¶åè°ç¨æ¹æ³1ï¼æ¹æ³1åæ¹æ³3é½æ¯è°ç¨updateDrawableï¼ï¼æ¹æ³ã
UE4-Slate源码学习(六)slate渲染Part2-Paint控件绘制
上一篇文章介绍了绘制一个SWindow的初期步骤,即计算整个UI树的拉伸拉伸控件大小,为绘制做准备。图片图片文章随后深入探讨了绘制流程的源码源码第二步,即执行FSlateApplication::PrivateDrawWindows()后,下载开始调用SWidget::Paint()函数,任意任意传奇源码编程教学每个控件随后实现其虚函数OnPaint()。拉伸拉伸
在这一过程中,图片图片绘制参数被封装在FPaintArgs中,源码源码作为Paint和OnPaint过程中的下载关键引用参数。FSlateRHIRenderer与FSlateDrawBuffer是任意任意继承自FSlateRenderer的类,作为FSlateApplicationBase的拉伸拉伸全局变量,在构造时创建。图片图片在绘制过程中,源码源码通过GetDrawBuffer()函数可获取到FSlateDrawBuffer对象。下载
FSlateDrawBuffer实现了Slate的spring注解注入源码绘制缓冲区,内部封装了FSlateWindowElementList数组,用于存储多个SWindow下的绘制元素列表。每个SWindow通过AddWindowElementList()返回一个元素列表。
FSlateWindowElementList负载了SWindow内的所有图元信息,内部封装了FSlateDrawElement的数组,包含Cached和Uncached元素,以及SWindow的指针和用于渲染的批处理数据FSlateBatchData。
FSlateDrawElement是构建Slate渲染界面的基本块,封装了UI树节点控件需要渲染的相关信息,如渲染变换、位置、大小、层级ID、绘制效果等,以及后续渲染阶段需要的盘多多搜索源码相关数据。
在Paint流程中,处理当前传入的SWindow和ChildWindows,首先判断窗口是否可见和是否最小化,然后从参数封装的OutDrawBuffer中获取WindowElementList。调用SWindow的PaintWindow()函数开始绘制窗口,并最终返回所有子控件计算完的最大层级。接着,子窗口递归绘制。
PaintWindow()函数在绘制窗口时,首先调用SetHittestArea()设置点击区域,HittestGrid会判断窗口大小是否改变,若不变则仅更新窗口在屏幕中的位置。构造FPaintArgs参数后,将其封装到FSlateInvalidationContext中。
FSlateInvalidationRoot类的c string源码分析PaintInvalidationRoot()函数可以作为控件树的根节点或叶子节点(SInvalidationPanel),构建快速路径避免每次绘制都计算大小和Paint函数,有利于优化。本篇文章主要分析正常慢速路径调用流程,优化相关将另文分析。
PaintSlowPath()函数从SWindow开始调用Paint()函数,并定义LayerId从0开始作为参数,进行实际的绘制相关计算。
Paint()函数首先处理裁剪、透明度混合、坐标转换等代码。若SWidget包含NeedsTick掩码,则调用Tick函数,我们在日常开发中通过蓝图或lua使用Tick函数时即调用到这里,通过SObjectWidget::Tick调用到UUserWidget::NativeTick供实现Tick。构造FSlateWidgetPersistentState PersistentState作为SWidget的源码如何检测后门变量,表示Paint时的状态。
PersistentState.CachedElementHandle将当前SWidget存储到FSlateWindowElementList中的WidgetDrawStack数组中。
更新FPaintArgs中的父节点参数和继承可点击测试参数,判断点击测试状态,然后将当前SWidget添加到点击测试中。调用虚函数OnPaint,由控件自己实现。
OnPaint()函数参数包括绘制参数引用、几何体、裁剪矩形、缓冲元素列表、层级、控件风格、父节点状态等。最后处理重绘标签、延迟绘制相关内容、UpdateWidgetProxy()根据缓存句柄更新快速路径中需要处理标记设置为Volatile不稳定状态的SWidget。
虚函数OnPaint()由子类自己实现,本文列举了SImage、SButton、SCompoundWidget和SConstraintCanvas的OnPaint()示例代码学习。
在SImage中,简单判断Brush是否存在以及BrushDrawType的类型,然后调用FSlateDrawElement::MakeBox将控件添加到缓冲区元素列表中。
SButton继承自SCompoundWidget,GetBorder()根据当前按钮状态返回ui中设置的Enabled、Press、Hover、Disabled等状态的Brush。
SCompoundWidget作为合成节点,有且只能有一个子节点,且在Paint时强制将子节点的LayerId+1,同时SCompoundWidget可以单独设置混合颜色和透明度,影响子节点。
SConstraintCanvas作为SWidget的基类对应UMG中常用的UCanvasPanel,通过ArrangeLayeredChildren()对孩子进行层级排序,并根据孩子的层级是否相同存储bool值在ChildLayers中。遍历所有孩子,判断是否开启新层级,递归调用Paint函数,最后返回最大层级。
SConstraintCanvas::ArrangeLayeredChildren函数中,获取设置bExplicitChildZOrder,表示可以将同层一次渲染,有利于提高渲染器批处理。对所有孩子排序,排序规则为FSortSlotsByZOrder。遍历所有孩子,判断可见性掩码、计算偏移、锚点、位置、拉伸缩放等,封装成FArrangedWidget存储到ArrangedChildren中,用于OnPaint时有序遍历。判断每个孩子ZOrder是否相同,相同则bNewLayer为false,大于LastZOrder则将bNewLayer设置为true,最终存储到ArrangedChildLayers中,用于OnPaint函数判断是否将layerId+1。
FSlateDrawElement::MakeBox()函数在OnPaint之后调用,将绘制控件的相关信息通过创建FSlateDrawElement绘制元素对象,添加到SWindow管理的FSlateWindowElementList元素列表中。创建Payload用于存储贴图等相关信息,根据控件Paint过程中的参数调用Element.Init初始化绘制元素,得到为该控件绘制创建的FSlateDrawElement对象。
总结整个Slate绘制流程的第二步,我们没有分析快速处理和优化细节,而是按照正常绘制流程分析代码。通过从PaintWindow开始遍历整个控件树,处理每个空间节点的Paint、OnPaint函数,最终目的是给每个控件创建一个FSlateDrawElement对象,存储渲染线程绘制所需的相关信息,并添加到FSlateWindowElementList中。理解了整个调用流程,整个过程较为清晰,本文基于UE4版本4..2。
unslider.js 插件 拉伸时 无法自适应
原作者源码上规定了
* {
margin: 0;
padding: 0;
-webkit-font-smoothing: antialiased;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
有奇效,包你满意