mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Don't blink cursors with CSS animation
It seems to create intermittent lags when moving the cursor and typing.
This commit is contained in:
@@ -58,7 +58,7 @@
|
||||
"temp": "0.5.0",
|
||||
"text-buffer": "^2.2.2",
|
||||
"theorist": "^1",
|
||||
"underscore-plus": "^1.2.2",
|
||||
"underscore-plus": "^1.3.0",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{extend, flatten, toArray, last} = require 'underscore-plus'
|
||||
_ = require 'underscore-plus'
|
||||
{extend, flatten, toArray, last} = _
|
||||
|
||||
ReactEditorView = require '../src/react-editor-view'
|
||||
nbsp = String.fromCharCode(160)
|
||||
|
||||
@@ -274,19 +276,22 @@ describe "EditorComponent", ->
|
||||
expect(cursorRect.width).toBe rangeRect.width
|
||||
|
||||
it "blinks cursors when they aren't moving", ->
|
||||
jasmine.unspy(window, 'setTimeout')
|
||||
|
||||
spyOn(_._, 'now').andCallFake -> window.now # Ensure _.debounce is based on our fake spec timeline
|
||||
cursorsNode = node.querySelector('.cursors')
|
||||
expect(cursorsNode.classList.contains('blinking')).toBe true
|
||||
|
||||
expect(cursorsNode.classList.contains('blink-off')).toBe false
|
||||
advanceClock(component.props.cursorBlinkPeriod / 2)
|
||||
expect(cursorsNode.classList.contains('blink-off')).toBe true
|
||||
advanceClock(component.props.cursorBlinkPeriod / 2)
|
||||
expect(cursorsNode.classList.contains('blink-off')).toBe false
|
||||
|
||||
# Stop blinking after moving the cursor
|
||||
editor.moveCursorRight()
|
||||
expect(cursorsNode.classList.contains('blinking')).toBe false
|
||||
expect(cursorsNode.classList.contains('blink-off')).toBe false
|
||||
|
||||
# Resume blinking after resume delay passes
|
||||
waits component.props.cursorBlinkResumeDelay
|
||||
runs ->
|
||||
expect(cursorsNode.classList.contains('blinking')).toBe true
|
||||
advanceClock(component.props.cursorBlinkResumeDelay)
|
||||
advanceClock(component.props.cursorBlinkPeriod / 2)
|
||||
expect(cursorsNode.classList.contains('blink-off')).toBe true
|
||||
|
||||
it "renders the hidden input field at the position of the last cursor if it is on screen", ->
|
||||
inputNode = node.querySelector('.hidden-input')
|
||||
|
||||
@@ -13,10 +13,10 @@ CursorsComponent = React.createClass
|
||||
|
||||
render: ->
|
||||
{editor, scrollTop, scrollLeft} = @props
|
||||
{blinking} = @state
|
||||
{blinkOff} = @state
|
||||
|
||||
className = 'cursors'
|
||||
className += ' blinking' if blinking
|
||||
className += ' blink-off' if blinkOff
|
||||
|
||||
div {className},
|
||||
if @isMounted()
|
||||
@@ -26,32 +26,32 @@ CursorsComponent = React.createClass
|
||||
CursorComponent({key: cursor.id, cursor, scrollTop, scrollLeft})
|
||||
|
||||
getInitialState: ->
|
||||
blinking: true
|
||||
blinkOff: false
|
||||
|
||||
componentDidMount: ->
|
||||
{editor} = @props
|
||||
@startBlinkingCursors()
|
||||
|
||||
componentWillUnmount: ->
|
||||
clearInterval(@cursorBlinkIntervalHandle)
|
||||
@stopBlinkingCursors()
|
||||
|
||||
componentWillUpdate: ({cursorsMoved}) ->
|
||||
@pauseCursorBlinking() if cursorsMoved
|
||||
|
||||
componentDidUpdate: ->
|
||||
@syncCursorAnimations() if @props.selectionAdded
|
||||
|
||||
startBlinkingCursors: ->
|
||||
@setState(blinking: true) if @isMounted()
|
||||
@toggleCursorBlinkHandle = setInterval(@toggleCursorBlink, @props.cursorBlinkPeriod / 2) if @isMounted()
|
||||
|
||||
startBlinkingCursorsAfterDelay: null # Created lazily
|
||||
|
||||
stopBlinkingCursors: ->
|
||||
console.log "START"
|
||||
clearInterval(@toggleCursorBlinkHandle)
|
||||
|
||||
toggleCursorBlink: ->
|
||||
console.log "TOGGLE"
|
||||
@setState(blinkOff: not @state.blinkOff)
|
||||
|
||||
pauseCursorBlinking: ->
|
||||
@state.blinking = false
|
||||
@state.blinkOff = false
|
||||
@stopBlinkingCursors()
|
||||
@startBlinkingCursorsAfterDelay ?= debounce(@startBlinkingCursors, @props.cursorBlinkResumeDelay)
|
||||
@startBlinkingCursorsAfterDelay()
|
||||
|
||||
syncCursorAnimations: ->
|
||||
node = @getDOMNode()
|
||||
cursorNodes = toArray(node.children)
|
||||
node.removeChild(cursorNode) for cursorNode in cursorNodes
|
||||
node.appendChild(cursorNode) for cursorNode in cursorNodes
|
||||
|
||||
@@ -32,7 +32,7 @@ EditorComponent = React.createClass
|
||||
|
||||
render: ->
|
||||
{focused, fontSize, lineHeight, fontFamily, showIndentGuide} = @state
|
||||
{editor, cursorBlinkResumeDelay} = @props
|
||||
{editor, cursorBlinkPeriod, cursorBlinkResumeDelay} = @props
|
||||
maxLineNumberDigits = editor.getScreenLineCount().toString().length
|
||||
|
||||
if @isMounted()
|
||||
@@ -61,8 +61,8 @@ EditorComponent = React.createClass
|
||||
ref: 'scrollView', editor, fontSize, fontFamily, showIndentGuide,
|
||||
lineHeight: lineHeightInPixels, renderedRowRange, @pendingChanges,
|
||||
scrollTop, scrollLeft, scrollHeight, scrollWidth, @scrollingVertically,
|
||||
@cursorsMoved, @selectionChanged, @selectionAdded, cursorBlinkResumeDelay,
|
||||
@onInputFocused, @onInputBlurred, @mouseWheelScreenRow
|
||||
@cursorsMoved, @selectionChanged, @selectionAdded, cursorBlinkPeriod,
|
||||
cursorBlinkResumeDelay, @onInputFocused, @onInputBlurred, @mouseWheelScreenRow
|
||||
}
|
||||
|
||||
ScrollbarComponent
|
||||
@@ -107,6 +107,7 @@ EditorComponent = React.createClass
|
||||
getInitialState: -> {}
|
||||
|
||||
getDefaultProps: ->
|
||||
cursorBlinkPeriod: 800
|
||||
cursorBlinkResumeDelay: 100
|
||||
lineOverdrawMargin: 8
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ EditorScrollViewComponent = React.createClass
|
||||
render: ->
|
||||
{editor, fontSize, fontFamily, lineHeight, showIndentGuide} = @props
|
||||
{renderedRowRange, pendingChanges, scrollTop, scrollLeft, scrollHeight, scrollWidth, scrollingVertically, mouseWheelScreenRow} = @props
|
||||
{selectionChanged, selectionAdded, cursorBlinkResumeDelay, cursorsMoved, onInputFocused, onInputBlurred} = @props
|
||||
{selectionChanged, selectionAdded, cursorBlinkPeriod, cursorBlinkResumeDelay, cursorsMoved, onInputFocused, onInputBlurred} = @props
|
||||
|
||||
if @isMounted()
|
||||
inputStyle = @getHiddenInputPosition()
|
||||
@@ -33,7 +33,7 @@ EditorScrollViewComponent = React.createClass
|
||||
onFocus: onInputFocused
|
||||
onBlur: onInputBlurred
|
||||
|
||||
CursorsComponent({editor, scrollTop, scrollLeft, cursorsMoved, selectionAdded, cursorBlinkResumeDelay})
|
||||
CursorsComponent({editor, scrollTop, scrollLeft, cursorsMoved, selectionAdded, cursorBlinkPeriod, cursorBlinkResumeDelay})
|
||||
LinesComponent {
|
||||
ref: 'lines', editor, fontSize, fontFamily, lineHeight, showIndentGuide,
|
||||
renderedRowRange, pendingChanges, scrollTop, scrollLeft, scrollingVertically,
|
||||
|
||||
@@ -20,16 +20,8 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&.is-focused .cursors.blinking .cursor {
|
||||
-webkit-animation: blink 0.8s;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@-webkit-keyframes blink {
|
||||
0% { opacity: .7; }
|
||||
50% { opacity: .7; }
|
||||
51% { opacity: 0; }
|
||||
100% { opacity: 0; }
|
||||
&.is-focused .cursors.blink-off .cursor {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.horizontal-scrollbar {
|
||||
|
||||
Reference in New Issue
Block a user