Quick Touch Events 2 (easing)
copy // no scrolling on mobile document.addEventListener ( 'touchmove' , e => e.preventDefault ( ) , { passive: false } ) ; const hasTouch = navigator.maxTouchPoints != null && navigator.maxTouchPoints > 0 ; // looking forward to `navigator?.maxTouchPoints > 0` // being better supported function touchify( e) { const touch = [ ] ; touch.x = touch.y = 0 ; if ( e.touches != null && e.touches .length > 0 ) { touch.x = e.touches [ 0 ] .clientX ; touch.y = e.touches [ 0 ] .clientY ; for ( let i = 0 ; i < e.touches .length ; i++ ) { touch[ i] = e.touches [ i] ; } } else { touch.x = e.clientX ; touch.y = e.clientY ; touch[ 0 ] = { clientX: e.clientX , clientY: e.clientY } ; } return touch; } let moveOrTouchMove; if ( hasTouch) { moveOrTouchMove = 'touchmove' ; } else { moveOrTouchMove = 'mousemove' ; } function dot( x, y, radius, color) { const el = document.createElement ( 'div' ) ; const size = `${ radius * 2 } px`; Object .assign ( el.style , { position: 'absolute' , left: `${ x} px`, top: `${ y} px`, width: size, height: size, transform: `translate( ${ - radius} px, ${ - radius} px) `, borderRadius: '50%' , background: color } ) ; el.classList .add ( 'dot' ) ; document.body .appendChild ( el) ; return el; } let dotX = 100 , dotY = 100 , touchX = 200 , touchY = 150 , damp = 12 , dotEl = dot( dotX, dotY, 20 , 'red' ) ; document.addEventListener ( moveOrTouchMove, e => { const { x, y } = touchify( e) ; touchX = x; touchY = y; } ) ; function loop( ) { dotX += ( touchX - dotX) / damp; dotY += ( touchY - dotY) / damp; Object .assign ( dotEl.style , { left: `${ dotX} px`, top: `${ dotY} px` } ) ; window.requestAnimationFrame ( loop) ; } loop( ) ;
Try it out…
Move your mouse on desktop or your finger on mobile – watch the red dot follow…
This is a simpler version of some of the things used in yesterdays post – just a quick way to normalize touch events – just one of many ways to do this – for simple stuff this is my goto
.
If you want to try it out on its own page – take a look here (specifically good for trying it on mobile).
You’ll probably want a to use a meta tag like this – for the full effect.
copy < meta name= "viewport" content= "width=device-width, initial-scale=1.0" >
Point DIV at Another DIV (Angle Between Two Points)
copy const dot = document.createElement ( 'div' ) Object .assign ( dot.style , { position: 'absolute' , left: '100px' , top: '100px' , width: '10px' , height: '10px' , transform: 'translate(-5px, -5px)' , background: 'black' } ) ; document.body .appendChild ( dot) ; const pointer = document.createElement ( 'div' ) ; Object .assign ( pointer.style , { position: 'absolute' , left: '-10px' , top: '-5px' , width: '20px' , height: '10px' , background: 'red' } ) ; document.body .appendChild ( pointer) ; // desktop only (`touchmove` needed for mobile) document.addEventListener ( 'mousemove' , ( e) => { const dx = parseFloat( dot.style .left ) - e.clientX ; const dy = parseFloat( dot.style .top ) - e.clientY ; const angle = Math .atan2 ( dy, dx) / Math .PI * 180 ; pointer.style .transform = ` translate( ${ e.clientX } px, ${ e.clientY } px) rotate( ${ angle} deg) `; } ) ;
Try it out…
Moving your mouse around the page, you’ll notice the red div
always points at the black div
.
(more…)
Wobbling Ball with SVG
copy const el = document.body .appendChild ( document.createElement ( 'div' ) ) ; el.innerHTML = ` < svg width= "100%" height= "100%" > < circle id= "circ" cx= "0" cy= "0" r= "50" fill= "red" style= "will-change: transform;" /> </ svg> < style> svg, div, body, html { overflow: visible; height: 100 %; width: 100 %; margin: 0 ; padding: 0 ; } </ style> `; let w = window.innerWidth , h = window.innerHeight , x = w / 2 , y = h / 2 , vx = vy = dx = dy = 0 , damp = 0.99 , div = 8 , ticks = 0 , wobbleChance = 0.03 , startTick = 50 ; function loop( ) { w = window.innerWidth ; h = window.innerHeight ; if ( x > w) { vx *= - 1 ; dx *= - 1 ; x = w; } else if ( x < 0 ) { vx *= - 1 ; dx *= - 1 ; x = 0 ; } if ( y > h) { vy *= - 1 ; dy *= - 1 ; y = h; } else if ( y < 0 ) { vy *= - 1 ; dy *= - 1 ; y = 0 } if ( Math .random ( ) < wobbleChance || ticks === startTick) { dx += Math .random ( ) * 10 - 5 ; dy += Math .random ( ) * 10 - 5 ; } dx *= damp; dy *= damp; vx += ( dx - vx) / div; vy += ( dy - vy) / div; x += vx; y += vy; circ.setAttribute ( 'transform' , `translate( ${ x} ${ y} ) `) ; ticks++; window.requestAnimationFrame ( loop) ; } loop( ) ; function resize( ) { const radius = Math .min ( w, h) * .05; // `window.circ` is the global id (⌐■_■) circ.r .baseVal .value = radius; } resize( ) ; window.addEventListener ( 'resize' , resize) ;
Try it out…
A wobbling ball with svg.
Draw a Spiral with Resize
copy const canvas = document.body .appendChild ( document.createElement ( 'canvas' ) ) ; const c = canvas.getContext ( '2d' ) ; function resize( ) { canvas.width = window.innerWidth ; canvas.height = window.innerHeight ; draw( ) ; } function draw( ) { c.clearRect ( 0 , 0 , canvas.width , canvas.height ) ; c.fillStyle = 'blue' ; const iter = 300 , halfWidth = window.innerWidth / 2 , halfHeight = window.innerHeight / 2 ; let rad = 0 , theta = 0 , x, y; for ( let i = 0 ; i < iter; i++ ) { x = halfWidth + rad * Math .cos ( theta) ; y = halfHeight + rad * Math .sin ( theta) ; c.fillRect ( x, y, 5 , 5 ) ; rad += Math .min ( window.innerWidth , window.innerHeight ) * 0.0015 ; theta += .1; } } resize( ) ; window.addEventListener ( 'resize' , resize) ;
Try it out…
Expanding on yesterdays post, this draws a resizable sprial on a canvas.