当前位置: 首页 > 科技观察

萌哥,我们在Vscode里放烟花

时间:2023-03-19 18:24:26 科技观察

本文转载自微信公众号《神光的编程秘籍》,作者神说必有光zxg。转载本文请联系神光编程秘籍公众号。最近在研究vscode插件。今天给大家分享一个效果特别亮眼的插件,叫powermode。写代码的时候放烟花,小编会抖。效果很炫,但是我们一定不能满足于使用它,还要研究它是如何实现的。你可能对vscode中的实现没有任何想法,但是如果把这个效果放在网页上,编辑器会在文字变化的时候抖动,然后上面会出现一些烟花效果。一些同学可能对此有想法。抖动小编:抖动不也是一种动画吗,就是左右位移,一秒向右,下一秒又回到原来的位置,这样就抖动了。烟花效果:不管什么花哨的烟花,我们都可以用gif做,就是在文字上面加一个元素,然后把gif放在上面,下次加gif的时候把之前的gif删掉。这样就可以在网页中实现编辑器抖动+烟花效果。把这个效果放到vscode里面也是一样的思路,因为vscode是基于electron实现的。而electron是基于chromium+nodejs的,也就是ui部分是网页。我们可以在vscode帮助中打开开发者工具:那么,猛哥,你看,这个编辑器的一部分是一个div,那么刚才在网页中实现的效果,在vscode中也可以实现,思路是一样的。思路是一样的,但是怎么做呢?这就需要了解vscode的扩展api,其实并不难。介绍一下这里使用的api:首先导入vscode包,所有的api都在这个包里面。import*asvscodefrom'vscode';那么,我们要给文字添加样式,如何添加样式呢?在vscode的编辑器中添加样式,不是直接操作dom,是有限制的,所以分几个步骤:(萌哥,下面的步骤要一步一步来,不能跳过看)得到当前编辑器通过vscode.windowconstactiveEditor=vscode.window.activeTextEditor;获取当前编辑器的编辑位置constcursorPosition=activeTextEditor.selection.active;计算添加装饰范围(range)的位置constnewRange=newvscode.Range(cursorPosition.with(cursorPosition.line,cursorPosition.character),cursorPosition.with(cursorPosition.line,Math.max(0,cursorPosition.character+delta)));创建装饰对象vscode.window.createTextEditorDecorationType({before:{contentText:'',textDecoration:`none;${defaultCssString}${backgroundCssString}${customCssString}`,},textDecoration:`none;position:relative;`,rangeBehavior:vscode.DecorationRangeBehavior.ClosedClosed});然后,装饰这个范围的文本activeEditor.setDecorations(decoration,[newRange]);你已经完成了,现在我们在vscode编辑器中,你正在编辑的地方,添加段落样式。装饰对象可以添加前后。这不是伪元素吗?对,就是伪元素,还可以加上一系列的样式。您可以添加任何样式。至此,你知道如何在编辑器中制作那些效果了吗?接下来,我们来看一下power-mode的实现细节。代码实现先从效果实现说起,主要是摇晃和放烟花:我们分析过摇晃和摇晃的原理,就是每隔一段时间做一次位移。首先,它定义了一系列位移装饰对象,这是通过vscode.window.createTextEditorDecorationType创建装饰对象的API:publicactivate=()=>{this.dispose();this.negativeX=vscode.window.createTextEditorDecorationType({textDecoration:`none;margin-left:0px;`});this.positiveX=vscode.window.createTextEditorDecorationType({textDecoration:`none;margin-left:${this.config.shakeIntensity}px;`});this.negativeY=vscode.window.createTextEditorDecorationType({textDecoration:`none;margin-top:0px;`});this.positiveY=vscode.window。createTextEditorDecorationType({textDecoration:`none;margin-top:${this.config.shakeIntensity}px;`});this.shakeDecorations=[this.negativeX,this.positiveX,this.negativeY,this.positiveY];}然后呢?让编辑器定时抖动:根据编辑位置计算范围,然后用privateshake=()=>{if(!this.config.enableShake){return;}//currenteditorconstact修饰范围iveEditor=vscode.window.activeTextEditor;//摇动范围,即当前行constxRanges=[];for(leti=0;i0.5){activeEditor.setDecorations(this.negativeX,[]);activeEditor.setDecorations(this.positiveX,xRanges);}else{activeEditor.setDecorations(this.positiveX,[]);activeEditor.setDecorations(this.negativeX,xRanges);}if(Math.random()>0.5){activeEditor.setDecorations(this.negativeY,[]);activeEditor.setDecorations(this.positiveY,this.fullRange);}else{activeEditor.setDecorations(this.positiveY,[]);activeEditor.setDecorations(this.negativeY,this.fullRange);}clearTimeout(this.shakeTimeout);this.shakeTimeout=setTimeout(()=>{this.unshake();},1000);}如上,就是每隔一段时间加入不同的位移样式,随机把烟花摇起来和下,左,右,然后放烟花,我们已经分析过了他的思路,就是在编辑好的位置加一张gif,下次播放的时候去掉最后一张。回顾一下这个过程://当前编辑器constactiveEditor=vscode.window.activeTextEditor;//当前编辑位置constcursorPosition=vscode.window.activeTextEditor.selection.active;//要修饰的范围constdelta=left?-2:1;constnewRange=newvscode.Range(cursorPosition.with(cursorPosition.line,cursorPosition.character),cursorPosition.with(cursorPosition.line,Math.max(0,cursorPosition.character+delta)));//创建装饰对象constdecoration=vscode.window.createTextEditorDecorationType({before:{//beforestyle},textDecoration:`当前元素样式`,rangeBehavior:vscode.DecorationRangeBehavior.ClosedClosed});//给范围添加装饰activeEditor.setDecorations(装饰,[新范围]);添加装饰的过程我们已经完成了,但是样式还没有填充,怎么添加呢?首先当前元素要相对定位,然后加一个before伪元素,设置为绝对定位,left和top为负数。之后就是设置背景图片了,powermode提供了这么多gif选项。所以,装饰对象是这样的://背景图片的样式constbackgroundCss=this.getBackgroundCssSettings(explosionUrl);//位置的样式constdefaultCss={position:'absolute',[CSS_LEFT]:`-10px`,[CSS_TOP]:`-1.2rem`,宽度:`${this.config.explosionSize}ch`,高度:`${this.config.explosionSize}rem`,显示:`inline-block`,['z-index']:1,['pointer-events']:'none',};//样式对象转为字符串constbackgroundCssString=this.objectToCssString(backgroundCss);constdefaultCssString=this.objectToCssString(defaultCss);constcustomCssString=this.objectToCssString(this.config.customCss||{});//创建装饰对象constdecoration=vscode.window.createTextEditorDecorationType({before:{contentText:'',textDecoration:`none;${defaultCssString}${backgroundCssString}${customCssString}`,},textDecoration:`none;position:relative;`,rangeBehavior:vscode.DecorationRangeBehavior.ClosedClosed});大功告成,所以我们在vscode中实现了抖动和烟花。但是,必须添加一个触发器条目。什么时候触发?涉及两个API:编辑文本时出现效果vscode.workspace.onDidChangeTextDocument(onDidChangeTextDocument);当修改插件配置时,插件对象被重置vscode.workspace.onDidChangeConfiguration(onDidChangeConfiguration);从如何触发是的,我们都知道触发后要做什么。接下来介绍如何将这个插件注册到vscode中。插件注册注册插件就是在package.json中配置,指定触发时机:"activationEvents":["*"]指定插件入口:"main":./out/src/extension",指定插件的配置:"Contributes":{"configuration":{"title":"PowerMode","properties":{"powermode.enabled":{"default":false,//defaultvalue"type":"boolean",//valueType"description":"EnabletoactivatePOWERMODE!!!"}}}}总结Vscode基于electron,electron基于chromium,所以网页还是用来制作UI,网页中的那么多效果基本上都可以在编辑器中实现。但它是有约束的,所以需要熟悉整个装饰过程:获取当前编辑器(activeEditor)获取当前编辑位置(position)计算要装饰的范围(range)为此创建一个装饰对象(decorationType)range文字加装饰(addDecoration)抖动和烟花是基于这个api实现的,但是抖动是上下左右随机位移,在编辑位置添加烟花。既然有了实现的思路,就要指定触发入口,也就是编辑文本时(onDidChangeTextDocument)。还有必须处理的配置更改(onDidChangeConfiguration)。之后只要注册到vscode,在package.json中配置入口(main)、活动事件(activeEvent)、配置项(contibutes.configuration)即可。猛哥,让我们一起在vscode放烟花吧!