在規定區域內自動調整文字位置
問題
最近在做一個需求,就是塗鴉時,在繪製的圖形旁邊通過文字顯示相關資訊.先給大家看看最終的效果:
一開始的時候被這個問題難倒了,怎麼找到合適的位置顯示文字資訊,讓它們既不超出顯示範圍,又互不重疊?
解決方案
如果考慮不能重疊的問題,就需要在圖形四周的位置遍歷一遍直到沒有跟其他文字重疊,加上繪製的圖形是可以移動問題,這樣問題就更復雜了.於是我只能簡單化,尋找代價低又基本能滿足要求的方式.
首先,定義一個適配規則:文字優先顯示在左邊,如果超出顯示區域則直接顯示在右邊,這種右邊的情況下如果也超出了顯示區域,則往左邊偏移文字文字,使其剛好在顯示區域邊上.確定了左右位置後,接著處理垂直方向,文字優先顯示在跟圖形最上邊位置齊平的位置,如果文字底部超出顯示區域,則往上偏移文字,使其底部剛好在顯示區域底邊.
以矩形為例,顯示效果如下:
對照規則,標註如下:
文字優先顯示在左邊(圖1,2,4,6,7,10
),如果超出顯示區域則直接顯示在右邊(圖3,5
),這種右邊的情況下如果也超出了顯示區域,則往左邊偏移文字文字,使其剛好在顯示區域邊上(圖9
).確定了左右位置後,接著處理垂直方向,文字優先顯示在跟圖形最上邊位置齊平的位置(除圖8外的所有圖形
),如果文字底部超出顯示區域,則往上偏移文字,使其底部剛好在顯示區域底邊(圖8
).
這樣就限定了影像顯示在規定區域內啦!
實現
最後給出主要程式碼的程式碼實現,包括了矩形,圓,線的文字位置調整:
String msg = getInfo();
StaticLayout textStaticLayout = new StaticLayout(msg, mTextPaint, (int) getMaxWidth(msg, mTextPaint) + 1, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
mTextBounds.set(0, 0, textStaticLayout.getWidth(), textStaticLayout.getHeight());
float x = 0, y = 0;
if (getShape() == DoodleShape.HOLLOW_RECT || getShape() == DoodleShape.HOLLOW_CIRCLE) {
// 左右限定
float diff = -mTextPaint.getTextSize() / 3 ;
x = mShapeBounds.right - diff; // 優先在右
y = mShapeBounds.top;
if (x + getLocation().x + mTextBounds.width() > getDoodle().getBitmap().getWidth()) { // 超過右邊邊界,移到左邊
x = mShapeBounds.left + diff - textStaticLayout.getWidth();
if (x + getLocation().x < 0) { // 左邊邊界限定
x = 0;
}
}
// 上下限定,優先在上
if (y + getLocation().y + mTextBounds.height() > getDoodle().getBitmap().getHeight()) {
y = mShapeBounds.bottom - textStaticLayout.getHeight();
}
if (y + getLocation().y < 0) {
y = 0;
}
} else { // 線
PointF sxy = this.mSxy; // 起點
PointF dxy = this.mDxy; // 終點
if (this.mSxy.x > this.mDxy.x) { // 保證起點在左,終點在右的相對位置
sxy = this.mDxy;
dxy = this.mSxy;
}
// 左右限定
x = dxy.x + mTextPaint.getTextSize() / 3; // 優先在右
y = dxy.y;
if (x + getLocation().x + mTextBounds.width() > getDoodle().getBitmap().getWidth()) { // 超過右邊邊界,移到左邊
x = sxy.x - mTextPaint.getTextSize() / 3 - textStaticLayout.getWidth();
y = sxy.y;
if (x + getLocation().x < 0) { // 左邊邊界限定
x = 0;
}
}
// 上下限定, 優先在上
if (y + getLocation().y + mTextBounds.height() > getDoodle().getBitmap().getHeight()) {
y = y - ((y + getLocation().y + mTextBounds.height()) - getDoodle().getBitmap().getHeight());
}
if (y + getLocation().y < 0) {
y = 0;
}
}
canvas.save();
canvas.translate(x, y);
textStaticLayout.draw(canvas);
canvas.restore();
總結
上面僅是處理文字邊界範圍內顯示,除此之外還會存在文字之間重疊的問題.這裡我們可以參照上面的思路,優化邏輯,比如在左右限定時,如果滿足右邊顯示,則增加判斷是否跟其他圖形的文字重疊,如果不重疊則確定右邊顯示,如果有重疊則換成在左邊顯示.思路很簡單即在每一步判斷後再增加一條更嚴格的判斷,當然我們無法做到所有文字都不重疊(不然需要太多判斷條件),只要能做到儘量不重疊即可.
文中一開始的效果的塗鴉程式碼在我的開源框架的開源專案>>>>開源專案Doodle!一個功能強大,可自定義和可擴充套件的塗鴉框架。謝謝大家支援!!!
相關文章
- Echarts 圖表位置調整Echarts
- UITableViewCell分割線位置調整UIView
- 2018.3.29 DIV位置調整程式碼
- android程式碼中動態調整圖片的位置Android
- vs code 自動調整程式碼格式
- 檢查是否區域內所整數都被覆蓋
- 批量調整視訊尺寸大小的方法,一鍵自動批量調整視訊
- Android TextView 在指定位置自動省略字元AndroidTextView字元
- auto_size_text 自動調整文字大小以適應其容器的 Flutter 外掛Flutter
- kindeditor 上傳圖片 自動調整尺寸大小
- win10語言欄位置調整方法,win10語言欄怎麼調位置Win10
- 自動編碼器Gridsearch超引數調整KerasKeras
- 「ArrayBuffer」應用-以自動調整照片方向為例
- 《激戰2》的紙上談兵和實踐調整:區域任務與動態事件事件
- 領域模型驅動開發(2)-工程結構的調整模型
- 公司位置怎麼上地圖,怎麼在地圖上畫出區域地圖
- Python辦公自動化之——調整Word樣式(二)Python
- VSCode回車換行後自動調整程式碼格式VSCode
- 使用@AutoConfigureBefore、After、Order調整Spring Boot自動配置順序Spring Boot
- PGA自動管理原理深入分析及效能調整(六)
- PGA自動管理原理深入分析及效能調整(五)
- PGA自動管理原理深入分析及效能調整(一)
- Excel如何設定列印區域?Exce列印區域設定教程Excel
- 定義基因區域
- win10怎麼關閉視窗移動至邊緣時自動調整大小_win10取消移動視窗到邊緣自動調整大小的方法Win10
- Java 在Word指定段落/文字位置插入分頁符Java
- 區域性內部類
- 分散式 | 動態調整 DBLE 內執行緒池的數目分散式執行緒
- RecyclerView滾動位置,滾動速度設定View
- 如何判斷某經緯度是否在地圖不規則區域內(Objective-C 實現)地圖Object
- pytorch---在訓練中動態的調整學習率PyTorch
- JavaScript 拖動調整元素尺寸JavaScript
- DcatAdmin行操作按鈕樣式調整(圖示+文字)
- win10如何取消視窗貼邊時自動調整大小Win10
- 使用IntersectionObserver 實現:自動監聽元素是否進入了裝置的可視區域之內Server
- 基於Vue實現圖片在指定區域內移動Vue
- 選單元素溢位時,自動滾動到可視區域
- 【多區域截圖拼接!】優愛酷定時多區截圖屏自動傳送工具 原創軟體