autojs繪畫實(shí)現(xiàn)六邊形示例詳解
界面基礎(chǔ)代碼
"nodejs ui";
require("rhino").install();
const ui = require("ui");
class MainActivity extends ui.Activity {
constructor() {
super();
}
get layoutXmlFile() {
return "layout.xml";
}
onContentViewSet() {}
}
ui.setMainActivity(MainActivity);
創(chuàng)建Hexagon類
class Hexagon {}
至于需要的屬性, 有需求的時(shí)候再寫
界面布局
<column> <canvas id="canvas" w="*" h="*"> </canvas> </column>
畫板事件
onContentViewSet(view) {
const canvasView = view.binding.canvas;
canvasView.on("draw", (canvas) => {
canvas.drawColor(canvasBgColor);
});
}
計(jì)算并繪制六邊形中心點(diǎn)
let canvasWidth = canvasView.getWidth();
let canvasHeight = canvasView.getHeight();
let centerX = canvasWidth / 2;
let centerY = canvasHeight / 2;
canvasView.on("draw", (canvas) => {
canvas.drawColor(canvasBgColor);
canvas.drawPoint(centerX, centerY, paint);
});
計(jì)算六邊形六個(gè)點(diǎn)的坐標(biāo)
這個(gè)方法應(yīng)該屬于六邊形這個(gè)類
getSixPoints() {
let points = [];
let angle = 0;
for (let i = 0; i < 6; i++) {
let x = this.centerX + this.sideLength * Math.cos(angle);
let y = this.centerY - this.sideLength * Math.sin(angle);
points.push({ x, y });
angle += Math.PI / 3;
}
return points;
}
計(jì)算六邊形的path
這個(gè)也屬于六邊形的方法
getPath() {
const path = new Path();
let points = this.getSixPoints();
path.moveTo(points[0].x, points[0].y);
for (let i = 1; i < points.length; i++) {
path.lineTo(points[i].x, points[i].y);
}
path.close();
return path;
}
繪制六邊形
let hexagon = new Hexagon(centerX, centerY, config.sideLength);
let hexagonPath = hexagon.getPath();
canvasView.on("draw", (canvas) => {
canvas.drawColor(canvasBgColor);
canvas.drawPoint(centerX, centerY, paint);
canvas.drawPath(hexagonPath, paint);
});

繪制一排六邊形
要繪制一排, 那么六邊形左右兩邊需要是數(shù)直的, 把 getSixPoints 方法里的 sin 和 cos 對(duì)調(diào)一下即可
let x = this.centerX + this.sideLength * Math.sin(angle); let y = this.centerY - this.sideLength * Math.cos(angle);

確定邊界條件
所有六邊形都要在畫板內(nèi), 我們畫左上角第一個(gè)六邊形;
計(jì)算中心點(diǎn)要考慮的條件
- 畫筆的寬度
- 六邊形邊長(zhǎng)
let angle = Math.PI / 3; let firstHexagonCenterX = config.sideLength * Math.sin(angle) + config.paintConfig.width; let firstHexagonCenterY = config.sideLength + config.paintConfig.width;

考慮兩個(gè)相鄰的六邊形連接處
兩個(gè)挨著的豎邊, 應(yīng)該只需要畫一條, 那么來計(jì)算第二個(gè)六邊形的中心位置, 以第一個(gè)六邊形為參照物
let secondHexagonCenterX = firstHexagonCenterX + config.sideLength * Math.sin(angle) * 2; let secondHexagonCenterY = firstHexagonCenterY;
繪制出的兩個(gè)六邊形
改了一下寬度, 方便觀察

限制一排六邊形最后一個(gè)的邊界
最后一個(gè)六邊形的最右側(cè)的邊, 不能超過畫板
let hexagonPaths = [];
let count = 1;
while (1) {
let nextHexagonCenterX = firstHexagonCenterX + config.sideLength * Math.sin(angle) * 2 * count;
if (nextHexagonCenterX + config.sideLength * Math.sin(angle) + config.paintConfig.width > canvasWidth) {
break;
}
let nextHexagonCenterY = firstHexagonCenterY;
let nextHexagon = new Hexagon(nextHexagonCenterX, nextHexagonCenterY, config.sideLength);
let nextHexagonPath = nextHexagon.getPath();
hexagonPaths.push(nextHexagonPath);
count++;
}
for (let i = 0; i < hexagonPaths.length; i++) {
canvas.drawPath(hexagonPaths[i], paint);
}

畫第二排六邊形
計(jì)算第二排第一個(gè)六邊形的中心點(diǎn)
let nextRowFirstHexagonCenterX = firstHexagonCenterX + config.sideLength * Math.sin(angle); let nextRowFirstHexagonCenterY = firstHexagonCenterY + config.sideLength * Math.cos(angle) + config.sideLength; let nextRowFirstHexagon = new Hexagon(nextRowFirstHexagonCenterX, nextRowFirstHexagonCenterY, config.sideLength); let nextRowFirstHexagonPath = nextRowFirstHexagon.getPath();

與第一排同理, 畫第二排

