Skip to content

Instantly share code, notes, and snippets.

@nicksheffield
Last active January 28, 2020 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicksheffield/2de5b5e6e11aa64d0daa89b645e2c7cd to your computer and use it in GitHub Desktop.
Save nicksheffield/2de5b5e6e11aa64d0daa89b645e2c7cd to your computer and use it in GitHub Desktop.
HoverMarquee react component
import React, { useState, useRef, useEffect } from 'react'
// found: https://stackoverflow.com/a/21015393
function getTextWidth(text, font) {
// re-use canvas object for better performance
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement('canvas'))
var context = canvas.getContext('2d')
context.font = font
var metrics = context.measureText(text)
return metrics.width
}
const HoverMarquee = ({ speed = 1, active, children }) => {
const [hovered, setHovered] = useState(false)
const ref = useRef()
const [font, setFont] = useState()
useEffect(() => {
if (ref.current) {
const computedStyles = window.getComputedStyle(ref.current)
setFont(computedStyles.font)
}
}, [ref])
const textWidth = getTextWidth(children, font)
const outerStyles = {
overflowX: 'hidden',
}
const dist = textWidth - (ref.current ? ref.current.clientWidth : 0)
const innerStyles = {
whiteSpace: 'nowrap',
overflow: active || hovered ? '' : 'hidden',
textOverflow: active || hovered ? '' : 'ellipsis',
transform: active || hovered ? `translateX(-${dist}px)` : 'translateX(0px)',
transition: active || hovered ? `transform ${(dist / 100) * speed}s linear` : `transform ${0.5}s ease-out`
}
return (
<div style={outerStyles} onMouseOver={() => setHovered(true)} onMouseOut={() => setHovered(false)} ref={ref}>
<div style={innerStyles}>{children}</div>
</div>
)
}
export default HoverMarquee
const App = () => {
return (
<div style={{ width: '200px' }}>
<HoverMarquee speed={2}>This is short text</HoverMarquee>
<HoverMarquee speed={2}>This is some longer text. Lorem ipsum dolor sit amet.</HoverMarquee>
<HoverMarquee speed={2}>This is even longer text. Lorem ipsum dolor sit amet. Perspiciatis, tempore assumenda culpa nostrum.</HoverMarquee>
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment