treewide: dart format + analyze + some other fixes
This commit is contained in:
@@ -6,21 +6,19 @@ import '../common/point.dart';
|
||||
|
||||
import 'bezier_cubic.dart' as bezier_cubic;
|
||||
import 'package:xml/xml.dart';
|
||||
import 'package:path/path.dart';
|
||||
|
||||
double _computePathLength(String path) =>
|
||||
parsePath(path).size(error: 1e-8).toDouble();
|
||||
|
||||
String _shescape(String path) =>
|
||||
"'${path.replaceAll(RegExp(r"(?=['\\\\])"), "\\\\")}'";
|
||||
// String _shescape(String path) =>
|
||||
// "'${path.replaceAll(RegExp(r"(?=['\\\\])"), "\\\\")}'";
|
||||
|
||||
extension _Dedent on String {
|
||||
String get dedented {
|
||||
final withoutEmptyLines =
|
||||
this.split('\n').where((l) => l.isNotEmpty).toList();
|
||||
final withoutEmptyLines = split('\n').where((l) => l.isNotEmpty).toList();
|
||||
final whitespaceAmounts = [
|
||||
for (final line in withoutEmptyLines)
|
||||
line.split('').takeWhile((c) => c == ' ').length
|
||||
line.split('').takeWhile((c) => c == ' ').length,
|
||||
];
|
||||
final whitespaceToRemove = whitespaceAmounts.reduce(min);
|
||||
return withoutEmptyLines
|
||||
@@ -63,40 +61,34 @@ const pt2 = Point(1, 1);
|
||||
// class {
|
||||
// }
|
||||
|
||||
enum TimingFunction {
|
||||
linear,
|
||||
ease,
|
||||
easeIn,
|
||||
easeInOut,
|
||||
easeOut,
|
||||
}
|
||||
enum TimingFunction { linear, ease, easeIn, easeInOut, easeOut }
|
||||
|
||||
extension Funcs on TimingFunction {
|
||||
double Function(double) get func => {
|
||||
TimingFunction.linear: (double x) => x,
|
||||
TimingFunction.ease: (double x) =>
|
||||
bezier_cubic.value(pt1, easeCt1, easeCt2, pt2, x),
|
||||
TimingFunction.easeIn: (double x) =>
|
||||
bezier_cubic.value(pt1, easeInCt1, easeInCt2, pt2, x),
|
||||
TimingFunction.easeInOut: (double x) =>
|
||||
bezier_cubic.value(pt1, easeInOutCt1, easeInOutCt2, pt2, x),
|
||||
TimingFunction.easeOut: (double x) =>
|
||||
bezier_cubic.value(pt1, easeOutCt1, easeOutCt2, pt2, x),
|
||||
}[this]!;
|
||||
TimingFunction.linear: (double x) => x,
|
||||
TimingFunction.ease: (double x) =>
|
||||
bezier_cubic.value(pt1, easeCt1, easeCt2, pt2, x),
|
||||
TimingFunction.easeIn: (double x) =>
|
||||
bezier_cubic.value(pt1, easeInCt1, easeInCt2, pt2, x),
|
||||
TimingFunction.easeInOut: (double x) =>
|
||||
bezier_cubic.value(pt1, easeInOutCt1, easeInOutCt2, pt2, x),
|
||||
TimingFunction.easeOut: (double x) =>
|
||||
bezier_cubic.value(pt1, easeOutCt1, easeOutCt2, pt2, x),
|
||||
}[this]!;
|
||||
|
||||
String get name => {
|
||||
TimingFunction.linear: 'linear',
|
||||
TimingFunction.ease: 'ease',
|
||||
TimingFunction.easeIn: 'ease-in',
|
||||
TimingFunction.easeInOut: 'ease-in-out',
|
||||
TimingFunction.easeOut: 'ease-out',
|
||||
}[this]!;
|
||||
TimingFunction.linear: 'linear',
|
||||
TimingFunction.ease: 'ease',
|
||||
TimingFunction.easeIn: 'ease-in',
|
||||
TimingFunction.easeInOut: 'ease-in-out',
|
||||
TimingFunction.easeOut: 'ease-out',
|
||||
}[this]!;
|
||||
}
|
||||
|
||||
// we will need this to deal with svg
|
||||
const namespaces = {
|
||||
'n': 'http://www.w3.org/2000/svg',
|
||||
'xlink': 'http://www.w3.org/1999/xlink'
|
||||
'xlink': 'http://www.w3.org/1999/xlink',
|
||||
};
|
||||
// etree.register_namespace("xlink","http://www.w3.org/1999/xlink")
|
||||
// final parser = etree.XMLParser(remove_blank_text=true);
|
||||
@@ -124,26 +116,36 @@ double timeRescale(interval) => pow(2 * interval, 2.0 / 3).toDouble();
|
||||
|
||||
/// clear all extra elements this program may have previously added
|
||||
void clearPreviousElements(XmlDocument doc) {
|
||||
for (final XmlNode el in doc
|
||||
.getElement('svg', namespace: namespaces['n'])
|
||||
?.getElement('style', namespace: namespaces['n'])
|
||||
?.children ??
|
||||
[]) {
|
||||
for (final XmlNode el
|
||||
in doc
|
||||
.getElement('svg', namespace: namespaces['n'])
|
||||
?.getElement('style', namespace: namespaces['n'])
|
||||
?.children ??
|
||||
[]) {
|
||||
if (RegExp(r'-Kanimaji$').hasMatch(el.getAttribute('id') ?? '')) {
|
||||
el.parent!.children.remove(el);
|
||||
}
|
||||
}
|
||||
for (final XmlNode g in doc
|
||||
.getElement('svg', namespace: namespaces['n'])
|
||||
?.getElement('g', namespace: namespaces['n'])
|
||||
?.children ??
|
||||
[]) {
|
||||
for (final XmlNode g
|
||||
in doc
|
||||
.getElement('svg', namespace: namespaces['n'])
|
||||
?.getElement('g', namespace: namespaces['n'])
|
||||
?.children ??
|
||||
[]) {
|
||||
if (RegExp(r'-Kanimaji$').hasMatch(g.getAttribute('id') ?? '')) {
|
||||
g.parent!.children.remove(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String basename(String path) {
|
||||
final int lastSlash = path.lastIndexOf(Platform.pathSeparator);
|
||||
if (lastSlash == -1) {
|
||||
return path;
|
||||
}
|
||||
return path.substring(lastSlash + 1);
|
||||
}
|
||||
|
||||
/// Note: setting any color to transparent will result in a much bigger
|
||||
/// filesize for GIFs.
|
||||
void createAnimation({
|
||||
@@ -190,7 +192,8 @@ void createAnimation({
|
||||
'g',
|
||||
attributes: {
|
||||
'id': 'kvg:$baseid-$id-Kanimaji',
|
||||
'style': 'fill:none;'
|
||||
'style':
|
||||
'fill:none;'
|
||||
'stroke:$color;'
|
||||
'stroke-width:$width;'
|
||||
'stroke-linecap:round;'
|
||||
@@ -232,11 +235,12 @@ void createAnimation({
|
||||
double tottime = 0;
|
||||
|
||||
// for (final g in doc.xpath("/n:svg/n:g", namespaces=namespaces) {
|
||||
for (final XmlNode g in doc
|
||||
.getElement('svg', namespace: namespaces['n'])
|
||||
?.getElement('g', namespace: namespaces['n'])
|
||||
?.children ??
|
||||
[]) {
|
||||
for (final XmlNode g
|
||||
in doc
|
||||
.getElement('svg', namespace: namespaces['n'])
|
||||
?.getElement('g', namespace: namespaces['n'])
|
||||
?.children ??
|
||||
[]) {
|
||||
if (RegExp(r'^kvg:StrokeNumbers_').hasMatch(g.getAttribute('id') ?? '')) {
|
||||
continue;
|
||||
}
|
||||
@@ -266,9 +270,7 @@ void createAnimation({
|
||||
'\n/* CSS automatically generated by kanimaji.py, do not edit! */\n';
|
||||
if (GENERATE_SVG) animatedCss = cssHeader;
|
||||
if (GENERATE_JS_SVG) {
|
||||
jsAnimatedCss += cssHeader +
|
||||
'''
|
||||
.backward {\n
|
||||
jsAnimatedCss += '''$cssHeader .backward {\n
|
||||
animation-direction: reverse !important;\n
|
||||
}
|
||||
''';
|
||||
@@ -287,18 +289,20 @@ void createAnimation({
|
||||
double elapsedtime = 0;
|
||||
|
||||
// add css elements for all strokes
|
||||
for (final XmlNode g in doc
|
||||
.getElement('svg', namespace: namespaces['n'])!
|
||||
.findElements('g', namespace: namespaces['n'])) {
|
||||
for (final XmlNode g
|
||||
in doc
|
||||
.getElement('svg', namespace: namespaces['n'])!
|
||||
.findElements('g', namespace: namespaces['n'])) {
|
||||
// for (final g in doc.xpath("/n:svg/n:g", namespaces=namespaces)){
|
||||
final groupid = g.getAttribute('id') ?? '';
|
||||
if (RegExp(r'^kvg:StrokeNumbers_').hasMatch(groupid)) {
|
||||
final String rule = '''
|
||||
final String rule =
|
||||
'''
|
||||
#${groupid.replaceAll(':', '\\3a ')} {
|
||||
display: none;
|
||||
}
|
||||
'''
|
||||
.dedented;
|
||||
.dedented;
|
||||
if (GENERATE_SVG) animatedCss += rule;
|
||||
if (GENERATE_JS_SVG) jsAnimatedCss += rule;
|
||||
if (GENERATE_GIF) {
|
||||
@@ -310,13 +314,14 @@ void createAnimation({
|
||||
}
|
||||
|
||||
final gidcss = groupid.replaceAll(':', '\\3a ');
|
||||
final rule = '''
|
||||
final rule =
|
||||
'''
|
||||
#$gidcss {
|
||||
stroke-width: ${strokeBorderWidth.toStringAsFixed(1)}px !important;
|
||||
stroke: $strokeBorderColor !important;
|
||||
}
|
||||
'''
|
||||
.dedented;
|
||||
.dedented;
|
||||
|
||||
if (GENERATE_SVG) animatedCss += rule;
|
||||
if (GENERATE_JS_SVG) jsAnimatedCss += rule;
|
||||
@@ -380,7 +385,8 @@ void createAnimation({
|
||||
|
||||
if (GENERATE_SVG) {
|
||||
// animation stroke progression
|
||||
animatedCss += '''
|
||||
animatedCss +=
|
||||
'''
|
||||
@keyframes strike-$pathname {
|
||||
0% { stroke-dashoffset: ${pathlen.toStringAsFixed(3)}; }
|
||||
${animStart.toStringAsFixed(3)}% { stroke-dashoffset: ${pathlen.toStringAsFixed(3)}; }
|
||||
@@ -398,11 +404,12 @@ void createAnimation({
|
||||
showhide-$pathname ${animationTime.toStringAsFixed(3)}s step-start infinite;
|
||||
}
|
||||
'''
|
||||
.dedented;
|
||||
.dedented;
|
||||
|
||||
if (showBrush) {
|
||||
// brush element visibility
|
||||
animatedCss += '''
|
||||
animatedCss +=
|
||||
'''
|
||||
@keyframes showhide-brush-$pathname {
|
||||
${animStart.toStringAsFixed(3)}% { visibility: hidden; }
|
||||
${animEnd.toStringAsFixed(3)}% { visibility: visible; }
|
||||
@@ -414,7 +421,7 @@ void createAnimation({
|
||||
showhide-brush-$pathname ${animationTime.toStringAsFixed(3)}s step-start infinite;
|
||||
}
|
||||
'''
|
||||
.dedented;
|
||||
.dedented;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,17 +430,19 @@ void createAnimation({
|
||||
|
||||
// brush and background hidden by default
|
||||
if (showBrush) {
|
||||
jsAnimatedCss += '''
|
||||
jsAnimatedCss +=
|
||||
'''
|
||||
#$brushPathidcss, #$brushBorderPathidcss, #$bgPathidcss {
|
||||
visibility: hidden;
|
||||
}
|
||||
'''
|
||||
.dedented;
|
||||
.dedented;
|
||||
}
|
||||
|
||||
// hide stroke after current element
|
||||
const afterCurrent = '[class *= "current"]';
|
||||
jsAnimatedCss += '''
|
||||
jsAnimatedCss +=
|
||||
'''
|
||||
$afterCurrent ~ #$animPathidcss {
|
||||
visibility: hidden;
|
||||
}
|
||||
@@ -451,9 +460,10 @@ void createAnimation({
|
||||
animation: strike-$pathname ${relativeDuration.toStringAsFixed(3)}s ${timingFunction.name} forwards 1;
|
||||
}
|
||||
'''
|
||||
.dedented;
|
||||
.dedented;
|
||||
if (showBrush) {
|
||||
jsAnimatedCss += '''
|
||||
jsAnimatedCss +=
|
||||
'''
|
||||
@keyframes strike-brush-$pathname {
|
||||
0% { stroke-dashoffset: ${pathlen.toStringAsFixed(3)}; }
|
||||
100% { stroke-dashoffset: 0.4; }
|
||||
@@ -464,7 +474,7 @@ void createAnimation({
|
||||
animation: strike-brush-$pathname ${relativeDuration.toStringAsFixed(3)}s ${timingFunction.name} forwards 1;
|
||||
}
|
||||
'''
|
||||
.dedented;
|
||||
.dedented;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +483,7 @@ void createAnimation({
|
||||
final time = k * GIF_FRAME_DURATION;
|
||||
final reltime = time * tottime / animationTime; // unscaled time
|
||||
|
||||
staticCss[k] = staticCss[k]! + '\n/* stroke $pathid */\n';
|
||||
staticCss[k] = '${staticCss[k]!}\n/* stroke $pathid */\n';
|
||||
|
||||
String rule = '';
|
||||
|
||||
@@ -486,7 +496,8 @@ void createAnimation({
|
||||
rule += ", #$brushPathidcss, #$brushBorderPathidcss";
|
||||
}
|
||||
|
||||
staticCss[k] = staticCss[k]! +
|
||||
staticCss[k] =
|
||||
staticCss[k]! +
|
||||
'''
|
||||
%$rule {
|
||||
visibility: hidden;
|
||||
@@ -501,7 +512,8 @@ void createAnimation({
|
||||
rule += ", #$brushPathidcss, #$brushBorderPathidcss";
|
||||
}
|
||||
|
||||
staticCss[k] = staticCss[k]! +
|
||||
staticCss[k] =
|
||||
staticCss[k]! +
|
||||
'''
|
||||
$rule {
|
||||
visibility: hidden;
|
||||
@@ -513,7 +525,8 @@ void createAnimation({
|
||||
((reltime - elapsedtime) / (newelapsedtime - elapsedtime));
|
||||
final progression = timingFunction.func(intervalprop);
|
||||
|
||||
staticCss[k] = staticCss[k]! +
|
||||
staticCss[k] =
|
||||
staticCss[k]! +
|
||||
'''
|
||||
#$animPathidcss {
|
||||
stroke-dasharray: ${pathlen.toStringAsFixed(3)} ${(pathlen + 0.002).toStringAsFixed(3)};
|
||||
@@ -523,7 +536,8 @@ void createAnimation({
|
||||
'''
|
||||
.dedented;
|
||||
if (showBrush) {
|
||||
staticCss[k] = staticCss[k]! +
|
||||
staticCss[k] =
|
||||
staticCss[k]! +
|
||||
'''
|
||||
#$brushPathidcss, #$brushBorderPathidcss {
|
||||
stroke-dasharray: 0.001 ${(pathlen + 0.002).toStringAsFixed(3)};
|
||||
@@ -554,13 +568,13 @@ void createAnimation({
|
||||
if (GENERATE_SVG) {
|
||||
print(animatedCss);
|
||||
final builder = XmlBuilder();
|
||||
final style = (builder
|
||||
..element(
|
||||
'style',
|
||||
attributes: {'id': "style-Kanimaji", 'type': 'text/css'},
|
||||
nest: animatedCss,
|
||||
))
|
||||
.buildFragment();
|
||||
final style =
|
||||
(builder..element(
|
||||
'style',
|
||||
attributes: {'id': "style-Kanimaji", 'type': 'text/css'},
|
||||
nest: animatedCss,
|
||||
))
|
||||
.buildFragment();
|
||||
doc.root.firstElementChild!.children.insert(0, style);
|
||||
File(outputFile).writeAsStringSync(doc.toXmlString(pretty: true));
|
||||
doc.root.children.removeAt(0);
|
||||
@@ -684,16 +698,15 @@ void main(List<String> args) {
|
||||
final fileList = [];
|
||||
for (int k = 0; k < kanji.length; k++) {
|
||||
createAnimation(
|
||||
inputFile: 'assets/kanjivg/kanji/${kanji.codeUnits[k].toRadixString(16).padLeft(5, '0')}.svg',
|
||||
outputFile: '${k+1}.svg',
|
||||
);
|
||||
fileList.add('${k+1}.svg');
|
||||
inputFile:
|
||||
'assets/kanjivg/kanji/${kanji.codeUnits[k].toRadixString(16).padLeft(5, '0')}.svg',
|
||||
outputFile: '${k + 1}.svg',
|
||||
);
|
||||
fileList.add('${k + 1}.svg');
|
||||
}
|
||||
|
||||
File('index.html').writeAsStringSync(
|
||||
'<html>' +
|
||||
fileList.map((e) => File(e).readAsStringSync().replaceAll(']>', '')).join('\n') +
|
||||
'</html>'
|
||||
'<html>${fileList.map((e) => File(e).readAsStringSync().replaceAll(']>', '')).join('\n')}</html>',
|
||||
);
|
||||
// createAnimation(
|
||||
// inputFile: 'assets/kanjivg/kanji/060c5.svg',
|
||||
|
||||
Reference in New Issue
Block a user