Commit 07afda50 authored by Adam Barth's avatar Adam Barth

Add a basic radial reaction to the switch

We still need to tune the various parameters, but this patch is a start.
parent 16be262a
......@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/switch.dart';
import 'package:sky/widgets.dart';
import 'package:sky/theme/colors.dart';
import 'package:vector_math/vector_math.dart';
......@@ -21,7 +20,7 @@ class BigSwitchApp extends App {
scale.scale(5.0, 5.0);
return new Container(
child: new Switch(value: _value, onChanged: _handleOnChanged),
padding: new EdgeDims.all(5.0),
padding: new EdgeDims.all(20.0),
transform: scale,
decoration: new BoxDecoration(
backgroundColor: Teal[600]
......
......@@ -10,6 +10,14 @@ enum EventDisposition {
consumed,
}
EventDisposition combineEventDispositions(EventDisposition left, EventDisposition right) {
if (left == EventDisposition.consumed || right == EventDisposition.consumed)
return EventDisposition.consumed;
if (left == EventDisposition.processed || right == EventDisposition.processed)
return EventDisposition.processed;
return EventDisposition.ignored;
}
abstract class HitTestTarget {
EventDisposition handleEvent(sky.Event event, HitTestEntry entry);
}
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:sky' as sky;
import 'dart:sky' show Point, Offset, Color, Paint;
import 'package:sky/animation/animated_value.dart';
import 'package:sky/animation/animation_performance.dart';
import 'package:sky/animation/curves.dart';
const Duration _kShowDuration = const Duration(milliseconds: 300);
const Duration _kHideDuration = const Duration(milliseconds: 200);
const Color _kOuterColor = const Color(0xFFFFFFFF);
const Color _kInnerColor = const Color(0xFFFFFFFF);
const double _kMaxOpacity = 0.2;
int _roundOpacity(double opacity) {
return (255 * opacity).round();
}
class RadialReaction {
RadialReaction({
this.center,
this.radius,
Point startPosition
}) {
_outerOpacity = new AnimatedValue<double>(0.0, end: _kMaxOpacity, curve: easeOut);
_innerCenter = new AnimatedValue<Point>(startPosition, end: center, curve: easeOut);
_innerRadius = new AnimatedValue<double>(0.0, end: radius, curve: easeOut);
_showPerformance = new AnimationPerformance()
..addVariable(_outerOpacity)
..addVariable(_innerCenter)
..addVariable(_innerRadius)
..duration = _kShowDuration;
_fade = new AnimatedValue(1.0, end: 0.0, curve: easeIn);
_hidePerformance = new AnimationPerformance()
..addVariable(_fade)
..duration =_kHideDuration;
}
final Point center;
final double radius;
AnimationPerformance _showPerformance;
AnimatedValue<double> _outerOpacity;
AnimatedValue<Point> _innerCenter;
AnimatedValue<double> _innerRadius;
Future _showComplete;
AnimationPerformance _hidePerformance;
AnimatedValue<double> _fade;
void show() {
_showComplete = _showPerformance.forward();
}
Future hide() async {
await _showComplete;
await _hidePerformance.forward();
}
void addListener(Function listener) {
_showPerformance.addListener(listener);
_hidePerformance.addListener(listener);
}
final Paint _outerPaint = new Paint();
final Paint _innerPaint = new Paint();
void paint(sky.Canvas canvas, Offset offset) {
_outerPaint.color = _kOuterColor.withAlpha(_roundOpacity(_outerOpacity.value * _fade.value));
canvas.drawCircle(center + offset, radius, _outerPaint);
_innerPaint.color = _kInnerColor.withAlpha(_roundOpacity(_kMaxOpacity * _fade.value));
canvas.drawCircle(_innerCenter.value + offset, _innerRadius.value, _innerPaint);
}
}
......@@ -19,7 +19,7 @@ import 'package:sky/rendering/stack.dart';
import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/framework.dart';
export 'package:sky/base/hit_test.dart' show EventDisposition;
export 'package:sky/base/hit_test.dart' show EventDisposition, combineEventDispositions;
export 'package:sky/rendering/box.dart' show BackgroundImage, BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims;
export 'package:sky/rendering/flex.dart' show FlexDirection, FlexJustifyContent, FlexAlignItems;
export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path;
......
......@@ -13,7 +13,7 @@ import 'package:sky/rendering/box.dart';
import 'package:sky/rendering/object.dart';
import 'package:sky/rendering/sky_binding.dart';
export 'package:sky/base/hit_test.dart' show EventDisposition;
export 'package:sky/base/hit_test.dart' show EventDisposition, combineEventDispositions;
export 'package:sky/rendering/box.dart' show BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims;
export 'package:sky/rendering/flex.dart' show FlexDirection;
export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path;
......
......@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:sky' as sky;
import 'package:sky/painting/radial_reaction.dart';
import 'package:sky/painting/shadows.dart';
import 'package:sky/rendering/box.dart';
import 'package:sky/rendering/object.dart';
......@@ -26,6 +28,7 @@ const double _kTrackWidth =
_kSwitchWidth - (_kThumbRadius - _kTrackRadius) * 2.0;
const Duration _kCheckDuration = const Duration(milliseconds: 200);
const Size _kSwitchSize = const Size(_kSwitchWidth + 2.0, _kSwitchHeight + 2.0);
const double _kReactionRadius = _kSwitchWidth / 2.0;
class Switch extends Component {
Switch({Key key, this.value, this.onChanged}) : super(key: key);
......@@ -72,13 +75,48 @@ class _RenderSwitch extends RenderToggleable {
Color _thumbColor;
Color get thumbColor => _thumbColor;
void set thumbColor(Color value) {
if (value == _thumbColor) return;
_thumbColor = value;
markNeedsPaint();
}
RadialReaction _radialReaction;
EventDisposition handleEvent(sky.Event event, BoxHitTestEntry entry) {
if (event is sky.PointerEvent) {
if (event.type == 'pointerdown') {
_showRadialReaction(entry.localPosition);
return combineEventDispositions(EventDisposition.processed,
super.handleEvent(event, entry));
}
if (event.type == 'pointerup') {
_hideRadialReaction();
return combineEventDispositions(EventDisposition.processed,
super.handleEvent(event, entry));
}
}
return super.handleEvent(event, entry);
}
void _showRadialReaction(Point startLocation) {
if (_radialReaction != null)
return;
_radialReaction = new RadialReaction(
center: new Point(_kSwitchSize.width / 2.0, _kSwitchSize.height / 2.0),
radius: _kReactionRadius,
startPosition: startLocation)
..addListener(markNeedsPaint)
..show();
}
Future _hideRadialReaction() async {
if (_radialReaction == null)
return;
await _radialReaction.hide();
_radialReaction = null;
}
void paint(PaintingCanvas canvas, Offset offset) {
sky.Color thumbColor = _kThumbOffColor;
sky.Color trackColor = _kTrackOffColor;
......@@ -97,6 +135,9 @@ class _RenderSwitch extends RenderToggleable {
..setRectXY(rect, _kTrackRadius, _kTrackRadius);
canvas.drawRRect(rrect, paint);
if (_radialReaction != null)
_radialReaction.paint(canvas, offset);
// Draw the raised thumb with a shadow
paint.color = thumbColor;
var builder = new ShadowDrawLooperBuilder();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment