From f163609a021ed8de53ddc800578a5f5e3a05228f Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 5 Oct 2021 21:20:30 -0700 Subject: [PATCH 01/10] Change commit behavior of the scale-rotate tool --- selection-scale-rotate.user.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index a3a11fb..9752bc7 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -208,15 +208,6 @@ function main () { rotate: 0 }) } - this.onMouseCommit = () => { - this.onCommit() - window.removeEventListener('mouseup', this.onMouseCommit) - } - this.onKeyCommit = e => { - if (e.key === 'Enter') { - this.onCommit() - } - } } componentWillUpdate (nextProps, nextState) { @@ -251,6 +242,9 @@ function main () { key, e('input', { style: { width: '3em' }, type: 'number', ...numberProps }), e('input', { type: 'range', ...rangeProps, onFocus: e => e.target.blur() }) + e('button', { style: { float: 'left' }, onClick: () => this.onCommit() }, + 'Commit' + ) ) } From 24d5fd823aa0115f3d1b65acecceab1f79b4f6ac Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 5 Oct 2021 21:30:50 -0700 Subject: [PATCH 02/10] Add missing comma --- selection-scale-rotate.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index 9752bc7..59894c0 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -241,7 +241,7 @@ function main () { return e('div', null, key, e('input', { style: { width: '3em' }, type: 'number', ...numberProps }), - e('input', { type: 'range', ...rangeProps, onFocus: e => e.target.blur() }) + e('input', { type: 'range', ...rangeProps, onFocus: e => e.target.blur() }), e('button', { style: { float: 'left' }, onClick: () => this.onCommit() }, 'Commit' ) From fecf7fb5074019d95191ea43b7405723320ba3fa Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 5 Oct 2021 21:41:33 -0700 Subject: [PATCH 03/10] Remove the function calls to the removed functions --- selection-scale-rotate.user.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index 59894c0..abfe6ce 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -230,13 +230,10 @@ function main () { onChange: e => this.setState({ [key]: parseFloatOrDefault(e.target.value) }) } const rangeProps = { - ...props, - onMouseDown: () => window.addEventListener('mouseup', this.onMouseCommit) + ...props } const numberProps = { - ...props, - onKeyUp: this.onKeyCommit, - onBlur: this.onCommit + ...props } return e('div', null, key, From 95fb72a5da33be85c942d06d853d3eeea7e2a795 Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 5 Oct 2021 21:51:57 -0700 Subject: [PATCH 04/10] Make only one commit button for the panel --- selection-scale-rotate.user.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index abfe6ce..ab217f0 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -239,9 +239,6 @@ function main () { key, e('input', { style: { width: '3em' }, type: 'number', ...numberProps }), e('input', { type: 'range', ...rangeProps, onFocus: e => e.target.blur() }), - e('button', { style: { float: 'left' }, onClick: () => this.onCommit() }, - 'Commit' - ) ) } @@ -252,7 +249,10 @@ function main () { this.renderSlider('scaleX', { min: 0, max: 2, step: 0.01 }), this.renderSlider('scaleY', { min: 0, max: 2, step: 0.01 }), this.renderSlider('scale', { min: 0, max: 2, step: 0.01 }), - this.renderSlider('rotate', { min: -180, max: 180, step: 1 }) + this.renderSlider('rotate', { min: -180, max: 180, step: 1 }), + e('button', { style: { float: 'left' }, onClick: () => this.onCommit() }, + 'Commit' + ) ), e('button', { From 87c32719965b9c7109888461bfffc0cd50e73680 Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 5 Oct 2021 21:54:21 -0700 Subject: [PATCH 05/10] Remove a comma which is no longer necessary --- selection-scale-rotate.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index ab217f0..2e58227 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -238,7 +238,7 @@ function main () { return e('div', null, key, e('input', { style: { width: '3em' }, type: 'number', ...numberProps }), - e('input', { type: 'range', ...rangeProps, onFocus: e => e.target.blur() }), + e('input', { type: 'range', ...rangeProps, onFocus: e => e.target.blur() }) ) } From 9a650cf48aa7183272ce078f2bb64378c3e17c5d Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 5 Oct 2021 22:17:48 -0700 Subject: [PATCH 06/10] Change transformation matrix to be product of scale and rotate --- selection-scale-rotate.user.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index 2e58227..65f6573 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -162,8 +162,12 @@ class ScaleRotateMod { getTransform() { const transform = rotateTransform(this.state.rotate * Math.PI / 180) transform[0] *= this.state.scale + transform[1] *= this.state.scale + transform[2] *= this.state.scale transform[3] *= this.state.scale transform[0] *= this.state.scaleX + transform[1] *= this.state.scaleX + transform[2] *= this.state.scaleY transform[3] *= this.state.scaleY return transform } From 59875ef5ddfc7bea91127f8e4bb7d39333abf33f Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 5 Oct 2021 22:18:57 -0700 Subject: [PATCH 07/10] Add a code comment about the transformation matrix --- selection-scale-rotate.user.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index 65f6573..c8e388d 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -160,6 +160,9 @@ class ScaleRotateMod { } getTransform() { + // The resulting transform is equivalent to the product of a scaling matrix + // followed by a rotation matrix. Refer to + // https://www.wolframalpha.com/input/?i=%7B%7Bx+*+s%2C+0%7D%2C+%7B0%2C+y+*+s%7D%7D+.+%7B%7Bcos+theta%2C+sin+theta%7D%2C+%7B-sin+theta%2C+cos+theta%7D%7D const transform = rotateTransform(this.state.rotate * Math.PI / 180) transform[0] *= this.state.scale transform[1] *= this.state.scale From 036d74de44fb4b9af9499e58be19bd11e31d6977 Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 5 Oct 2021 22:29:16 -0700 Subject: [PATCH 08/10] Add a button for each slider to reset it --- selection-scale-rotate.user.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index c8e388d..4489ea1 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -206,6 +206,18 @@ function main () { } }) + this.onReset = (key) => { + const defaults = { + scale: 1, + scaleX: 1, + scaleY: 1, + rotate: 0 + } + let changedState = {} + changedState[key] = defaults[key] + this.setState(changedState) + } + this.onCommit = () => { this.scaleRotateMod.commit() this.setState({ @@ -245,7 +257,8 @@ function main () { return e('div', null, key, e('input', { style: { width: '3em' }, type: 'number', ...numberProps }), - e('input', { type: 'range', ...rangeProps, onFocus: e => e.target.blur() }) + e('input', { type: 'range', ...rangeProps, onFocus: e => e.target.blur() }), + e('button', { onClick: () => this.onReset(key) }, 'Reset') ) } From 71a3b35d2228afc50fe859425885683dbebc6334 Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Tue, 16 Nov 2021 19:09:10 -0800 Subject: [PATCH 09/10] Bump the version number, update script metadata --- selection-scale-rotate.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index 4489ea1..0b54712 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -1,13 +1,13 @@ // ==UserScript== // @name Line Rider Selection Rotate and Scale Mod // @namespace http://tampermonkey.net/ -// @version 0.4 +// @version 0.5 // @description Adds ability to rotate and scale selections -// @author David Lu +// @author David Lu & Ethan Li // @match https://www.linerider.com/* // @match https://*.official-linerider.com/* // @match http://localhost:8000/* -// @downloadURL https://github.com/EmergentStudios/linerider-userscript-mods/raw/master/selection-scale-rotate.user.js +// @downloadURL https://github.com/ethanjli/linerider-userscript-mods/raw/master/selection-scale-rotate.user.js // @grant none // ==/UserScript== From d349771aaaec7041b9859aa551da2004f41e1fbf Mon Sep 17 00:00:00 2001 From: Ethan Li Date: Mon, 27 Dec 2021 13:06:01 -0800 Subject: [PATCH 10/10] Add checkboxes to mirror a selection in X or Y (#2) * Add checkboxes to mirror a selection along X or Y * Revert download URL to upstream repo --- selection-scale-rotate.user.js | 42 ++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/selection-scale-rotate.user.js b/selection-scale-rotate.user.js index 0b54712..9d320cd 100644 --- a/selection-scale-rotate.user.js +++ b/selection-scale-rotate.user.js @@ -1,13 +1,13 @@ // ==UserScript== // @name Line Rider Selection Rotate and Scale Mod // @namespace http://tampermonkey.net/ -// @version 0.5 +// @version 0.5.1 // @description Adds ability to rotate and scale selections // @author David Lu & Ethan Li // @match https://www.linerider.com/* // @match https://*.official-linerider.com/* // @match http://localhost:8000/* -// @downloadURL https://github.com/ethanjli/linerider-userscript-mods/raw/master/selection-scale-rotate.user.js +// @downloadURL https://github.com/EmergentStudios/linerider-userscript-mods/raw/master/selection-scale-rotate.user.js // @grant none // ==/UserScript== @@ -113,7 +113,7 @@ class ScaleRotateMod { this.changed = false } - if (this.state.active && this.selectedPoints.size > 0 && (this.state.scale !== 1 || this.state.scaleX !== 1 || this.state.scaleY !== 1 || this.state.rotate !== 0)) { + if (this.state.active && this.selectedPoints.size > 0 && (this.state.scale !== 1 || this.state.scaleX !== 1 || this.state.scaleY !== 1 || this.state.flipX || this.state.flipY || this.state.rotate !== 0)) { const selectedLines = [...getLinesFromPoints(this.selectedPoints)] .map(id => this.track.getLine(id)) .filter(l => l) @@ -168,10 +168,18 @@ class ScaleRotateMod { transform[1] *= this.state.scale transform[2] *= this.state.scale transform[3] *= this.state.scale - transform[0] *= this.state.scaleX - transform[1] *= this.state.scaleX - transform[2] *= this.state.scaleY - transform[3] *= this.state.scaleY + let scaleX = this.state.scaleX + if (this.state.flipX) { + scaleX *= -1 + } + let scaleY = this.state.scaleY + if (this.state.flipY) { + scaleY *= -1 + } + transform[0] *= scaleX + transform[1] *= scaleX + transform[2] *= scaleY + transform[3] *= scaleY return transform } } @@ -193,6 +201,8 @@ function main () { scale: 1, scaleX: 1, scaleY: 1, + flipX: false, + flipY: false, rotate: 0, } @@ -211,6 +221,8 @@ function main () { scale: 1, scaleX: 1, scaleY: 1, + flipX: false, + flipY: false, rotate: 0 } let changedState = {} @@ -224,6 +236,8 @@ function main () { scale: 1, scaleX: 1, scaleY: 1, + flipX: false, + flipY: false, rotate: 0 }) } @@ -242,6 +256,18 @@ function main () { } } + renderCheckbox (key, props) { + props = { + ...props, + checked: this.state[key], + onChange: e => this.setState({ [key]: e.target.checked }) + } + return e('div', null, + key, + e('input', { type: 'checkbox', ...props }) + ) + } + renderSlider (key, props) { props = { ...props, @@ -266,6 +292,8 @@ function main () { return e('div', null, this.state.active && e('div', null, + this.renderCheckbox('flipX', { min: 0, max: 2, step: 0.01 }), + this.renderCheckbox('flipY', { min: 0, max: 2, step: 0.01 }), this.renderSlider('scaleX', { min: 0, max: 2, step: 0.01 }), this.renderSlider('scaleY', { min: 0, max: 2, step: 0.01 }), this.renderSlider('scale', { min: 0, max: 2, step: 0.01 }),