黑客帝国代码特效(一招让妹子尖叫)(2)
时间:2022-12-30 22:05 来源:网络整理 作者:采集插件 点击:次
上面的代码中,使用了 CSI n;1m 的形式来定义颜色,其实是两种效果的,一个是具体颜色值,一个是加粗,一些命令行实现中会使用加粗效果来定义亮色。比如,如果直接定义 CSI 32 m 可能最终展示的是暗绿色,我们改成 CSI 32;1m 则将显示亮绿色。 颜色支持多种格式,上面的是 3-bit 和 4-bit 格式,同时还有 8-bit 和 24-bit。代码中也有使用样例,这里不再赘述了。 矩阵渲染在 matrix-rain 的代码中,index.js 里的核心功能是 MatrixRain 这个类: class MatrixRain { constructor(opts) {this.transpose = opts.direction === `h`;this.color = opts.color;this.charRange = opts.charRange;this.maxSpeed = 20;this.colDroplets = [];this.numCols = 0;this.numRows = 0;// handle reading from fileif (opts.filePath) {if (!fs.existsSync(opts.filePath)) {throw new Error(`${opts.filePath} doesn't exist`);}this.fileChars = fs.readFileSync(opts.filePath, `utf-8`).trim().split(``);this.filePos = 0;this.charRange = `file`;} } generateChars(len, charRange) {// by default charRange == asciilet chars = new Array(len);if (charRange === `ascii`) {for (let i = 0; i < len; i ) {chars[i] = String.fromCharCode(rand(0x21, 0x7E));}} else if (charRange === `braille`) {for (let i = 0; i < len; i ) {chars[i] = String.fromCharCode(rand(0x2840, 0x28ff));}} else if (charRange === `katakana`) {for (let i = 0; i < len; i ) {chars[i] = String.fromCharCode(rand(0x30a0, 0x30ff));}} else if (charRange === `emoji`) {// emojis are two character widths, so use a prefixconst emojiPrefix = String.fromCharCode(0xd83d);for (let i = 0; i < len; i ) {chars[i] = emojiPrefix String.fromCharCode(rand(0xde01, 0xde4a));}} else if (charRange === `file`) {for (let i = 0; i < len; i , this.filePos ) {this.filePos = this.filePos < this.fileChars.length ? this.filePos : 0;chars[i] = this.fileChars[this.filePos];}}return chars; } makeDroplet(col) {return {col,alive: 0,curRow: rand(0, this.numRows),height: rand(this.numRows / 2, this.numRows),speed: rand(1, this.maxSpeed),chars: this.generateChars(this.numRows, this.charRange),}; } resizeDroplets() {[this.numCols, this.numRows] = process.stdout.getWindowSize();// transpose for directionif (this.transpose) {[this.numCols, this.numRows] = [this.numRows, this.numCols];}// Create droplets per column// add/remove droplets to match column sizeif (this.numCols > this.colDroplets.length) {for (let col = this.colDroplets.length; col < this.numCols; col) {// make two droplets per row that start in random positionsthis.colDroplets.push([this.makeDroplet(col), this.makeDroplet(col)]);}} else {this.colDroplets.splice(this.numCols, this.colDroplets.length - this.numCols);} } writeAt(row, col, str, color) {// Only output if in viewportif (row >=0 && row < this.numRows && col >=0 && col < this.numCols) {const pos = this.transpose ? ansi.cursorPos(col, row) : ansi.cursorPos(row, col);write(`${pos}${color || ``}${str || ``}`);} } renderFrame() {const ansiColor = ansi.colors[`fg${this.color.charAt(0).toUpperCase()}${this.color.substr(1)}`]();for (const droplets of this.colDroplets) {for (const droplet of droplets) {const {curRow, col: curCol, height} = droplet;droplet.alive ;if (droplet.alive % droplet.speed === 0) {this.writeAt(curRow - 1, curCol, droplet.chars[curRow - 1], ansiColor);this.writeAt(curRow, curCol, droplet.chars[curRow], ansi.colors.fgWhite());this.writeAt(curRow - height, curCol, ` `);droplet.curRow ;}if (curRow - height > this.numRows) {// reset dropletObject.assign(droplet, this.makeDroplet(droplet.col), {curRow: 0});}}}flush(); }} 还有几个工具方法: // Simple string stream buffer stdout flush at oncelet outBuffer = [];function write(chars) { return outBuffer.push(chars);}function flush() { process.stdout.write(outBuffer.join(``)); return outBuffer = [];}function rand(start, end) { return start Math.floor(Math.random() * (end - start));} matrix-rain 的启动代码如下: const args = argParser.parseArgs();const matrixRain = new MatrixRain(args);function start() { if (!process.stdout.isTTY) {console.error(`Error: Output is not a text terminal`);process.exit(1); } // clear terminal and use alt buffer process.stdin.setRawMode(true); write(ansi.useAltBuffer()); write(ansi.cursorInvisible()); write(ansi.colors.bgBlack()); write(ansi.colors.fgBlack()); write(ansi.clearScreen()); flush(); matrixRain.resizeDroplets();}function stop() { write(ansi.cursorVisible()); write(ansi.clearScreen()); write(ansi.cursorHome()); write(ansi.useNormalBuffer()); flush(); process.exit();}process.on(`SIGINT`, () => stop());process.stdin.on(`data`, () => stop());process.stdout.on(`resize`, () => matrixRain.resizeDroplets());setInterval(() => matrixRain.renderFrame(), 16); // 60FPSstart(); 首先初始化一个 MatrixRain 类,然后调用 start 方法。start 方法中通过 MatrixRain 的 resizeDroplets 方法来初始化要显示的内容。 MatrixRain 类实例中管理着一个 colDroplets 数组,保存这每一列的雨滴。在 resizeDroplets 中我们可以看到,每一列有两个雨滴。 (责任编辑:admin) |
- 上一篇:大佬亲闺女成了豪门团宠最新章节(曲小兮)
- 下一篇:苹果电脑怎么重启「干货」