您的位置:奥门新浦京网址 > Wed前段 > 使用Canvas实时处理Video,一个前端开发工程师的

使用Canvas实时处理Video,一个前端开发工程师的

发布时间:2019-10-14 18:31编辑:Wed前段浏览(188)

    一个前端开发工程师的Vim跟IDE一样

    2017/01/18 · 基础技术 · vim

    原文出处: 小弟调调   

    这里是我新配置出来的 jaywcjlove/vim-web 一直在打磨中,基本上可以用了。拿出来骗 star 先上图

    图片 1

    当你打开网页的时候,世界都发生了什么(1)

    2015/09/10 · HTML5, JavaScript · 网页

    原文出处: 吴迪   

    你有没有好奇过,当你试图打开一个网页的时候,这个世界上都发生了一些什么事情?会不会因为你手气键落,产生了蝴蝶效应,指尖的风拂起千年后你梦中的那个女孩的刘海?咳,也不是没有可能。今天我就来告诉你会发生什么事情,你可以沏一壶茶,坐在躺椅上,慢慢品味……

    时光倒流到你刚才打开这个页面的那一瞬间…

    Hi!大家好,我的名字叫做浏览器,我还有个很酷的英文名字叫做Browser!很高兴认识你!

    图片 2

    什么,你想上百度?没问题!请你告诉我一下,百度的地址是什么?或者说,百度的URL是什么?

    对了,给你介绍一下URL,全称Unified Resource Locator,中文名为统一资源定位符,也就是我们俗称的网址。它就像互联网上的门牌一样,而浏览器就好像的士司机。你只要告诉浏览器你想要看的网页的URL,他就会把你载到那里啦!

    图片 3

    嗯,百度的地址是http://baidu.com是吧,好嘞!我现在就开始帮你去把这个网页给请过来。

    首先,我先要找到这个网页的家在哪里。网页的家有一个名字叫做服务器,它的英文名叫做Server。服务器本身其实也是一台电脑,跟你家中的电脑其实是非常相似的。只不过相比起来,服务器性能会比普通的电脑的性能来得强劲,因为它需要服务成千上万个人!

    图片 4

    那么这么多的服务器,我怎么找到百度所在的那个服务器呢?就靠你刚才告诉我的URL了!URL只是服务器地址的一个比较好听的名字而已,我没有办法直接通过这个地址找到服务器。其实啊,在服务器的世界里面,他们还有一种更精确的地址表达方式,叫做IP地址。

    插一嘴:IP地址是什么,它是怎么工作的,恐怕可以写好几本书了。简单地说,IP地址就是形同192.168.0.1这种形式的数字和英文句号的组合。你可以把它当做相对URL来讲更加准确的地址。

    我找到IP地址的方式其实很简单,我只要请操作系统(OS, Operating System)帮忙就好了。所谓的操作系统,就是类似Windows、Mac OS一样的软件,你能够在它们上面安装各种各样的软件。其中Mac OS是苹果电脑专用的操作系统。

    图片 5

    这个从URL到IP地址的过程叫做DNS查找,即DNS Lookup。天啊,又一个新名词!没关系,你不需要记住这个名词。你所需要知道的是,这里看似操作系统独自很快地完成了这个过程,但是其实它为此所做的事情相当复杂。我们今后将有专门的文章用来介绍这一过程。

    HTML5:使用Canvas实时处理Video

    2015/09/11 · HTML5 · Canvas

    本文由 伯乐在线 - cucr 翻译,唐尤华 校稿。未经许可,禁止转载!
    英文出处:mozilla。欢迎加入翻译组。

    结合HTML5下的videocanvas的功能,你可以实时处理视频数据,为正在播放的视频添加各种各样的视觉效果。本教程演示如何使用JavaScript代码实现chroma-keying特效(也被称为“绿色屏幕效应”)。

    请看这个实例.

    安装

    最新版本的Vim 7.4+ 使用(brew install macvim)安装,vim 版本更新 brew install macvim --override-system-vim

    Shell

    $ git clone ~/.vim $ ln -s ~/.vim/.vimrc ~/.vimrc # 上面执行完成之后 # 开始下载安装插件 $ vim # 在vim中运行 ":PlugInstall" # 上面插件安装完成之后执行下面内容 # command-t 文件搜索插件安装 $ cd ~/.vim/plugged/command-t $ rake make # 搜索文本内容工具 # 需要安装 CtrlSF的依赖ripgrep $ brew install ripgrep # 代码提示插件也需要你运行安装哦,不然没有效果嘞 cd ~/.vim/plugged/YouCompleteMe ./install.sh # 需要安装ctags 不然配置没效果哦 # ctags for Mac $ brew install ctags # ctags for Centos7 $ yum install ctags

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    $ git clone https://github.com/jaywcjlove/vim-web.git ~/.vim
    $ ln -s ~/.vim/.vimrc ~/.vimrc
     
    # 上面执行完成之后
    # 开始下载安装插件
    $ vim # 在vim中运行 ":PlugInstall"
     
    # 上面插件安装完成之后执行下面内容
    # command-t 文件搜索插件安装
    $ cd ~/.vim/plugged/command-t
    $ rake make
     
    # 搜索文本内容工具
    # 需要安装 CtrlSF的依赖ripgrep
    $ brew install ripgrep
     
    # 代码提示插件也需要你运行安装哦,不然没有效果嘞
    cd ~/.vim/plugged/YouCompleteMe
    ./install.sh
     
    # 需要安装ctags 不然配置没效果哦
    # ctags for Mac
    $ brew install ctags
    # ctags for Centos7
    $ yum install ctags

    注: 默认已经安装了前端必备插件。.vimrc 是控制 vim 行为的配置文件,位于 ~/.vimrc,不论 vim 窗口外观、显示字体,还是操作方式、快捷键、插件属性均可通过编辑该配置文件将 vim 调教成最适合你的编辑器。

    建立连接和发送请求

    已经顺利拿到了服务器的IP地址,接下来我就要向他要东西啦!首先我希望它把baidu.com对应的网页传送给我。我们之间传输信息的方式比较特殊,不需要我坐地铁去找它然后搬回来,而是我会跟服务器建立一个连接

    连接,英文名叫做Connection。实际上,它就像开辟了一个专用的通道,供我们互相之间传递信息。

    图片 6

    接下来,我就会通过这个专用通道,向服务器发起一个请求(Request)。在这个请求里面,我会像服务器阐明我想要的资源是什么,例如在这里,我想要的资源就是百度的首页。

    那么具体这个资源的位置我是怎么告诉服务器的呢?还得回到刚才的URL来说!

    图片 7

    一个URL一般由六个部分组成,这里我们只介绍主机名(服务器名)和资源位置(或者说是资源路径)。一个服务器上可以有很多的资源,对应着不同的页面或者文件,例如http://xxx.com/login可以是某网站的登录页面,http://xxx.com/register则可以是某网站的注册页面。这里的/login/register就代表了两个不同的资源(这里是页面)。/是比较特殊的资源路径,叫做“根路径”,通常就是网站的首页了。其实,这里的原理就和我们电脑上的文件夹是一模一样的。

    在知道了需要的资源的位置之后,我就会给服务器发送一个请求。这个请求实际上就是一系列的英文字符,就像一篇文章一样。

    GET / HTTP/1.1 User-Agent: curl/7.37.1 Host: baidu.com Accept: */*

    1
    2
    3
    4
    GET / HTTP/1.1
    User-Agent: curl/7.37.1
    Host: baidu.com
    Accept: */*

    怎么样,我也是很有文采的吧!在这里,你需要知道的是,GET /即代表,我现在要从服务器上拿下来一个资源,这个资源的位置是/。另外,Host: baidu.com代表我要请求的主机名叫做baidu.com。Host这个英文单词就是有主机的意思!

    好了,请求已经准备完毕了,我现在就通过之前建立的连接将这个请求直接送给服务器!

    文档内容

    本文使用的XHTML文档如下所示。

    XHTML

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "; <html xmlns="; <head> <style> body { background: black; color:#CCCCCC; } #c2 { background-image: url(foo.png); background-repeat: no-repeat; } div { float: left; border :1px solid #444444; padding:10px; margin: 10px; background:#3B3B3B; } </style> <script type="text/javascript;version=1.8" src="main.js"></script> </head> <body onload="processor.doLoad()"> <div> <video id="video" src="video.ogv" controls="true"/> </div> <div> <canvas id="c1" width="160" height="96"/> <canvas id="c2" width="160" height="96"/> </div> </body> </html>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <style>
          body {
            background: black;
            color:#CCCCCC;
          }
          #c2 {
            background-image: url(foo.png);
            background-repeat: no-repeat;
          }
          div {
            float: left;
            border :1px solid #444444;
            padding:10px;
            margin: 10px;
            background:#3B3B3B;
          }
        </style>
        <script type="text/javascript;version=1.8" src="main.js"></script>
      </head>
     
      <body onload="processor.doLoad()">
        <div>
          <video id="video" src="video.ogv" controls="true"/>
        </div>
        <div>
          <canvas id="c1" width="160" height="96"/>
          <canvas id="c2" width="160" height="96"/>
        </div>
      </body>
    </html>

    以上代码关键部分如下:

    1.创建了两个canvas元素,ID分别为c1和c2。c1用于显示当前帧的原始视频,c2是用来显示执行chroma-keying特效后的视频;c2预加载了一张静态图片,将用来取代视频中的背景色部分。
    2.JavaScript代码从main.js文件导入;这段脚本使用JavaScript 1.8的特性,所以在导入脚本时,第22行中指定了版本。
    3.当网页加载时,main.js中的processor.doLoad()方法会运行。

    查看配置位置

    Shell

    # 进入vim输入下面字符 :echo $MYVIMRC

    1
    2
    # 进入vim输入下面字符
    :echo $MYVIMRC

    获得响应

    当服务器获得请求之后,经过一系列的工作(可能是类似翻箱倒柜找材料之类的吧),最后将要送还给我的材料,包括网页的代码,全部打包起来形成一个响应(Response),通过连接返回给我。

    响应是和请求对应的,一个请求对应一个响应。这就好像问问题一样,一问一答。所以,响应本身其实也就是一系列的英文字符,就像这样:(下面的响应是被简化的版本)

    HTTP/1.1 200 OK Date: Mon, 31 Aug 2015 03:06:34 GMT Server: Apache Cache-Control: max-age=86400 Expires: Tue, 01 Sep 2015 03:06:34 GMT Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT ETag: "51-4b4c7d90" Accept-Ranges: bytes Content-Length: 81 Connection: Keep-Alive Content-Type: text/html <html> .... 此处省略N多行 </html>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    HTTP/1.1 200 OK
    Date: Mon, 31 Aug 2015 03:06:34 GMT
    Server: Apache
    Cache-Control: max-age=86400
    Expires: Tue, 01 Sep 2015 03:06:34 GMT
    Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
    ETag: "51-4b4c7d90"
    Accept-Ranges: bytes
    Content-Length: 81
    Connection: Keep-Alive
    Content-Type: text/html
     
    <html>
        .... 此处省略N多行
    </html>

    你可以注意到,响应分为两个部分。在13行之上的部分称作响应头(Response Head),下面的部分称作响应主体(Response Body)。在这里,响应主体就是网页的代码了。

    图片 8

    好了,到目前为止,我已经拿到了网页的代码。

    JavaScript代码

    main.js中的JS代码包含三个方法。

    插件管理

    这里面刚开始使用的Vim插件管理工具VundleVim/Vundle.vim,后面为了大家安装方便,使用了 junegunn/vim-plug,这个插件管理工具,俺十分不喜欢,多了个 autoload 目录,安装过程也奇丑无比,安装快速,所以就使用它吧,下面命令更新安装的 plug.vim,默认已经有了不需要这一步。

    Shell

    curl -fLo ~/.vim/autoload/plug.vim --create-dirs

    1
    2
    curl -fLo ~/.vim/autoload/plug.vim --create-dirs
        https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

    等等…啥是代码?

    好问题!

    网页本身其实是由一系列的英文字符编写成的,这些英文字符称作“代码”(Code)。这些英文字符和普通的英文文章看起来差不多,但是它们都是用一种我(浏览器)可以看得懂的格式写成的。我通过阅读这些英文字符,理解它,然后按照它的意思将你想要看的页面渲染出来。

    别急,关于这些,我们在接下来的文章中慢慢道来。

    1 赞 2 收藏 评论

    图片 9

    初始化chroma-key

    doLoad()方法在XHTML文档初始加载时调用。这个方法的作用是为chroma-key处理代码准备所需的变量,设置一个事件侦听器,当用户开始播放视频时我们能检测到。

    JavaScript

    doLoad: function() { this.video = document.getElementById("video"); this.c1 = document.getElementById("c1"); this.ctx1 = this.c1.getContext("2d"); this.c2 = document.getElementById("c2"); this.ctx2 = this.c2.getContext("2d"); let self = this; this.video.addEventListener("play", function() { self.width = self.video.videoWidth / 2; self.height = self.video.videoHeight / 2; self.timerCallback(); }, false); },

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    doLoad: function() {
        this.video = document.getElementById("video");
        this.c1 = document.getElementById("c1");
        this.ctx1 = this.c1.getContext("2d");
        this.c2 = document.getElementById("c2");
        this.ctx2 = this.c2.getContext("2d");
        let self = this;
        this.video.addEventListener("play", function() {
            self.width = self.video.videoWidth / 2;
            self.height = self.video.videoHeight / 2;
            self.timerCallback();
          }, false);
      },

    这段代码获取XHTML文档中video元素和两个canvas元素的引用,还获取了两个canvas的图形上下文的引用。这些将在我们实现chroma-keying特效时使用。

    addEventListener()监听video元素,当用户按下视频上的播放按钮时被调用。为了应对用户回放,这段代码获取视频的宽度和高度,并且减半(我们将在执行chroma-keying效果时将视频的大小减半),然后调用timerCallback()方法来启动视频捕捉和视觉效果计算。

    安装插件

    将配置信息其加入 ~/.vim/.vimrc 中的call plug#begin()call plug#end() 之间,最后进入 vim 输入下面命令,摁 enter 进行安装。

    Shell

    :PlugInstall

    1
    :PlugInstall

    定时器回调

    定时器回调函数在视频开始播放时被调用(当“播放”事件发生时),然后负责自身周期调用,为每一帧视频实现keying特效。

    JavaScript

    timerCallback: function() { if (this.video.paused || this.video.ended) { return; } this.computeFrame(); let self = this; setTimeout(function () { self.timerCallback(); }, 0); },

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    timerCallback: function() {
        if (this.video.paused || this.video.ended) {
          return;
        }
        this.computeFrame();
        let self = this;
        setTimeout(function () {
            self.timerCallback();
          }, 0);
      },

    回调函数首先检查视频是否正在播放;如果没有,回调函数不做任何事并立即返回。

    然后调用computeFrame()方法,该方法对当前视频帧执行chroma-keying特效。

    回调函数做的最后一件事就是调用setTimeout(),来让它自身尽快地被重新调用。在真实环境中,你可能会基于视频的帧率来设置调用频率。

    更新插件

    插件更新频率较高,差不多每隔一个月你应该看看哪些插件有推出新版本,批量更新,只需在 vim 中执行下面命令即可。

    Vim

    :PlugUpdate

    1
    :PlugUpdate

    处理视频帧数据

    computeFrame()方法,如下所示,实际上负责抓取每一帧的数据和执行chroma-keying特效。

    JavaScript

    computeFrame: function() { this.ctx1.drawImage(this.video, 0, 0, this.width, this.height); let frame = this.ctx1.getImageData(0, 0, this.width, this.height); let l = frame.data.length / 4; for (let i = 0; i < l; i++) { let r = frame.data[i * 4 + 0]; let g = frame.data[i * 4 + 1]; let b = frame.data[i * 4 + 2]; if (g > 100 && r > 100 && b < 43) frame.data[i * 4 + 3] = 0; } this.ctx2.putImageData(frame, 0, 0); return; }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    computeFrame: function() {
        this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
        let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
        let l = frame.data.length / 4;
     
        for (let i = 0; i < l; i++) {
          let r = frame.data[i * 4 + 0];
          let g = frame.data[i * 4 + 1];
          let b = frame.data[i * 4 + 2];
          if (g > 100 && r > 100 && b < 43)
            frame.data[i * 4 + 3] = 0;
        }
        this.ctx2.putImageData(frame, 0, 0);
        return;
      }

    当它被调用后,video元素将显示最近的视频帧数据,如下所示:

    图片 10

    在第2行,视频帧被复制到第一个canvas ctx1的图形上下文中,高度和宽度值指定为我们之前保存的帧大小的一半。注意,您可以通过传递video元素到绘图上下文的drawImage()方法来绘制当前视频帧。其结果是:

    图片 11

    第3行代码通过调用第一个canvas上下文的getImageData()方法,来获取原始图像数据当前视频帧的一个副本。它提供了原始的32位像素图像数据,这样我们就能够进行操作。第4行代码通过将帧图像数据的总长度除以4,来计算图像的总像素数。

    第6行代码循环扫描所有像素,获取每个像素的红、绿、蓝值,同时和预定义的背景色进行比较,这些背景色将用foo.png中导入的背景图像替换。

    被检测成背景的每一个像素,将它的alpha值替换为零,表明该像素是完全透明的。结果,最终的图像背景部分是100%透明的,这样在第13行代码,把它被绘制到目标的上下文中时,效果是内容叠加到静态背景上。

    由此产生的图像看起来像这样:

    图片 12

    在视频播放时反复这样做,这样一帧接一帧处理,呈现出chroma-key的特效。

    请看这个实例。

    1 赞 1 收藏 评论

    卸载插件

    先在 .vimrc 中注释或者删除对应插件配置信息,然后在 vim 中执行下面命令,即可删除对应插件。

    Vim

    :PlugClean

    1
    :PlugClean

    关于作者:cucr

    图片 13

    新浪微博:@hop_ping 个人主页 · 我的文章 · 17

    图片 14

    启动Vim

    Shell

    $ vim

    1
    $ vim

    常用快捷键

    这里的快捷键是我配置好的可用的。

    Vim

    ;fl # 换出菜单列表 nw # 窗口切换 ;lw # 跳转至右方的窗口 ;hw # 跳转至左方的窗口 ;kw # 跳转至上方的子窗口 ;jw # 跳转至下方的子窗口 # 可以直接在Tab之间切换。 gt # 后一个Tab标签 gT # 前一个Tab标签 ;q # 关闭一个标签 ctrl-f # 下一页 f 就是`forword` ctrl-b # 上一页 b 就是`backward` ;t # 通过搜索文件打开文件 # 快速文本内定位 ;;b # 光标前代码定位 ;;e # 光标后代码定位 ;;f # 光标后代码定位 <搜索自负> 出现定位信息 ;;F # 光标前代码定位 <搜索自负> 出现定位信息 ;ilt # 设置显示/隐藏标签列表子窗口(函数列表)的快捷键。速记:identifier list by tag 0 # 行首 $ # 行尾 :r ~/git/R.js # 将文件内容导入到该文件中 :!which ls # 找命令不推出vim运行命令 :!date # 查看编辑时间 :r !date # 将当前编辑时间导入当前文本光标所在行 U # 选中 - 变大写 u # 选中 - 变小写 ~ # 选中 - 变大写变小写,小写变大写 ;cc # 代码注释"//" ;cm # 代码段落注释"/**/" ;ci # 注释相反,注释的取消注释,没注释的注释 ;cs # 段落注释,注释每行前面加"*" ;c$ # 光标开始到行结束的位置注释 ;cA # 在行尾部添加注释符"//" ;cu # 取消代码注释 za # 单个代码折叠 zM # 折叠左右代码 zR # 所有代码折叠取消 ;i # 开/关缩进可视化 > # 代码锁进 - 选中摁尖括号 < # 代码锁进 - 选中摁尖括号 :1,24s/header/www/g # 第1到24行将header替换成www <c-z> # 退出Vim

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    ;fl # 换出菜单列表
    nw  # 窗口切换
    ;lw # 跳转至右方的窗口
    ;hw # 跳转至左方的窗口
    ;kw # 跳转至上方的子窗口
    ;jw # 跳转至下方的子窗口
     
     
    # 可以直接在Tab之间切换。
    gt # 后一个Tab标签
    gT # 前一个Tab标签
    ;q # 关闭一个标签
     
    ctrl-f # 下一页 f 就是`forword`
    ctrl-b # 上一页 b 就是`backward`  
     
    ;t # 通过搜索文件打开文件
     
    # 快速文本内定位
    ;;b # 光标前代码定位
    ;;e # 光标后代码定位
    ;;f # 光标后代码定位 <搜索自负> 出现定位信息
    ;;F # 光标前代码定位 <搜索自负> 出现定位信息
     
    ;ilt # 设置显示/隐藏标签列表子窗口(函数列表)的快捷键。速记:identifier list by tag
     
    0   # 行首
    $   # 行尾
     
    :r ~/git/R.js # 将文件内容导入到该文件中
    :!which ls  # 找命令不推出vim运行命令
    :!date      # 查看编辑时间
    :r !date    # 将当前编辑时间导入当前文本光标所在行
     
    U # 选中 - 变大写
    u # 选中 - 变小写
    ~ # 选中 - 变大写变小写,小写变大写
     
    ;cc # 代码注释"//"
    ;cm # 代码段落注释"/**/"
    ;ci # 注释相反,注释的取消注释,没注释的注释
    ;cs # 段落注释,注释每行前面加"*"
    ;c$ # 光标开始到行结束的位置注释
    ;cA # 在行尾部添加注释符"//"
    ;cu # 取消代码注释
     
    za # 单个代码折叠
    zM # 折叠左右代码
    zR # 所有代码折叠取消
     
    ;i  # 开/关缩进可视化
    >   # 代码锁进 - 选中摁尖括号
    <   # 代码锁进 - 选中摁尖括号
     
    :1,24s/header/www/g  # 第1到24行将header替换成www
     
    <c-z>  # 退出Vim

    基础使用

    • inoremap (Insert Mode)就只在插入(insert)模式下生效
    • vnoremap (Visual Mode)只在visual模式下生效
    • nnoremap (Normal Mode)就在normal模式下(狂按esc后的模式)生效
    • 快捷键<c-y>, 标示(Ctrly,)

    快捷键通配符

    快捷键通配符 <leader> 相当于是一个通用的命令符,默认好像是,你可以在.vimrc中将他改为任意一个按键,在我们这个配置我改为了冒号;

    Vim

    " 定义快捷键的前缀,即 <Leader> let mapleader=";"

    1
    2
    " 定义快捷键的前缀,即 <Leader>
    let mapleader=";"

    插入命令

    Vim

    a # → 在光标所在字符后插入 A # → 在光标所在字符尾插入 i # → 在光标所在字符前插入 I # → 在光标所在行行首插入 o # → 在光标下插入新行 O # → 在光标上插入新行

    1
    2
    3
    4
    5
    6
    a # → 在光标所在字符后插入  
    A # → 在光标所在字符尾插入  
    i # → 在光标所在字符前插入  
    I # → 在光标所在行行首插入  
    o # → 在光标下插入新行  
    O # → 在光标上插入新行

    删除命令

    Vim

    x # → 删除关闭所在处字符 nx # → 删除关闭所在处n个字符 dd # → 删除光标所在行, ndd # → 删除n行 dG # → 删除光标所在行到文件末尾内容 D # → 删除光标所在处到行尾内容 :n1,n2d # → 删除指定范围的行 如:1,2d

    1
    2
    3
    4
    5
    6
    7
    x   # → 删除关闭所在处字符  
    nx  # → 删除关闭所在处n个字符  
    dd  # → 删除光标所在行,
    ndd # → 删除n行  
    dG  # → 删除光标所在行到文件末尾内容  
    D   # → 删除光标所在处到行尾内容  
    :n1,n2d # → 删除指定范围的行 如:1,2d

    定位命令

    Vim

    :set number #→ 设置行号 简写set nu :set nonu #→ 取消行号 gg #→ 到第一行 G #→ 到最后一行 nG #→ 到第n行 :n #→ 到第n行 S #→ 移至行尾 0 #→ 移至行尾 hjkl #→ 前下上后 w #→ 到下一个单词的开头 b #→ 与w相反 e #→ 到下一个单词的结尾。 ge #→ 与e相反 0 #→ 到行头 ^ #→ 到本行的第一个非blank字符 $ #→ 到行尾 g_ #→ 到本行最后一个不是blank字符的位置。 fa #→ 到下一个为a的字符处,你也可以fs到下一个为s的字符。 t, #→ 到逗号前的第一个字符。逗号可以变成其它字符。 3fa #→ 在当前行查找第三个出现的a。 F 和 T → 和 f 和 t 一样,只不过是相反方向。 zz # 将当前行置于屏幕中间(不是转载…) zt # 将当前行置于屏幕顶端(不是猪头~) zb # 底端啦~

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    :set number   #→ 设置行号 简写set nu  
    :set nonu   #→ 取消行号  
    gg  #→ 到第一行  
    G   #→ 到最后一行  
    nG  #→ 到第n行  
    :n  #→ 到第n行  
    S   #→ 移至行尾  
    0   #→ 移至行尾  
    hjkl #→ 前下上后  
     
    w   #→ 到下一个单词的开头  
    b   #→ 与w相反  
    e   #→ 到下一个单词的结尾。  
    ge  #→ 与e相反  
     
    0   #→ 到行头  
    ^   #→ 到本行的第一个非blank字符  
    $   #→ 到行尾  
    g_  #→ 到本行最后一个不是blank字符的位置。  
    fa  #→ 到下一个为a的字符处,你也可以fs到下一个为s的字符。  
    t,  #→ 到逗号前的第一个字符。逗号可以变成其它字符。  
    3fa #→ 在当前行查找第三个出现的a。  
    F 和 T → 和 f 和 t 一样,只不过是相反方向。  
     
    zz # 将当前行置于屏幕中间(不是转载…)  
    zt # 将当前行置于屏幕顶端(不是猪头~)  
    zb # 底端啦~

    本文由奥门新浦京网址发布于Wed前段,转载请注明出处:使用Canvas实时处理Video,一个前端开发工程师的

    关键词: