vscode插件分享:看看它如何实现烟花抖动效果

1. vscode插件分享:看看它如何实现烟花抖动效果

对于程序员来说,vscode是必不可少的开发工具之一。而在vscode中,丰富的插件也是不可或缺的,它们能极大地提高我们的工作效率和开发体验。今天,我们来聊一聊一款有趣的插件——fireworks。

1.1 插件简介

Fireworks是一款提供了烟花抖动效果的vscode插件,它可以让你的代码编辑器变得更加有趣。

1.2 插件安装

安装Fireworks非常简单,只需要在vscode的扩展功能中搜索“fireworks”即可找到并安装。

1.3 插件使用

安装完成后,打开vscode,在编辑器任意位置右键点击,选择“Start Fireworks”即可激活烟花效果。

// 激活烟花效果的快捷键也可以在设置中进行设置

"fireworks.start": {

"command": "fireworks.start",

"key": "ctrl+alt+f",

"when": "editorTextFocus"

},

激活烟花效果后,编辑器将出现烟花抖动的效果,每个字符会随机移动一定的距离。同时,将光标移动到某个字符附近,也会触发烟花效果。

2. 插件源码分析

我们接下来来看一下Fireworks插件是如何实现烟花抖动效果的。

2.1 实现原理

Fireworks插件主要是通过修改编辑器的CSS样式来实现抖动效果。具体来说,它添加了对每个字符的CSS3动画效果,使它们不断灰度变化、位置不断移动。因此,只需要在CSS样式上添加对应的class即可实现想要的效果。

const baseInterval = 250;

const wcharInterval = 80;

const charMoveVal = '1px';

const keyframesPrefix = '-webkit-';

const toTransparentStr = 'rgba(255,255,255,0)';

const fromTransparentStr = 'rgba(255,255,255,1)';

const toTextShadowStr = '0 0 4px rgba(255,255,255,1)';

const fromTextShadowStr = '0 0 16px rgba(255,255,255,0)';

const className = 'fireworks-animation';

const charRegex = /[\S]/gu;

const whitespaceRegex = /\s/gu;

function getCharacterCSS(char: string, index: number): string {

const delay = `${baseInterval + wcharInterval * index}ms`;

const transfrom = `

translateX(${charMoveVal})

translateY(${charMoveVal})

scale(1.5)

rotate(3deg)

skew(-15deg, -15deg)

`;

return `

.${className}:nth-child(${index + 1})::after {

animation-delay: ${delay};

transform: ${transfrom};

text-shadow: ${toTextShadowStr};

color: ${fromTransparentStr};

animation-direction: alternate;

}

.${className}:nth-child(${index + 1})::before {

animation-delay: ${delay};

transform: ${transfrom};

text-shadow: ${toTextShadowStr};

color: ${toTransparentStr};

}

`;

}

function getWhitespaceCSS(index: number): string {

const delay = `${baseInterval + wcharInterval * index}ms`;

return `

.${className}:nth-child(${index + 1})::after {

animation-delay: ${delay};

text-shadow: ${fromTextShadowStr};

color: ${fromTransparentStr};

animation-direction: alternate;

}

.${className}:nth-child(${index + 1})::before {

animation-delay: ${delay};

text-shadow: ${fromTextShadowStr};

color: ${toTransparentStr};

}

`;

}

export function activate(context: ExtensionContext) {

let active = false;

const updateCSS = (editor: TextEditor) => {

const document = editor.document;

const text = document.getText();

const charsOnly = text.match(charRegex)?.join('').split('');

const full = text.split('');

let css = '';

if (charsOnly) {

const characters = charsOnly.map((char, index) =>

whitespaceRegex.test(char) ? getWhitespaceCSS(index) : getCharacterCSS(char, index),

);

css = characters.join('\n');

} else {

css = full.map((char, index) =>

whitespaceRegex.test(char) ? getWhitespaceCSS(index) : getCharacterCSS(char, index),

).join('\n');

}

const disposed = !editor || editor.document !== document;

if (active && !disposed) {

editor.setDecorations(styles, []);

}

if (active && !disposed) {

const decorations = full.map((_, index) => {

return {

range: new Range(new Position(0, index), new Position(0, index + 1)),

hoverMessage: ''

};

});

editor.setDecorations(styles, decorations);

}

const cssClass = `.${className}::before, .${className}::after ${'{'}\n${css}\n${'}'}`;

const style = ``;

if (active && !disposed) {

editor.setDecorations(styles, []);

const pageStyle = document.getElementById('fireworks-stylesheet');

pageStyle?.remove();

document.body.removeChild(previewHTML);

} else if (active) {

active = false;

return;

}

const previewHTML = document.createElement('div');

const previewStyles = document.createElement('style');

previewHTML.id = 'fireworks-preview';

previewStyles.id = 'fireworks-stylesheet';

previewStyles.innerHTML = cssClass;

previewHTML.innerHTML = text.split('').map((char, index) => {

const klass = whitespaceRegex.test(char) ? 'whitespace' : `character ${className}`;

return `<${'span'} class="${klass}" style="animation-delay: ${baseInterval + wcharInterval * index}ms">${char}`;

}).join('');

document.body.append(previewHTML);

document.head.append(previewStyles);

active = true;

};

const styles = window.createTextEditorDecorationType({

color: { id: 'highlight' },

});

const editor = window.activeTextEditor;

if (editor) {

updateCSS(editor);

document.getElementById('workbench.editor.walkThrough.embeddedEditor')?.classList.add(className);

}

const subscriptions = context.subscriptions;

subscriptions.push(

window.onDidChangeActiveTextEditor(

editor => {

if (editor) {

updateCSS(editor);

document.getElementById('workbench.editor.walkThrough.embeddedEditor')?.classList.add(className);

}

},

null,

subscriptions,

),

);

subscriptions.push(

workspace.onDidChangeTextDocument(

event => {

const editor = window.activeTextEditor;

if (editor && event.document === editor.document) {

updateCSS(editor);

}

},

null,

subscriptions,

),

);

subscriptions.push(

workspace.onDidChangeConfiguration(() => {

const editor = window.activeTextEditor;

if (editor) {

updateCSS(editor);

}

}),

);

}

2.2 代码解析

上面的代码中,主要实现了以下几个功能:

生成一个CSS3的动画类,用来生成Fireworks的动画效果。

在打开编辑器后,向编辑器中插入用于生成动画的HTML元素。

在编辑器中监听文本的改变,并对新添加的文本生成动画效果。

重写编辑器的保存方法,当正在生成动画效果时,禁止删除生成动画的元素。

结合上述代码解释,Fireworks插件如何实现烟花抖动效果已经变得非常清晰和易懂了。

3. 总结

通过本文的学习,我们了解了一款基于vscode的抖动效果插件Fireworks,并且深度解析了它的实现原理。相信通过丰富的插件和学习,我们能够打造更加强大的IDE工具和编程环境,从而更轻松地进行开发工作。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。