Instantly share code, notes, and snippets.
Last active
November 26, 2020 20:01
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save roipeker/45bf283b37a3121e04c00aa0228e5dce to your computer and use it in GitHub Desktop.
graphx line button
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// utility just to open a URL in html. | |
/// include "url_launcher: any" in your pubspec dependencies. | |
import 'package:url_launcher/url_launcher.dart'; | |
openUrl(String url) async { | |
await launch(url, forceSafariVC: true); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// roipeker 2020 | |
/// | |
/// GraphX hover button line effect. | |
/// | |
/// web demo: | |
/// https://roi-graphx-linebutton.surge.sh | |
/// | |
/// source: | |
/// https://gist.github.com/roipeker/45bf283b37a3121e04c00aa0228e5dce | |
/// | |
/// GraphX package: https://pub.dev/packages/graphx | |
/// | |
import 'package:flutter/material.dart'; | |
import 'package:graphx/graphx.dart'; | |
import 'js_utils.dart'; | |
class DemoButtonApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
centerTitle: false, | |
title: Text( | |
'graphx hover button', | |
style: TextStyle( | |
fontSize: 12, | |
), | |
), | |
elevation: 0, | |
backgroundColor: Colors.black.withOpacity(.1), | |
), | |
body: Center( | |
child: SizedBox( | |
width: 140, | |
height: 120, | |
child: SceneBuilderWidget( | |
builder: () => SceneController.withLayers( | |
front: DemoButtonScene(), | |
), | |
), | |
), | |
), | |
bottomNavigationBar: Container( | |
height: 50, | |
color: Colors.black45, | |
child: Padding( | |
padding: const EdgeInsets.all(12.0), | |
child: Row( | |
children: [ | |
SizedBox(width: 12), | |
TextButton( | |
child: Text( | |
'graphx gist', | |
style: TextStyle(fontSize: 12), | |
), | |
onPressed: () { | |
openUrl( | |
'https://gist.github.com/roipeker/45bf283b37a3121e04c00aa0228e5dce'); | |
}, | |
), | |
], | |
), | |
), | |
), | |
); | |
} | |
} | |
final stageColor = Colors.grey.shade800; | |
class DemoButtonScene extends SceneRoot { | |
DemoButtonScene() { | |
config(autoUpdateAndRender: true, usePointer: true); | |
} | |
@override | |
void addedToStage() { | |
stage.color = stageColor.value; | |
var btn = Btn1(120, 60); | |
addChild(btn); | |
btn.x = stage.stageWidth / 2; | |
btn.y = stage.stageHeight / 2; | |
} | |
} | |
class Btn1 extends Sprite { | |
double w, h; | |
Path _oriPath; | |
PathMetric _metrics; | |
final _tweenTf = 0.0.twn; | |
final _tweenBg1 = 0.0.twn; | |
final _tweenBg2 = 0.0.twn; | |
final _stageColorTween = stageColor.twn; | |
Shape bg; | |
Shape bg2; | |
Shape bgBounds; | |
StaticText tf; | |
bool isOver = false; | |
Btn1([this.w = 100, this.h = 50]) { | |
_init(); | |
} | |
void _init() { | |
bg = Shape(); | |
bg.graphics | |
.lineStyle(.4, Colors.white.value) | |
.drawRect(0, 0, w, h) | |
.endFill(); | |
bgBounds = Shape(); | |
bgBounds.graphics.beginFill(0x0).drawRect(0, 0, w, h).endFill(); | |
bgBounds.alpha = 0.001; | |
bg2 = Shape(); | |
_oriPath = Path.from(bg.graphics.getPaths()); | |
_metrics = _oriPath.computeMetrics(forceClosed: true).first; | |
tf = StaticText( | |
text: 'GRAPHX', | |
textStyle: StaticText.getStyle( | |
letterSpacing: 1, | |
color: Colors.white, | |
fontSize: 18, | |
fontWeight: FontWeight.w100, | |
), | |
); | |
addChild(bg); | |
addChild(bg2); | |
addChild(bgBounds); | |
addChild(tf); | |
// mouseChildren = false; | |
tf.mouseEnabled = bg.mouseEnabled = bg2.mouseEnabled = false; | |
// bgBounds.mouseUseShape = false; | |
bgBounds.mouseEnabled = true; | |
bgBounds.useCursor = true; | |
bgBounds.onMouseDown.add((e) { | |
GTween.killTweensOf(tf); | |
GTween.killTweensOf(_openLink); | |
tf.tween(duration: .3, scale: .88); | |
stage.onMouseUp.addOnce((e) { | |
GTween.killTweensOf(tf); | |
tf.tween(duration: .5, scale: 1, ease: GEase.elasticOut); | |
if (isOver) { | |
GTween.delayedCall(1.2, _openLink); | |
} | |
}); | |
}); | |
bgBounds.onMouseOver.add((e) { | |
_tweenTo(true); | |
isOver = true; | |
bgBounds.onMouseOut.addOnce((e) { | |
isOver = false; | |
_tweenTo(false); | |
}); | |
}); | |
alignPivot(); | |
tf.alignPivot(); | |
tf.setPosition(w / 2, h / 2); | |
} | |
void _openLink() { | |
openUrl('https://pub.dev/packages/graphx'); | |
} | |
void _tweenTo(bool enters) { | |
[ | |
_tweenTf, | |
_tweenBg1, | |
_tweenBg2, | |
_stageColorTween, | |
].forEach(GTween.killTweensOf); | |
double value = enters ? 1.0 : 0.0; | |
/// tween background color. | |
_stageColorTween.target = _stageColorTween.value; | |
_stageColorTween.tween( | |
enters ? Colors.grey.shade900 : stageColor, | |
ease: GEase.easeOutSine, | |
duration: 1.1, | |
onUpdate: () { | |
stage.color = _stageColorTween.value.value; | |
}, | |
); | |
_tweenTf.tween(value, duration: .4, onUpdate: _drawText); | |
_tweenBg1.tween( | |
value, | |
duration: .5, | |
onUpdate: _drawBg1, | |
); | |
_tweenBg2.tween( | |
value, | |
duration: enters ? 1.2 : .6, | |
delay: enters ? 0.2 : 0.0, | |
onUpdate: _drawBg2, | |
ease: GEase.easeOutExpo, | |
); | |
} | |
void _setStyle({ | |
FontWeight fontWeight, | |
double letterSpacing, | |
Color color, | |
double fontSize, | |
}) { | |
tf.setTextStyle(StaticText.getStyle( | |
fontWeight: fontWeight, | |
fontSize: fontSize, | |
color: color, | |
letterSpacing: letterSpacing, | |
)); | |
} | |
void _drawBg1() { | |
var percent = _tweenBg1.value; | |
var len = _metrics.length * (1 - percent); | |
var newPath = _metrics.extractPath(0, len); | |
bg.graphics.clear(); | |
bg.graphics.lineStyle(.4 + (percent * 2.5), Colors.white.value); | |
bg.graphics.drawPath(newPath); | |
bg.graphics.endFill(); | |
} | |
void _drawBg2() { | |
var from = _metrics.length - 90 * _tweenBg2.value; | |
var to = from + 20; | |
var newPath = _metrics.extractPath(from, to); | |
bg2.graphics.clear(); | |
bg2.graphics.lineStyle(2 + _tweenBg2.value * 1, Colors.white.value); | |
bg2.graphics.drawPath(newPath); | |
bg2.graphics.endFill(); | |
} | |
void _drawText() { | |
var variants = FontWeight.values; | |
var idx = (_tweenTf.value * (variants.length - 2)).round(); | |
var weight = variants[idx]; | |
_setStyle( | |
fontWeight: weight, | |
letterSpacing: _tweenTf.value, | |
color: Colors.white, | |
fontSize: 18, | |
); | |
tf.alignPivot(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment