WIP WYSIWYG ~3D SVG editor.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow users to drag focused numeric inputs.

Makes it a lot easier to get fine-grained input out of stock browser
input elements. Still a little bit of jank to dispel (desktop browsers
will let you drag selected text between inputs, which is easy to
trigger accidentally), but we'll revisit later.

+70 -6
+7 -6
index.html
··· 50 50 <div id="rotate" class="vector prop"> 51 51 <h4>Rotate</h4> 52 52 <label for="rotate-x">X</label> 53 - <input type="number" id="rotate-x" /> 53 + <input type="number" id="rotate-x" step="0.1" /> 54 54 <label for="rotate-y">Y</label> 55 - <input type="number" id="rotate-y" /> 55 + <input type="number" id="rotate-y" step="0.1" /> 56 56 <label for="rotate-z">Z</label> 57 - <input type="number" id="rotate-z" /> 57 + <input type="number" id="rotate-z" step="0.1" /> 58 58 </div> 59 59 <div id="scale" class="vector prop"> 60 60 <h4>Scale</h4> <label for="scale-x">X</label> 61 - <input type="number" id="scale-x" /> 61 + <input type="number" id="scale-x" step="0.1" /> 62 62 <label for="scale-y">Y</label> 63 - <input type="number" id="scale-y" /> 63 + <input type="number" id="scale-y" step="0.1" /> 64 64 <label for="scale-z">Z</label> 65 - <input type="number" id="scale-z" /> 65 + <input type="number" id="scale-z" step="0.1" /> 66 66 </div> 67 67 </div> 68 68 <div class="prop-group"> ··· 123 123 Made with love, anime.js, and zdog by Jaromino. 124 124 </footer> 125 125 <script src="zoodle.js"></script> 126 + <script src="input-enhancements.js"></script> 126 127 </body> 127 128 </html>
+63
input-enhancements.js
··· 1 + class EnhancedInput { 2 + constructor( input ) { 3 + this.input = input; 4 + this.startX = 0; 5 + this.startY = 0; 6 + this.startValue = 0; 7 + 8 + this._dragStart = this.dragStart.bind(this); 9 + this._dragMove = this.dragMove.bind(this); 10 + this._dragEnd = this.dragEnd.bind(this); 11 + 12 + this.input.addEventListener( "focus", this.enableDrag.bind(this) ); 13 + this.input.addEventListener( "blur", this.disableDrag.bind(this) ); 14 + } 15 + enableDrag() { 16 + console.log(this.input + " focused"); 17 + this.input.addEventListener( "pointerdown", this._dragStart ); 18 + } 19 + disableDrag() { 20 + console.log(this.input + " blurred"); 21 + this.input.removeEventListener( "pointerdown", this._dragStart ); 22 + this.input.removeEventListener( "pointermove", this._dragMove ); 23 + this.input.removeEventListener( "pointerup", this._dragEnd ); 24 + this.input.removeEventListener( "pointercancel", this._dragEnd ); 25 + } 26 + dragStart(event) { 27 + console.log(this.input + " dragging"); 28 + this.startX = event.screenX; 29 + this.startY = event.screenY; 30 + this.startValue = this.input.valueAsNumber; 31 + 32 + this.input.setPointerCapture( event.pointerId ); 33 + this.input.addEventListener( "pointermove", this._dragMove ); 34 + this.input.addEventListener( "pointerup", this._dragEnd ); 35 + this.input.addEventListener( "pointercancel", this._dragEnd ); 36 + } 37 + dragMove(event) { 38 + const dx = event.screenX - this.startX; 39 + const dy = event.screenY - this.startY; 40 + let step = this.input.step ? parseFloat(this.input.step) : 1; 41 + this.input.valueAsNumber = this.startValue + dy * 0.1 * step; 42 + 43 + // Manually fire input event since updating it programmatically won't. 44 + const inputEvent = new Event('input', { 45 + bubbles: true, 46 + cancelable: true 47 + }); 48 + this.input.dispatchEvent(inputEvent); 49 + } 50 + dragEnd(event) { 51 + console.log(this.input + " released"); 52 + this.startX = 0; 53 + this.startY = 0; 54 + 55 + this.input.removeEventListener( "pointermove", this._dragMove ); 56 + this.input.removeEventListener( "pointerup", this._dragEnd ); 57 + this.input.removeEventListener( "pointercancel", this._dragEnd ); 58 + } 59 + } 60 + 61 + document.querySelectorAll("input[type='number']").forEach(input => { 62 + input.enhanced = new EnhancedInput(input); 63 + });