diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts
index 918837a18821d3d0b1b52de5b3ca09bd7d2310a3..cc5866ae3e7e702f134d72463e4b3d72c7a6cba3 100644
--- a/src/mol-canvas3d/canvas3d.ts
+++ b/src/mol-canvas3d/canvas3d.ts
@@ -248,7 +248,7 @@ namespace Canvas3D {
         }
 
         async function identify(x: number, y: number): Promise<PickingId | undefined> {
-            if (pickDirty || isPicking) return undefined
+            if (pickDirty || isPicking) return;
 
             isPicking = true
 
@@ -265,19 +265,19 @@ namespace Canvas3D {
             // await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
             webgl.readPixels(xp, yp, 1, 1, buffer)
             const objectId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
-            if (objectId === -1) return
+            if (objectId === -1) { isPicking = false; return; }
 
             instancePickTarget.bind()
             // await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
             webgl.readPixels(xp, yp, 1, 1, buffer)
             const instanceId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
-            if (instanceId === -1) return
+            if (instanceId === -1) { isPicking = false; return; }
 
             groupPickTarget.bind()
             // await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
             webgl.readPixels(xp, yp, 1, 1, buffer)
             const groupId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
-            if (groupId === -1) return
+            if (groupId === -1) { isPicking = false; return; }
 
             isPicking = false
 
diff --git a/src/mol-plugin/ui/controls/parameters.tsx b/src/mol-plugin/ui/controls/parameters.tsx
index b3a9f672189205ba370162d839c3704c9fbf1024..f7399b0bbf2e3b9a5b4eec0b64d89a82d9eb7251 100644
--- a/src/mol-plugin/ui/controls/parameters.tsx
+++ b/src/mol-plugin/ui/controls/parameters.tsx
@@ -5,18 +5,16 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import * as React from 'react'
-
+import { Vec2 } from 'mol-math/linear-algebra';
+import { Color } from 'mol-util/color';
+import { ColorListName, getColorListFromName } from 'mol-util/color/scale';
+import { ColorNames, ColorNamesValueMap } from 'mol-util/color/tables';
+import { memoize1 } from 'mol-util/memoize';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { camelCaseToWords } from 'mol-util/string';
-import { ColorNames, ColorNamesValueMap } from 'mol-util/color/tables';
-import { Color } from 'mol-util/color';
-import { Vec2 } from 'mol-math/linear-algebra';
+import * as React from 'react';
 import LineGraphComponent from './line-graph/line-graph-component';
-
 import { Slider, Slider2 } from './slider';
-import { getColorListFromName, ColorListNames } from 'mol-util/color/scale';
-
 
 export interface ParameterControlsProps<P extends PD.Params = PD.Params> {
     params: P,
@@ -57,7 +55,7 @@ function controlFor(param: PD.Any): ParamControl | undefined {
         case 'select': return SelectControl;
         case 'text': return TextControl;
         case 'interval': return typeof param.min !== 'undefined' && typeof param.max !== 'undefined'
-        ? BoundedIntervalControl : IntervalControl;
+            ? BoundedIntervalControl : IntervalControl;
         case 'group': return GroupControl;
         case 'mapped': return MappedControl;
         case 'line-graph': return LineGraphControl;
@@ -243,33 +241,56 @@ function ColorValueOption(color: Color) {
     </option> : null
 }
 
-
 export class ColorControl extends SimpleParam<PD.Color> {
     onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
         this.update(Color(parseInt(e.target.value)));
     }
 
+    stripStyle(): React.CSSProperties {
+        return {
+            background: Color.toStyle(this.props.value),
+            position: 'absolute',
+            bottom: '0',
+            height: '4px',
+            right: '0',
+            left: '0'
+        };
+    }
+
     renderControl() {
-        return <select value={this.props.value} onChange={this.onChange} style={{ borderLeft: `16px solid ${Color.toStyle(this.props.value)}` }}>
-            {ColorValueOption(this.props.value)}
-            {ColorOptions()}
-        </select>;
+        return <div style={{ position: 'relative' }}>
+            <select value={this.props.value} onChange={this.onChange}>
+                {ColorValueOption(this.props.value)}
+                {ColorOptions()}
+            </select>
+            <div style={this.stripStyle()} />
+        </div>;
     }
 }
 
-let _colorScales: React.ReactFragment | undefined = void 0;
-function ColorScaleOptions() {
-    if (_colorScales) return _colorScales;
-    _colorScales = <>{ColorListNames.map(name => <option key={name} value={name}>{camelCaseToWords(name)}</option>)}</>;
-    return _colorScales;
-}
+const colorScaleGradient = memoize1((n: ColorListName) => `linear-gradient(to right, ${getColorListFromName(n).map(c => Color.toStyle(c)).join(', ')})`);
 
 export class ColorScaleControl extends SimpleParam<PD.ColorScale<any>> {
     onChange = (e: React.ChangeEvent<HTMLSelectElement>) => { this.update(e.target.value); }
+
+    stripStyle(): React.CSSProperties {
+        return {
+            background: colorScaleGradient(this.props.value),
+            position: 'absolute',
+            bottom: '0',
+            height: '4px',
+            right: '0',
+            left: '0'
+        };
+    }
+
     renderControl() {
-        return <select value={this.props.value || ''} onChange={this.onChange} disabled={this.props.isDisabled} style={{background: `linear-gradient(to right, ${getColorListFromName(this.props.value).map(c => Color.toStyle(c)).join(', ')})`}}>
-            {ColorScaleOptions()}
-        </select>;
+        return <div style={{ position: 'relative' }}>
+            <select value={this.props.value || ''} onChange={this.onChange} disabled={this.props.isDisabled}>
+                {this.props.param.options.map(([value, label]) => <option key={value} value={value}>{label}</option>)}
+            </select>
+            <div style={this.stripStyle()} />
+        </div>;
     }
 }
 
diff --git a/src/mol-plugin/ui/state/apply-action.tsx b/src/mol-plugin/ui/state/apply-action.tsx
index 93a6cd3ab99833a0e9ee7207f979ef641f14131d..17482d70072e34909f0e0545b9c6e8986366a6e0 100644
--- a/src/mol-plugin/ui/state/apply-action.tsx
+++ b/src/mol-plugin/ui/state/apply-action.tsx
@@ -8,7 +8,7 @@ import { PluginCommands } from 'mol-plugin/command';
 import { PluginContext } from 'mol-plugin/context';
 import { State, Transform } from 'mol-state';
 import { StateAction } from 'mol-state/action';
-import { memoizeOne } from 'mol-util/memoize';
+import { memoizeLatest } from 'mol-util/memoize';
 import { StateTransformParameters, TransformContolBase } from './common';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 
@@ -47,7 +47,7 @@ class ApplyActionContol extends TransformContolBase<ApplyActionContol.Props, App
     applyText() { return 'Apply'; }
     isUpdate() { return false; }
 
-    private _getInfo = memoizeOne((t: Transform.Ref, v: string) => StateTransformParameters.infoFromAction(this.plugin, this.props.state, this.props.action, this.props.nodeRef));
+    private _getInfo = memoizeLatest((t: Transform.Ref, v: string) => StateTransformParameters.infoFromAction(this.plugin, this.props.state, this.props.action, this.props.nodeRef));
 
     state = { ref: this.props.nodeRef, version: this.props.state.transforms.get(this.props.nodeRef).version, error: void 0, isInitial: true, params: this.getInfo().initialValues, busy: false };
 
diff --git a/src/mol-plugin/ui/state/update-transform.tsx b/src/mol-plugin/ui/state/update-transform.tsx
index eb01bfcb02502a64abf5bf9df67619653cd32d42..c7e89a1f43d4ba812913cecfc5572aa82787d822 100644
--- a/src/mol-plugin/ui/state/update-transform.tsx
+++ b/src/mol-plugin/ui/state/update-transform.tsx
@@ -5,7 +5,7 @@
  */
 
 import { State, Transform } from 'mol-state';
-import { memoizeOne } from 'mol-util/memoize';
+import { memoizeLatest } from 'mol-util/memoize';
 import { StateTransformParameters, TransformContolBase } from './common';
 
 export { UpdateTransformContol };
@@ -45,7 +45,7 @@ class UpdateTransformContol extends TransformContolBase<UpdateTransformContol.Pr
         return autoUpdate({ a: cell.obj!, b: parentCell.obj!, oldParams: this.getInfo().initialValues, newParams }, this.plugin);
     }
 
-    private _getInfo = memoizeOne((t: Transform) => StateTransformParameters.infoFromTransform(this.plugin, this.props.state, this.props.transform));
+    private _getInfo = memoizeLatest((t: Transform) => StateTransformParameters.infoFromTransform(this.plugin, this.props.state, this.props.transform));
 
     state: UpdateTransformContol.ComponentState = { transform: this.props.transform, error: void 0, isInitial: true, params: this.getInfo().initialValues, busy: false };
 
diff --git a/src/mol-plugin/ui/viewport.tsx b/src/mol-plugin/ui/viewport.tsx
index e33496c5852dddff1df0bd75fc88945beb170217..6ccfd15a86170b8b4acea6c2437ae8d95ec88f97 100644
--- a/src/mol-plugin/ui/viewport.tsx
+++ b/src/mol-plugin/ui/viewport.tsx
@@ -67,8 +67,8 @@ export class ViewportControls extends PluginComponent {
 }
 
 export class Viewport extends PluginComponent<{ }, ViewportState> {
-    private container: HTMLDivElement | null = null;
-    private canvas: HTMLCanvasElement | null = null;
+    private container = React.createRef<HTMLDivElement>();
+    private canvas = React.createRef<HTMLCanvasElement>();
 
     state: ViewportState = {
         noWebGl: false
@@ -79,7 +79,7 @@ export class Viewport extends PluginComponent<{ }, ViewportState> {
     }
 
     componentDidMount() {
-        if (!this.canvas || !this.container || !this.plugin.initViewer(this.canvas, this.container)) {
+        if (!this.canvas.current || !this.container.current || !this.plugin.initViewer(this.canvas.current!, this.container.current!)) {
             this.setState({ noWebGl: true });
         }
         this.handleResize();
@@ -123,8 +123,8 @@ export class Viewport extends PluginComponent<{ }, ViewportState> {
         if (this.state.noWebGl) return this.renderMissing();
 
         return <div className='msp-viewport'>
-            <div className='msp-viewport-host3d' ref={elm => this.container = elm}>
-                <canvas ref={elm => this.canvas = elm}></canvas>
+            <div className='msp-viewport-host3d' ref={this.container}>
+                <canvas ref={this.canvas} />
             </div>
         </div>;
     }
diff --git a/src/mol-util/memoize.ts b/src/mol-util/memoize.ts
index f9427a9c90c6fc94d06fd10b91d788a31b4ccaa8..d74f25380edcf97df9cce41639e6aeb5f16944b4 100644
--- a/src/mol-util/memoize.ts
+++ b/src/mol-util/memoize.ts
@@ -4,7 +4,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-export function memoizeOne<Args extends any[], T>(f: (...args: Args) => T): (...args: Args) => T {
+export function memoizeLatest<Args extends any[], T>(f: (...args: Args) => T): (...args: Args) => T {
     let lastArgs: any[] | undefined = void 0, value: any = void 0;
     return (...args) => {
         if (!lastArgs || lastArgs.length !== args.length) {
@@ -21,4 +21,14 @@ export function memoizeOne<Args extends any[], T>(f: (...args: Args) => T): (...
         }
         return value;
     }
+}
+
+export function memoize1<A, T>(f: (a: A) => T): (a: A) => T {
+    const cache = new Map<A, T>();
+    return a => {
+        if (cache.has(a)) return cache.get(a)!;
+        const v = f(a);
+        cache.set(a, v);
+        return v;
+    }
 }
\ No newline at end of file