繪制多排六邊形
很明顯, 我們要使用循環(huán), 橫著要循環(huán), 豎著也要循環(huán), 那么這個(gè)循環(huán)怎么寫呢?
我們一組一組的計(jì)算六邊形中心點(diǎn), 一組有兩排六邊形:
- 第一排5個(gè)
- 第二排4個(gè)
下一組, 往下移動(dòng) 3 個(gè)邊長(zhǎng),
因?yàn)榈谝唤M, 我們已經(jīng)檢查過畫板右側(cè),
所以, 接下來的計(jì)算, 只需要考慮畫板底部, 不需要判斷畫板右側(cè)了;
我們改變的只有縱坐標(biāo)
先畫一組
let firstRow = [];
let secondRow = [];
let firstGroup = [firstRow, secondRow];
let firstRowCount = 0;
while (1) {
let centerX = firstHexagonCenterX + firstRowCount * config.sideLength * 2 * Math.sin(angle);
if (centerX > canvasWidth - config.sideLength * Math.sin(angle) - config.paintConfig.width) {
break;
}
let centerY = firstHexagonCenterY;
firstRow.push(new Hexagon(centerX, centerY, config.sideLength));
firstRowCount++;
}
/* -------------------------------------------------------------------------- */
let secondRowCount = 0;
while (1) {
let centerX = firstHexagonCenterX + secondRowCount * config.sideLength * 2 * Math.sin(angle) + config.sideLength * Math.sin(angle);
if (centerX > canvasWidth - config.sideLength * Math.sin(angle) - config.paintConfig.width) {
break;
}
let centerY = firstHexagonCenterY + config.sideLength + config.sideLength * Math.cos(angle);
secondRow.push(new Hexagon(centerX, centerY, config.sideLength));
secondRowCount++;
}
hexagons = firstGroup.flat();
let hexagonPaths = hexagons.map((hexagon) => hexagon.getPath());
/* -------------------------------------------------------------------------- */
canvasView.on("draw", (canvas) => {
canvas.drawColor(canvasBgColor);
for (let i = 0; i < hexagonPaths.length; i++) {
canvas.drawPath(hexagonPaths[i], paint);
}
});
這是一個(gè)二維數(shù)組, 我們用flat抹平成一維數(shù)組
一組一組的計(jì)算坐標(biāo)
y坐標(biāo)依次增長(zhǎng)3個(gè)邊長(zhǎng)即可

先計(jì)算第一排, 再計(jì)算第二排
let row = 1;
while (1) {
let nextGroupFirstRow = [];
let nextGroupSecondRow = [];
let nextGroup = [nextGroupFirstRow, nextGroupSecondRow];
let firstGroupFirstRow = firstGroup[0];
let firstGroupFirstHexagon = firstGroupFirstRow[0];
if (firstGroupFirstHexagon.centerY + config.sideLength * 3 * row > canvasHeight) {
break;
}
nextGroupFirstRow = firstGroupFirstRow.map((hexagon) => {
let centerX = hexagon.centerX;
let centerY = hexagon.centerY + config.sideLength * 3 * row;
nextGroupFirstRow.push(new Hexagon(centerX, centerY, config.sideLength));
});
let firstGroupSecondRow = firstGroup[1];
let firstGroupSecondHexagon = firstGroupSecondRow[0];
if (firstGroupSecondHexagon.centerY + config.sideLength * 3 * row > canvasHeight) {
break;
}
nextGroupSecondRow = firstGroupSecondRow.map((hexagon) => {
let centerX = hexagon.centerX;
let centerY = hexagon.centerY + config.sideLength * 3 * row;
nextGroupSecondRow.push(new Hexagon(centerX, centerY, config.sideLength));
});
groups.push(nextGroup);
row++;
}
hexagons = groups.flat(2);
let hexagonPaths = hexagons.map((hexagon) => hexagon.getPath());
環(huán)境
設(shè)備: 小米11pro
Android版本: 12
Autojs版本: 9.3.11
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文檔, autojs文檔, 最后才是群里問問 ---
部分內(nèi)容來自網(wǎng)絡(luò) 本教程僅用于學(xué)習(xí), 禁止用于其他用途
以上就是autojs畫六邊形實(shí)現(xiàn)示例詳解的詳細(xì)內(nèi)容,更多關(guān)于autojs繪畫實(shí)現(xiàn)六邊形的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序 wx.request(OBJECT)發(fā)起請(qǐng)求詳解
這篇文章主要介紹了微信小程序 wx.request(OBJECT)發(fā)起請(qǐng)求詳解的相關(guān)資料,需要的朋友可以參考下2016-10-10
關(guān)于JavaScript?中?if包含逗號(hào)表達(dá)式
這篇文章主要介紹了?關(guān)于JavaScript?中?if包含逗號(hào)表達(dá)式,有時(shí)會(huì)看到JavaScript中if判斷里包含英文逗號(hào)?“,”,這個(gè)是其實(shí)是逗號(hào)表達(dá)式。在if條件里,只有最后一個(gè)表達(dá)式起判斷作用。下面來看看文章的具體介紹吧2021-11-11
微信小程序 免費(fèi)SSL證書https、TLS版本問題的解決辦法
這篇文章主要介紹了微信小程序 免費(fèi)SSL證書https、TLS版本問題的解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12
Javascript中彈窗confirm與prompt的區(qū)別
今天小編就為大家分享一篇關(guān)于Javascript中彈窗confirm與prompt的區(qū)別,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10
JS前端模擬Excel條件格式實(shí)現(xiàn)數(shù)據(jù)條效果
這篇文章主要為大家介紹了JS前端模擬Excel條件格式實(shí)現(xiàn)數(shù)據(jù)條效果,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Servlet3.0與純javascript通過Ajax交互的實(shí)例詳解
Servlet與純javascript通過Ajax交互,對(duì)于很多人來說應(yīng)該很簡(jiǎn)單。不過還是寫寫,方便Ajax學(xué)習(xí)的后來者2018-03-03
Vite項(xiàng)目自動(dòng)添加eslint prettier源碼解讀
這篇文章主要為大家介紹了Vite項(xiàng)目自動(dòng)添加eslint prettier源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
THREE.js添加多個(gè)castShadow光源報(bào)錯(cuò)解決及原因分析
這篇文章主要介紹了THREE.js添加多個(gè)castShadow的光源報(bào)錯(cuò)解決及原因分析2023-06-06

