From 50c1d85ade7af90ef2b052a46473eed00ca9b99d Mon Sep 17 00:00:00 2001 From: samreid Date: Mon, 14 Dec 2020 15:20:54 -0700 Subject: [PATCH] Factor out MagnifyingGlassNode, see https://github.com/phetsims/circuit-construction-kit-common/issues/620 --- js/MagnifyingGlassNode.js | 55 +++++++++++++++++++++++++++++++++++++++ js/buttons/ZoomButton.js | 37 ++++++-------------------- 2 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 js/MagnifyingGlassNode.js diff --git a/js/MagnifyingGlassNode.js b/js/MagnifyingGlassNode.js new file mode 100644 index 000000000..fe7abe548 --- /dev/null +++ b/js/MagnifyingGlassNode.js @@ -0,0 +1,55 @@ +// Copyright 2020, University of Colorado Boulder + +import merge from '../../phet-core/js/merge.js'; +import Circle from '../../scenery/js/nodes/Circle.js'; +import Line from '../../scenery/js/nodes/Line.js'; +import Node from '../../scenery/js/nodes/Node.js'; +import sceneryPhet from './sceneryPhet.js'; + +/** + * + * @author Sam Reid (PhET Interactive Simulations) + */ + +class MagnifyingGlassNode extends Node { + + constructor( options ) { + + options = merge( { + glassRadius: 15, + glassFill: 'white', // center of the glass + glassStroke: 'black', // rim and handle + icon: null // optional icon will be centered in the glass area, if provided + }, options ); + + // the magnifying glass + const glassLineWidth = 0.25 * options.glassRadius; + const glassNode = new Circle( options.glassRadius, { + fill: options.glassFill, + stroke: options.glassStroke, + lineWidth: glassLineWidth + } ); + + // handle at lower-left of glass, at a 45-degree angle + const outsideRadius = options.glassRadius + ( glassLineWidth / 2 ); // use outside radius so handle line cap doesn't appear inside glassNode + const handleNode = new Line( + outsideRadius * Math.cos( Math.PI / 4 ), outsideRadius * Math.sin( Math.PI / 4 ), + options.glassRadius * Math.cos( Math.PI / 4 ) + ( 0.65 * options.glassRadius ), options.glassRadius * Math.sin( Math.PI / 4 ) + ( 0.65 * options.glassRadius ), { + stroke: options.glassStroke, + lineWidth: 0.4 * options.glassRadius, + lineCap: 'round' + } ); + + options.children = [ glassNode, handleNode ]; + + if ( options.icon ) { + options.icon.center = glassNode.center; + options.children.push( options.icon ); + } + + super( options ); + } +} + +sceneryPhet.register( 'MagnifyingGlassNode', MagnifyingGlassNode ); +export default MagnifyingGlassNode; \ No newline at end of file diff --git a/js/buttons/ZoomButton.js b/js/buttons/ZoomButton.js index 123e77018..909195d7b 100644 --- a/js/buttons/ZoomButton.js +++ b/js/buttons/ZoomButton.js @@ -9,11 +9,9 @@ import Dimension2 from '../../../dot/js/Dimension2.js'; import InstanceRegistry from '../../../phet-core/js/documentation/InstanceRegistry.js'; import merge from '../../../phet-core/js/merge.js'; -import Circle from '../../../scenery/js/nodes/Circle.js'; -import Line from '../../../scenery/js/nodes/Line.js'; -import Node from '../../../scenery/js/nodes/Node.js'; import RectangularPushButton from '../../../sun/js/buttons/RectangularPushButton.js'; import Tandem from '../../../tandem/js/Tandem.js'; +import MagnifyingGlassNode from '../MagnifyingGlassNode.js'; import MinusNode from '../MinusNode.js'; import PhetColorScheme from '../PhetColorScheme.js'; import PlusNode from '../PlusNode.js'; @@ -29,40 +27,21 @@ class ZoomButton extends RectangularPushButton { options = merge( { in: true, // true: zoom-in button, false: zoom-out button baseColor: PhetColorScheme.BUTTON_YELLOW, - magnifyingGlassRadius: 15, - magnifyingGlassFill: 'white', // center of the glass - magnifyingGlassStroke: 'black', // rim and handle + magnifyingGlassOptions: { glassRadius: 15 }, tandem: Tandem.REQUIRED }, options ); - // the magnifying glass - const glassLineWidth = 0.25 * options.magnifyingGlassRadius; - const glassNode = new Circle( options.magnifyingGlassRadius, { - fill: options.magnifyingGlassFill, - stroke: options.magnifyingGlassStroke, - lineWidth: glassLineWidth - } ); - - // handle at lower-left of glass, at a 45-degree angle - const outsideRadius = options.magnifyingGlassRadius + ( glassLineWidth / 2 ); // use outside radius so handle line cap doesn't appear inside glassNode - const handleNode = new Line( - outsideRadius * Math.cos( Math.PI / 4 ), outsideRadius * Math.sin( Math.PI / 4 ), - options.magnifyingGlassRadius * Math.cos( Math.PI / 4 ) + ( 0.65 * options.magnifyingGlassRadius ), options.magnifyingGlassRadius * Math.sin( Math.PI / 4 ) + ( 0.65 * options.magnifyingGlassRadius ), { - stroke: options.magnifyingGlassStroke, - lineWidth: 0.4 * options.magnifyingGlassRadius, - lineCap: 'round' - } ); - // plus or minus sign in middle of magnifying glass const signOptions = { - size: new Dimension2( 1.3 * options.magnifyingGlassRadius, options.magnifyingGlassRadius / 3 ), - centerX: glassNode.centerX, - centerY: glassNode.centerY + size: new Dimension2( 1.3 * options.magnifyingGlassOptions.glassRadius, options.magnifyingGlassOptions.glassRadius / 3 ) }; - const signNode = options.in ? new PlusNode( signOptions ) : new MinusNode( signOptions ); + + const magnifyingGlassNode = new MagnifyingGlassNode( merge( { + icon: options.in ? new PlusNode( signOptions ) : new MinusNode( signOptions ) + }, options.magnifyingGlassOptions ) ); assert && assert( !options.content, 'ZoomButton sets content' ); - options.content = new Node( { children: [ handleNode, glassNode, signNode ] } ); + options.content = magnifyingGlassNode; super( options );