From 185ca22488920cf0f286e1287f68913d4ccfd75d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 14 Nov 2012 20:43:34 -0700 Subject: [PATCH] Make cursor blink by changing CSS visibility with `setInterval` This is actually more efficient than the CSS animation we were doing previously, because it doesn't force the cursor to be sampled at 60 FPS for something that changes around twice a second. --- spec/app/editor-spec.coffee | 8 ++++---- src/app/cursor-view.coffee | 33 ++++++++++++++++++++++++++++++--- src/app/editor.coffee | 2 +- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index b7719d7ed..a7023a11a 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -935,11 +935,11 @@ describe "Editor", -> editor.setSelectedBufferRange([[0, 0], [3, 0]]) expect(editor.getSelection().isEmpty()).toBeFalsy() - expect(cursorView).not.toBeVisible() + expect(cursorView.css('visibility')).toBe 'hidden' editor.setCursorBufferPosition([1, 3]) expect(editor.getSelection().isEmpty()).toBeTruthy() - expect(cursorView).toBeVisible() + expect(cursorView.css('visibility')).toBe 'visible' describe "auto-scrolling", -> it "only auto-scrolls when the last cursor is moved", -> @@ -1794,10 +1794,10 @@ describe "Editor", -> editor.setCursorScreenPosition([2,0]) expect(editor.lineElementForScreenRow(2)).toMatchSelector('.fold.selected') - expect(editor.find('.cursor').css('display')).toBe 'none' + expect(editor.find('.cursor').css('visibility')).toBe 'hidden' editor.setCursorScreenPosition([3,0]) - expect(editor.find('.cursor').css('display')).toBe 'block' + expect(editor.find('.cursor').css('visibility')).toBe 'visible' describe "when a selected fold is scrolled into view (and the fold line was not previously rendered)", -> it "renders the fold's line element with the 'selected' class", -> diff --git a/src/app/cursor-view.coffee b/src/app/cursor-view.coffee index 689e1a100..e684ed855 100644 --- a/src/app/cursor-view.coffee +++ b/src/app/cursor-view.coffee @@ -9,16 +9,19 @@ class CursorView extends View @content: -> @pre class: 'cursor idle', => @raw ' ' + blinkPeriod: 800 editor: null visible: true needsUpdate: true needsAutoscroll: true needsRemoval: false + shouldPauseBlinking: false initialize: (@cursor, @editor) -> - @cursor.on 'change-screen-position.cursor-view', (screenPosition, { bufferChange, autoscroll }) => + @cursor.on 'change-screen-position.cursor-view', (screenPosition, { autoscroll }) => @needsUpdate = true + @shouldPauseBlinking = true @needsAutoscroll = (autoscroll ? true) and @cursor?.isLastCursor() @editor.requestDisplayUpdate() @@ -43,9 +46,13 @@ class CursorView extends View unless _.isEqual(@lastPixelPosition, pixelPosition) changedPosition = true @css(pixelPosition) -# @removeIdleClassTemporarily() unless bufferChange @trigger 'cursor-move' + if @shouldPauseBlinking + @resetBlinking() + else if !@startBlinkingTimeout + @startBlinking() + @setVisible(@cursor.isVisible() and not @editor.isFoldedAtScreenRow(screenPosition.row)) getPixelPosition: -> @@ -54,7 +61,27 @@ class CursorView extends View setVisible: (visible) -> unless @visible == visible @visible = visible - @toggle(@visible) + if @visible + @css('visibility', '') + else + @css('visibility', 'hidden') + + toggleVisible: -> + @setVisible(not @visible) if @cursor.isVisible + + stopBlinking: -> + clearInterval(@blinkInterval) if @blinkInterval + @blinkInterval = null + @setVisible(true) if @cursor.isVisible + + startBlinking: -> + return if @blinkInterval? + blink = => @toggleVisible() + @blinkInterval = setInterval(blink, @blinkPeriod / 2) + + resetBlinking: -> + @stopBlinking() + @startBlinking() getBufferPosition: -> @cursor.getBufferPosition() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index cb8cb2f84..d401ec90b 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -768,7 +768,7 @@ class Editor extends View syncCursorAnimations: -> for cursorView in @getCursorViews() - do (cursorView) -> cursorView.resetCursorAnimation() + do (cursorView) -> cursorView.resetBlinking() autoscroll: (options={}) -> for cursorView in @getCursorViews() when cursorView.needsAutoscroll