Last active
February 2, 2019 06:24
-
-
Save think49/2a30b4e865f3dca4043440fb9b99a448 to your computer and use it in GitHub Desktop.
create-square-aa.js: 四角形のASCII Artを生成する
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* create-square-aa-1.0.1.js | |
* create ASCII art square. | |
* | |
* @version 1.0.1 | |
* @author think49 | |
* @url https://gist.github.com/think49/2a30b4e865f3dca4043440fb9b99a448 | |
* @license http://www.opensource.org/licenses/mit-license.php (The MIT License) | |
*/ | |
'use strict'; | |
var createSquareAa = (function (_min) { | |
return function createSquareAa (width, height, x, y, radius) { | |
var min = _min, canvas ='', whiteMark = '〇', blackMark = '◎', widthPlus, currentWidth, remainingHeight, whiteLine, leftWhiteLine, whiteWidth, whiteHeight, blackLine, blackSideLine, blackInnerWidth, blackInnerHeight; | |
width = +width || 0; | |
height = +height || 0; | |
x = +x || 0; | |
y = +y || 0; | |
radius = +radius || 0; | |
widthPlus = width + 1; | |
whiteLine = '\n'.padStart(widthPlus, whiteMark); | |
whiteWidth = x - radius; | |
whiteHeight = y - radius; | |
if (whiteWidth >= width || whiteHeight >= height) { | |
return ''.padEnd(widthPlus * height, whiteLine); | |
} | |
canvas = ''.padEnd(widthPlus * whiteHeight, whiteLine); | |
remainingHeight = height - (whiteHeight > 0 ? whiteHeight : 0); | |
blackInnerWidth = radius * 2 - 1; | |
if (whiteHeight >= 0) { | |
leftWhiteLine = ''.padEnd(whiteWidth, whiteMark); | |
blackLine = leftWhiteLine.padEnd(min(whiteWidth + blackInnerWidth + 2, width), blackMark).padEnd(width, whiteMark) + '\n'; | |
canvas += blackLine; | |
if (! --remainingHeight) { | |
return canvas; | |
} | |
} | |
if (radius > 0) { | |
blackInnerHeight = min(blackInnerWidth, whiteHeight + blackInnerWidth + 1, remainingHeight); | |
if (blackInnerHeight > 0) { | |
// console.log(blackInnerWidth, blackInnerHeight) | |
leftWhiteLine = leftWhiteLine || ''.padEnd(whiteWidth, whiteMark); | |
currentWidth = whiteWidth + 1; | |
blackSideLine = leftWhiteLine.padEnd(min(currentWidth, width), blackMark).padEnd(min(currentWidth += blackInnerHeight, width), whiteMark).padEnd(min(++currentWidth, width), blackMark).padEnd(width, whiteMark) + '\n'; | |
remainingHeight -= blackInnerHeight; | |
canvas += blackSideLine.padEnd(widthPlus * blackInnerHeight, blackSideLine); | |
if (!remainingHeight) { | |
return canvas; | |
} | |
} | |
if (blackInnerHeight >= 0) { | |
canvas += blackLine || (leftWhiteLine || ''.padEnd(whiteWidth, whiteMark)).padEnd(min(whiteWidth + blackInnerWidth + 2, width), blackMark).padEnd(width, whiteMark) + '\n'; | |
} | |
if (!--remainingHeight) { | |
return canvas; | |
} | |
} | |
return canvas.padEnd(widthPlus * height, whiteLine); | |
}; | |
}(Math.min)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>test - create-square-aa.js</title> | |
<style> | |
pre { | |
color: black; | |
background-color: #eee; | |
font-size: 50px; | |
font-family: monospace; | |
} | |
</style> | |
</head> | |
<body> | |
<pre id="canvas"></pre> | |
<script src="create-square-aa-1.0.1.js"></script> | |
<script> | |
'use strict'; | |
function appendTextNode (element, string) { | |
var doc = element.ownerDocument; | |
element.appendChild(doc.createTextNode(string + '\n\n')); | |
} | |
function main () { | |
var canvas = this.document.getElementById('canvas') | |
console.assert(createSquareAa(5, 5, 2, 2, 0) === '〇〇〇〇〇\n〇〇〇〇〇\n〇〇◎〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); // 5x5 中央位置(半径0) | |
console.assert(createSquareAa(5, 5, 2, 2, 1) === '〇〇〇〇〇\n〇◎◎◎〇\n〇◎〇◎〇\n〇◎◎◎〇\n〇〇〇〇〇\n'); // 5x5 中央位置(半径1) | |
console.assert(createSquareAa(5, 5, 2, 1, 1) === '〇◎◎◎〇\n〇◎〇◎〇\n〇◎◎◎〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); // 5x5 上にシフトする(半径1) | |
console.assert(createSquareAa(5, 5, 2, 0, 1) === '〇◎〇◎〇\n〇◎◎◎〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, 2, -1, 1) === '〇◎◎◎〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, 2, -2, 1) === '〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, 3, 2, 1) === '〇〇〇〇〇\n〇〇◎◎◎\n〇〇◎〇◎\n〇〇◎◎◎\n〇〇〇〇〇\n'); // 5x5 右にシフトする(半径1) | |
console.assert(createSquareAa(5, 5, 4, 2, 1) === '〇〇〇〇〇\n〇〇〇◎◎\n〇〇〇◎〇\n〇〇〇◎◎\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, 5, 2, 1) === '〇〇〇〇〇\n〇〇〇〇◎\n〇〇〇〇◎\n〇〇〇〇◎\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, 6, 2, 1) === '〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, 1, 2, 1) === '〇〇〇〇〇\n◎◎◎〇〇\n◎〇◎〇〇\n◎◎◎〇〇\n〇〇〇〇〇\n'); // 5x5 左にシフトする(半径1) | |
console.assert(createSquareAa(5, 5, 0, 2, 1) === '〇〇〇〇〇\n◎◎〇〇〇\n〇◎〇〇〇\n◎◎〇〇〇\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, -1, 2, 1) === '〇〇〇〇〇\n◎〇〇〇〇\n◎〇〇〇〇\n◎〇〇〇〇\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, -2, 2, 1) === '〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, 2, 3, 1) === '〇〇〇〇〇\n〇〇〇〇〇\n〇◎◎◎〇\n〇◎〇◎〇\n〇◎◎◎〇\n'); // 5x5 下にシフトする(半径1) | |
console.assert(createSquareAa(5, 5, 2, 4, 1) === '〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇◎◎◎〇\n〇◎〇◎〇\n'); | |
console.assert(createSquareAa(5, 5, 2, 5, 1) === '〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇◎◎◎〇\n'); | |
console.assert(createSquareAa(5, 5, 2, 6, 1) === '〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); | |
console.assert(createSquareAa(5, 5, 2, 2, 2) === '◎◎◎◎◎\n◎〇〇〇◎\n◎〇〇〇◎\n◎〇〇〇◎\n◎◎◎◎◎\n'); // 5x5 中央位置(半径2) | |
console.assert(createSquareAa(5, 5, 2, 2, 3) === '〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n〇〇〇〇〇\n'); // 5x5 中央位置(半径3) | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 2, 0)); // 5x5 中央位置(半径0) | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 2, 1)); // 5x5 中央位置(半径1) | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 1, 1)); // 5x5 上にシフトする(半径1) | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 0, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 2, -1, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 2, -2, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 3, 2, 1)); // 5x5 右にシフトする(半径1) | |
appendTextNode(canvas, createSquareAa(5, 5, 4, 2, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 5, 2, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 6, 2, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 1, 2, 1)); // 5x5 左にシフトする(半径1) | |
appendTextNode(canvas, createSquareAa(5, 5, 0, 2, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, -1, 2, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, -2, 2, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 3, 1)); // 5x5 下にシフトする(半径1) | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 4, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 5, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 6, 1)); | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 2, 2)); // 5x5 中央位置(半径2) | |
appendTextNode(canvas, createSquareAa(5, 5, 2, 2, 3)); // 5x5 中央位置(半径3) | |
} | |
main.call(this); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
teratail
teratailの下記質問の要件を元にコードを書きました。
Polyfill
本コードでは、ES2017 規定の
String.prototype.padStart
,String.prototype.padEnd
を利用しており、未対応ブラウザの為にPolyfillが必要となります。ベンチマーク
「キャンバスサイズの最大値: 1010 (※1)」「繰り返し回数: 1000回」でベンチマークをとってみました。
Lhankor_Mhy(初版), te2ji(type1 初版) に手を加えたコードの結果がこちら。
次の環境で実行しています。
(※1) テキストボックス入力値は「1000」ですが、関数 benchmark の処理で +10 しています。0x0のキャンバスでは有効値が取れないと思われる為の措置です。
(※2) ベンチマーク処理の都合上、引数の順番等の処理を一部変更しています。特に、raccyさんのコードは設計思想が大きく異なり、
rect
サイズを指定する為に追加処理を入れています。