nonebot-plugin-osubot 6.24.0__py3-none-any.whl → 6.24.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nonebot-plugin-osubot might be problematic. Click here for more details.
- nonebot_plugin_osubot/draw/osu_preview.py +64 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/css/style.css +258 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/README.md +109 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.js +3 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.js.map +1 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.worker.js +3 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.worker.js.map +1 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/beatmap.js +211 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/hitobject.js +29 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/point.js +55 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/scroll.js +45 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/timingpoint.js +35 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/LegacyRandom.js +81 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/PalpableCatchHitObject.js +53 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/bananashower.js +33 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/catch.js +211 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/fruit.js +21 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/juicestream.js +176 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/hitnote.js +21 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/holdnote.js +37 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/mania.js +164 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/preview.js +61 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/bezier2.js +33 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/catmullcurve.js +34 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/centripetalcatmullrom.js +30 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/circumstancedcircle.js +47 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/curve.js +25 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/curvetype.js +17 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/equaldistancemulticurve.js +70 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/linearbezier.js +40 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/hitcircle.js +85 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/slider.js +120 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/spinner.js +56 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/standard.js +170 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/donkat.js +40 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/drumroll.js +34 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/shaker.js +58 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/taiko.js +120 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/js/util.js +61 -0
- nonebot_plugin_osubot/draw/osu_preview_templates/pic.html +110 -0
- nonebot_plugin_osubot/matcher/preview.py +7 -0
- nonebot_plugin_osubot/pp.py +7 -0
- {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.2.dist-info}/METADATA +2 -2
- {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.2.dist-info}/RECORD +45 -5
- {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.2.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
var bgblob;
|
|
2
|
+
function Preview(SCALE = 0.2) {
|
|
3
|
+
this.screen = document.createElement('canvas');
|
|
4
|
+
this.screen.width = Beatmap.WIDTH;
|
|
5
|
+
this.screen.height = Beatmap.HEIGHT;
|
|
6
|
+
this.ctx = this.screen.getContext('2d');
|
|
7
|
+
this.ctx.scale(SCALE, SCALE);
|
|
8
|
+
this.startTime = 0;
|
|
9
|
+
this.endTime = 0;
|
|
10
|
+
this.previewTime = -1;
|
|
11
|
+
|
|
12
|
+
var self = this;
|
|
13
|
+
}
|
|
14
|
+
Preview.prototype.load = function (osufile, success, fail) {
|
|
15
|
+
if (typeof this.xhr != 'undefined') {
|
|
16
|
+
this.xhr.abort();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var self = this;
|
|
20
|
+
try {
|
|
21
|
+
self.beatmap = Beatmap.parse(osufile);
|
|
22
|
+
|
|
23
|
+
self.ctx.restore();
|
|
24
|
+
self.ctx.save();
|
|
25
|
+
self.beatmap.update(self.ctx);
|
|
26
|
+
self.at(0);
|
|
27
|
+
|
|
28
|
+
self.previewTime = self.beatmap.PreviewTime > 0 ? self.beatmap.PreviewTime : -1;
|
|
29
|
+
|
|
30
|
+
self.startTime = self.beatmap.HitObjects.length > 0 ? self.beatmap.HitObjects[0].time - 1000 : 0;
|
|
31
|
+
if (self.startTime < 0) {
|
|
32
|
+
self.startTime = 0;
|
|
33
|
+
}
|
|
34
|
+
self.endTime = self.beatmap.HitObjects.length > 0 ? self.beatmap.HitObjects[self.beatmap.HitObjects.length - 1].endTime : 0;
|
|
35
|
+
|
|
36
|
+
if (typeof success == 'function') {
|
|
37
|
+
success.call(self);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
if (typeof fail == 'function') {
|
|
42
|
+
fail.call(self, e);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
Preview.prototype.at = function (time) {
|
|
47
|
+
if (time > this.endTime) {
|
|
48
|
+
time = this.endTime;
|
|
49
|
+
}
|
|
50
|
+
if (time < this.startTime) {
|
|
51
|
+
time = this.startTime;
|
|
52
|
+
}
|
|
53
|
+
this.ctx.save();
|
|
54
|
+
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
55
|
+
this.ctx.clearRect(0, 0, Beatmap.WIDTH, Beatmap.HEIGHT);
|
|
56
|
+
this.ctx.restore();
|
|
57
|
+
if (typeof this.beatmap.processBG != 'undefined') {
|
|
58
|
+
this.beatmap.processBG(this.ctx);
|
|
59
|
+
}
|
|
60
|
+
this.beatmap.draw(time, this.ctx);
|
|
61
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function Bezier2(points)
|
|
2
|
+
{
|
|
3
|
+
// https://github.com/itdelatrisu/opsu/blob/master/src/itdelatrisu/opsu/objects/curves/Bezier2.java
|
|
4
|
+
if (points.length < 2)
|
|
5
|
+
{
|
|
6
|
+
throw 'invalid data';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
this.points = points;
|
|
10
|
+
var approxLength = 0;
|
|
11
|
+
for (var i = 1; i < this.points.length; i++)
|
|
12
|
+
{
|
|
13
|
+
approxLength += this.points[i].distanceTo(this.points[i - 1]);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
CurveType.call(this, approxLength);
|
|
17
|
+
}
|
|
18
|
+
Bezier2.prototype = Object.create(CurveType.prototype);
|
|
19
|
+
Bezier2.prototype.constructor = Bezier2;
|
|
20
|
+
Bezier2.prototype.pointAt = function(t)
|
|
21
|
+
{
|
|
22
|
+
var n = this.points.length - 1,
|
|
23
|
+
point = new Point(),
|
|
24
|
+
combination = 1;
|
|
25
|
+
for (var i = 0; i <= n; i++)
|
|
26
|
+
{
|
|
27
|
+
var bernstein = combination * Math.pow(t, i) * Math.pow(1 - t, n - i);
|
|
28
|
+
point.x += this.points[i].x * bernstein;
|
|
29
|
+
point.y += this.points[i].y * bernstein;
|
|
30
|
+
combination = combination * (n - i) / (i + 1);
|
|
31
|
+
}
|
|
32
|
+
return point;
|
|
33
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function CatmullCurve(points, pixelLength)
|
|
2
|
+
{
|
|
3
|
+
// https://github.com/itdelatrisu/opsu/blob/master/src/itdelatrisu/opsu/objects/curves/CatmullCurve.java
|
|
4
|
+
var catmulls = [],
|
|
5
|
+
controls = [];
|
|
6
|
+
if (!points[0].equalTo(points[1]))
|
|
7
|
+
{
|
|
8
|
+
controls.push(points[0]);
|
|
9
|
+
}
|
|
10
|
+
for (var i = 0; i < points.length; i++)
|
|
11
|
+
{
|
|
12
|
+
controls.push(points[i]);
|
|
13
|
+
try
|
|
14
|
+
{
|
|
15
|
+
catmulls.push(new CentripetalCatmullRom(controls));
|
|
16
|
+
controls.shift();
|
|
17
|
+
}
|
|
18
|
+
catch (e) {}
|
|
19
|
+
}
|
|
20
|
+
var point2 = points.slice(-2);
|
|
21
|
+
if (!point2[1].equalTo(point2[0]))
|
|
22
|
+
{
|
|
23
|
+
controls.push(point2[1]);
|
|
24
|
+
}
|
|
25
|
+
try
|
|
26
|
+
{
|
|
27
|
+
catmulls.push(new CentripetalCatmullRom(controls));
|
|
28
|
+
}
|
|
29
|
+
catch (e) {}
|
|
30
|
+
|
|
31
|
+
EqualDistanceMultiCurve.call(this, catmulls, pixelLength);
|
|
32
|
+
};
|
|
33
|
+
CatmullCurve.prototype = Object.create(EqualDistanceMultiCurve.prototype);
|
|
34
|
+
CatmullCurve.prototype.constructor = CatmullCurve;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function CentripetalCatmullRom(points)
|
|
2
|
+
{
|
|
3
|
+
// https://github.com/itdelatrisu/opsu/blob/master/src/itdelatrisu/opsu/objects/curves/CentripetalCatmullRom.java
|
|
4
|
+
// needs 4 points
|
|
5
|
+
if (points.length != 4)
|
|
6
|
+
{
|
|
7
|
+
throw 'invalid data';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
this.points = points;
|
|
11
|
+
var approxLength = 0;
|
|
12
|
+
for (var i = 1; i < 4; i++)
|
|
13
|
+
{
|
|
14
|
+
approxLength += this.points[i].distanceTo(this.points[i - 1]);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
CurveType.call(this, approxLength / 2);
|
|
18
|
+
}
|
|
19
|
+
CentripetalCatmullRom.prototype = Object.create(CurveType.prototype);
|
|
20
|
+
CentripetalCatmullRom.prototype.constructor = CentripetalCatmullRom;
|
|
21
|
+
CentripetalCatmullRom.prototype.pointAt = function(t)
|
|
22
|
+
{
|
|
23
|
+
t = Math.lerp(1, 2, t);
|
|
24
|
+
var A1 = this.points[0].clone().scale(1 - t).translate(this.points[1].clone().scale(t));
|
|
25
|
+
var A2 = this.points[1].clone().scale(2 - t).translate(this.points[2].clone().scale(t - 1));
|
|
26
|
+
var A3 = this.points[2].clone().scale(3 - t).translate(this.points[3].clone().scale(t - 2));
|
|
27
|
+
var B1 = A1.clone().scale(2 - t).translate(A2.clone().scale(t));
|
|
28
|
+
var B2 = A2.clone().scale(3 - t).translate(A3.clone().scale(t - 1));
|
|
29
|
+
return B1.clone().scale(2 - t).translate(B2.clone().scale(t - 1)).scale(0.5);
|
|
30
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
function CircumscribedCircle(points, pixelLength)
|
|
2
|
+
{
|
|
3
|
+
var a = points[0].x - points[1].x, b = points[0].y - points[1].y,
|
|
4
|
+
c = points[1].x - points[2].x, d = points[1].y - points[2].y,
|
|
5
|
+
q = (a * d - b * c) * 2,
|
|
6
|
+
l0 = points[0].x * points[0].x + points[0].y * points[0].y,
|
|
7
|
+
l1 = points[1].x * points[1].x + points[1].y * points[1].y,
|
|
8
|
+
l2 = points[2].x * points[2].x + points[2].y * points[2].y,
|
|
9
|
+
x = ((l0 - l1) * d + (l1 - l2) * -b) / q,
|
|
10
|
+
y = ((l0 - l1) * -c + (l1 - l2) * a) / q,
|
|
11
|
+
dx = points[0].x - x,
|
|
12
|
+
dy = points[0].y - y,
|
|
13
|
+
r = Math.hypot(dx, dy),
|
|
14
|
+
base = Math.atan2(dy, dx),
|
|
15
|
+
t = pixelLength / r * Math.ccw(points[0], points[1], points[2]);
|
|
16
|
+
if (!t)
|
|
17
|
+
{
|
|
18
|
+
// when points[2] is missing or vectors are parallel
|
|
19
|
+
throw 'invalid data';
|
|
20
|
+
}
|
|
21
|
+
this.circle = {
|
|
22
|
+
x: x,
|
|
23
|
+
y: y,
|
|
24
|
+
radius: r
|
|
25
|
+
};
|
|
26
|
+
this.angle = {
|
|
27
|
+
base: base,
|
|
28
|
+
delta: t
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
var nCurve = pixelLength / Curve.PRECISION | 0;
|
|
32
|
+
this.path = [];
|
|
33
|
+
for (var i = 0; i <= nCurve; i++)
|
|
34
|
+
{
|
|
35
|
+
this.path[i] = this.pointAt(i / nCurve);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Curve.call(this);
|
|
39
|
+
};
|
|
40
|
+
CircumscribedCircle.prototype = Object.create(Curve.prototype);
|
|
41
|
+
CircumscribedCircle.prototype.constructor = CircumscribedCircle;
|
|
42
|
+
CircumscribedCircle.prototype.pointAt = function(t)
|
|
43
|
+
{
|
|
44
|
+
var angle = this.angle.base + this.angle.delta * t;
|
|
45
|
+
return new Point(this.circle.x + Math.cos(angle) * this.circle.radius,
|
|
46
|
+
this.circle.y + Math.sin(angle) * this.circle.radius);
|
|
47
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function Curve()
|
|
2
|
+
{
|
|
3
|
+
this.startAngle = this.path[0].angleTo(this.path[1]);
|
|
4
|
+
var path2 = this.path.slice(-2);
|
|
5
|
+
this.endAngle = path2[1].angleTo(path2[0]);
|
|
6
|
+
}
|
|
7
|
+
Curve.prototype.path = undefined;
|
|
8
|
+
Curve.prototype.pointAt = undefined;
|
|
9
|
+
Curve.PRECISION = 5;
|
|
10
|
+
Curve.parse = function(sliderType, points, pixelLength)
|
|
11
|
+
{
|
|
12
|
+
try
|
|
13
|
+
{
|
|
14
|
+
if (sliderType == 'P')
|
|
15
|
+
{
|
|
16
|
+
return new CircumscribedCircle(points, pixelLength);
|
|
17
|
+
}
|
|
18
|
+
if (sliderType == 'C')
|
|
19
|
+
{
|
|
20
|
+
return new CatmullCurve(points, pixelLength);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch(e) {}
|
|
24
|
+
return new LinearBezier(points, pixelLength, sliderType == 'L');
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function CurveType(approxLength)
|
|
2
|
+
{
|
|
3
|
+
// https://github.com/itdelatrisu/opsu/blob/master/src/itdelatrisu/opsu/objects/curves/CurveType.java
|
|
4
|
+
var points = (approxLength / 4 | 0) + 1;
|
|
5
|
+
this.path = [];
|
|
6
|
+
for (var i = 0; i <= points; i++)
|
|
7
|
+
{
|
|
8
|
+
this.path[i] = this.pointAt(i / points);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
this.distance = [ 0 ];
|
|
12
|
+
for (var i = 1; i <= points; i++)
|
|
13
|
+
{
|
|
14
|
+
this.distance[i] = this.path[i].distanceTo(this.path[i - 1]);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
CurveType.prototype.pointAt = undefined;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
function EqualDistanceMultiCurve(curves, pixelLength)
|
|
2
|
+
{
|
|
3
|
+
// https://github.com/itdelatrisu/opsu/blob/master/src/itdelatrisu/opsu/objects/curves/EqualDistanceMultiCurve.java
|
|
4
|
+
var nCurve = pixelLength / Curve.PRECISION | 0;
|
|
5
|
+
this.path = [];
|
|
6
|
+
|
|
7
|
+
var distanceAt = 0,
|
|
8
|
+
curveIndex = 0,
|
|
9
|
+
curve = curves[curveIndex],
|
|
10
|
+
pointIndex = 0,
|
|
11
|
+
startPoint = curve.path[0],
|
|
12
|
+
lastDistanceAt = 0;
|
|
13
|
+
// for each distance, try to get in between the two points that are between it
|
|
14
|
+
for (var i = 0; i <= nCurve; i++)
|
|
15
|
+
{
|
|
16
|
+
var prefDistance = i * pixelLength / nCurve | 0;
|
|
17
|
+
while (distanceAt < prefDistance)
|
|
18
|
+
{
|
|
19
|
+
lastDistanceAt = distanceAt;
|
|
20
|
+
startPoint = curve.path[pointIndex];
|
|
21
|
+
|
|
22
|
+
if (++pointIndex >= curve.path.length)
|
|
23
|
+
{
|
|
24
|
+
if (curveIndex + 1 < curves.length)
|
|
25
|
+
{
|
|
26
|
+
curve = curves[++curveIndex];
|
|
27
|
+
pointIndex = 0;
|
|
28
|
+
}
|
|
29
|
+
else
|
|
30
|
+
{
|
|
31
|
+
pointIndex = curve.path.length - 1;
|
|
32
|
+
if (lastDistanceAt == distanceAt)
|
|
33
|
+
{
|
|
34
|
+
// out of points even though the preferred distance hasn't been reached
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
distanceAt += curve.distance[pointIndex];
|
|
40
|
+
}
|
|
41
|
+
var endPoint = curve.path[pointIndex];
|
|
42
|
+
|
|
43
|
+
// interpolate the point between the two closest distances
|
|
44
|
+
if (distanceAt - lastDistanceAt > 1)
|
|
45
|
+
{
|
|
46
|
+
this.path[i] = Math.lerp(startPoint, endPoint, (prefDistance - lastDistanceAt) / (distanceAt - lastDistanceAt));
|
|
47
|
+
}
|
|
48
|
+
else
|
|
49
|
+
{
|
|
50
|
+
this.path[i] = endPoint;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
Curve.call(this);
|
|
55
|
+
};
|
|
56
|
+
EqualDistanceMultiCurve.prototype = Object.create(Curve.prototype);
|
|
57
|
+
EqualDistanceMultiCurve.prototype.constructor = EqualDistanceMultiCurve;
|
|
58
|
+
EqualDistanceMultiCurve.prototype.pointAt = function(t)
|
|
59
|
+
{
|
|
60
|
+
var indexF = this.path.length * t,
|
|
61
|
+
index = indexF | 0;
|
|
62
|
+
if (index + 1 < this.path.length)
|
|
63
|
+
{
|
|
64
|
+
return Math.lerp(this.path[index], this.path[index + 1], indexF - index);
|
|
65
|
+
}
|
|
66
|
+
else
|
|
67
|
+
{
|
|
68
|
+
return this.path[this.path.length - 1];
|
|
69
|
+
}
|
|
70
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function LinearBezier(points, pixelLength, linear)
|
|
2
|
+
{
|
|
3
|
+
// https://github.com/itdelatrisu/opsu/blob/master/src/itdelatrisu/opsu/objects/curves/LinearBezier.java
|
|
4
|
+
var beziers = [],
|
|
5
|
+
controls = [],
|
|
6
|
+
last;
|
|
7
|
+
for (var i = 0; i < points.length; i++)
|
|
8
|
+
{
|
|
9
|
+
var point = points[i];
|
|
10
|
+
if (linear)
|
|
11
|
+
{
|
|
12
|
+
if (typeof last != 'undefined')
|
|
13
|
+
{
|
|
14
|
+
controls.push(point);
|
|
15
|
+
beziers.push(new Bezier2(controls));
|
|
16
|
+
controls = [];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else if (point.equalTo(last))
|
|
20
|
+
{
|
|
21
|
+
try
|
|
22
|
+
{
|
|
23
|
+
beziers.push(new Bezier2(controls));
|
|
24
|
+
}
|
|
25
|
+
catch (e) {}
|
|
26
|
+
controls = [];
|
|
27
|
+
}
|
|
28
|
+
controls.push(point);
|
|
29
|
+
last = point;
|
|
30
|
+
}
|
|
31
|
+
try
|
|
32
|
+
{
|
|
33
|
+
beziers.push(new Bezier2(controls));
|
|
34
|
+
}
|
|
35
|
+
catch (e) {}
|
|
36
|
+
|
|
37
|
+
EqualDistanceMultiCurve.call(this, beziers, pixelLength);
|
|
38
|
+
};
|
|
39
|
+
LinearBezier.prototype = Object.create(EqualDistanceMultiCurve.prototype);
|
|
40
|
+
LinearBezier.prototype.constructor = LinearBezier;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
function HitCircle(data, beatmap)
|
|
2
|
+
{
|
|
3
|
+
HitObject.call(this, data, beatmap);
|
|
4
|
+
|
|
5
|
+
this.stack = 0;
|
|
6
|
+
}
|
|
7
|
+
HitCircle.prototype = Object.create(HitObject.prototype, {
|
|
8
|
+
newCombo: {
|
|
9
|
+
get: function()
|
|
10
|
+
{
|
|
11
|
+
return this.flag & 4;
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
comboSkip: {
|
|
15
|
+
get: function()
|
|
16
|
+
{
|
|
17
|
+
return this.flag >> 4;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
HitCircle.prototype.constructor = HitCircle;
|
|
22
|
+
HitCircle.ID = 1;
|
|
23
|
+
Standard.prototype.hitObjectTypes[HitCircle.ID] = HitCircle;
|
|
24
|
+
HitCircle.FADE_IN_TIME = 375;
|
|
25
|
+
HitCircle.FADE_OUT_TIME = 200;
|
|
26
|
+
HitCircle.prototype.draw = function(time, ctx)
|
|
27
|
+
{
|
|
28
|
+
var dt = this.time - time,
|
|
29
|
+
opacity = 1;
|
|
30
|
+
if (dt >= 0)
|
|
31
|
+
{
|
|
32
|
+
opacity = (this.beatmap.approachTime - dt) / HitCircle.FADE_IN_TIME;
|
|
33
|
+
}
|
|
34
|
+
else
|
|
35
|
+
{
|
|
36
|
+
opacity = 1 + dt / HitCircle.FADE_OUT_TIME;
|
|
37
|
+
}
|
|
38
|
+
ctx.globalAlpha = Math.max(0, Math.min(opacity, 1));
|
|
39
|
+
|
|
40
|
+
this.drawCircle(this.position, ctx);
|
|
41
|
+
this.drawText(this.position, this.combo, 0, ctx);
|
|
42
|
+
if (dt >= 0)
|
|
43
|
+
{
|
|
44
|
+
this.drawApproach(dt, ctx);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
HitCircle.prototype.drawCircle = function(position, ctx)
|
|
48
|
+
{
|
|
49
|
+
// HitCircle
|
|
50
|
+
ctx.beginPath();
|
|
51
|
+
ctx.arc(position.x - this.stack * this.beatmap.stackOffset,
|
|
52
|
+
position.y - this.stack * this.beatmap.stackOffset,
|
|
53
|
+
this.beatmap.circleRadius - this.beatmap.circleBorder / 2, -Math.PI, Math.PI);
|
|
54
|
+
ctx.shadowBlur = 0;
|
|
55
|
+
ctx.fillStyle = this.color;
|
|
56
|
+
ctx.fill();
|
|
57
|
+
// Overlay
|
|
58
|
+
ctx.shadowBlur = this.beatmap.shadowBlur;
|
|
59
|
+
ctx.strokeStyle = '#fff';
|
|
60
|
+
ctx.lineWidth = this.beatmap.circleBorder;
|
|
61
|
+
ctx.stroke();
|
|
62
|
+
};
|
|
63
|
+
HitCircle.prototype.drawText = function(position, text, deg, ctx)
|
|
64
|
+
{
|
|
65
|
+
ctx.shadowBlur = this.beatmap.shadowBlur;
|
|
66
|
+
ctx.fillStyle = '#fff';
|
|
67
|
+
ctx.save();
|
|
68
|
+
ctx.translate(position.x - this.stack * this.beatmap.stackOffset,
|
|
69
|
+
position.y - this.stack * this.beatmap.stackOffset);
|
|
70
|
+
ctx.rotate(deg);
|
|
71
|
+
ctx.fillText(text, 0, 0);
|
|
72
|
+
ctx.restore();
|
|
73
|
+
};
|
|
74
|
+
HitCircle.prototype.drawApproach = function(dt, ctx)
|
|
75
|
+
{
|
|
76
|
+
var scale = 1 + dt / this.beatmap.approachTime * 3;
|
|
77
|
+
ctx.beginPath();
|
|
78
|
+
ctx.arc(this.position.x - this.stack * this.beatmap.stackOffset,
|
|
79
|
+
this.position.y - this.stack * this.beatmap.stackOffset,
|
|
80
|
+
this.beatmap.circleRadius * scale - this.beatmap.circleBorder / 2, -Math.PI, Math.PI);
|
|
81
|
+
ctx.shadowBlur = 0;
|
|
82
|
+
ctx.strokeStyle = this.color;
|
|
83
|
+
ctx.lineWidth = this.beatmap.circleBorder / 2 * scale;
|
|
84
|
+
ctx.stroke();
|
|
85
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
function Slider(data, beatmap)
|
|
2
|
+
{
|
|
3
|
+
HitCircle.call(this, data, beatmap);
|
|
4
|
+
|
|
5
|
+
var points = data[5].split('|');
|
|
6
|
+
var sliderType = points[0];
|
|
7
|
+
points[0] = this.position;
|
|
8
|
+
for (var i = 1; i < points.length; i++)
|
|
9
|
+
{
|
|
10
|
+
points[i] = new Point(points[i].split(':'));
|
|
11
|
+
}
|
|
12
|
+
this.repeat = data[6] | 0;
|
|
13
|
+
this.pixelLength = +data[7];
|
|
14
|
+
|
|
15
|
+
var sliderTime = this.beatmap.timingPointAt(this.time).beatLength * (
|
|
16
|
+
this.pixelLength / this.beatmap.SliderMultiplier
|
|
17
|
+
) / 100;
|
|
18
|
+
this.endTime += sliderTime * this.repeat;
|
|
19
|
+
this.duration = this.endTime - this.time;
|
|
20
|
+
|
|
21
|
+
this.curve = Curve.parse(sliderType, points, this.pixelLength);
|
|
22
|
+
|
|
23
|
+
this.endPosition = this.curve.pointAt(1);
|
|
24
|
+
}
|
|
25
|
+
Slider.prototype = Object.create(HitCircle.prototype);
|
|
26
|
+
Slider.prototype.constructor = Slider;
|
|
27
|
+
Slider.ID = 2;
|
|
28
|
+
Standard.prototype.hitObjectTypes[Slider.ID] = Slider;
|
|
29
|
+
Slider.FADE_IN_TIME = 375;
|
|
30
|
+
Slider.FADE_OUT_TIME = 200;
|
|
31
|
+
Slider.REVERSE_ARROW = String.fromCharCode(10132);
|
|
32
|
+
Slider.OPACITY = 0.66;
|
|
33
|
+
Slider.prototype.draw = function(time, ctx)
|
|
34
|
+
{
|
|
35
|
+
var dt = this.time - time,
|
|
36
|
+
opacity = 1;
|
|
37
|
+
if (dt >= 0)
|
|
38
|
+
{
|
|
39
|
+
opacity = (this.beatmap.approachTime - dt) / Slider.FADE_IN_TIME;
|
|
40
|
+
}
|
|
41
|
+
else if (time > this.endTime)
|
|
42
|
+
{
|
|
43
|
+
opacity = 1 - (time - this.endTime) / Slider.FADE_OUT_TIME;
|
|
44
|
+
}
|
|
45
|
+
ctx.globalAlpha = Math.max(0, Math.min(opacity, 1));
|
|
46
|
+
|
|
47
|
+
this.drawPath(ctx);
|
|
48
|
+
// this.drawCircle(this.endPosition, ctx);
|
|
49
|
+
// this.drawCircle(this.position, ctx);
|
|
50
|
+
|
|
51
|
+
var repeat = -dt * this.repeat / this.duration;
|
|
52
|
+
// this.repeat - this.repeat % 2: 홀수면 짝수로 내리기
|
|
53
|
+
if (this.repeat > 1 && repeat + 1 <= (this.repeat & ~1))
|
|
54
|
+
{
|
|
55
|
+
this.drawCircle(this.endPosition, ctx);
|
|
56
|
+
this.drawText(this.endPosition, Slider.REVERSE_ARROW, this.curve.endAngle, ctx);
|
|
57
|
+
}
|
|
58
|
+
// this.repeat - (this.repeat + 1) % 2: 짝수면 홀수로 내리기
|
|
59
|
+
if (repeat > 0 && repeat + 1 <= this.repeat - !(this.repeat & 1))
|
|
60
|
+
{
|
|
61
|
+
this.drawCircle(this.position, ctx);
|
|
62
|
+
this.drawText(this.position, Slider.REVERSE_ARROW, this.curve.startAngle, ctx);
|
|
63
|
+
}
|
|
64
|
+
else if (dt >= 0)
|
|
65
|
+
{
|
|
66
|
+
this.drawCircle(this.position, ctx);
|
|
67
|
+
this.drawText(this.position, this.combo, 0, ctx);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (dt >= 0)
|
|
71
|
+
{
|
|
72
|
+
this.drawApproach(dt, ctx);
|
|
73
|
+
}
|
|
74
|
+
else if (time < this.endTime)
|
|
75
|
+
{
|
|
76
|
+
this.drawFollowCircle(repeat, ctx);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
Slider.prototype.drawPath = function(ctx)
|
|
80
|
+
{
|
|
81
|
+
ctx.save();
|
|
82
|
+
// Slider
|
|
83
|
+
ctx.globalAlpha *= Slider.OPACITY;
|
|
84
|
+
ctx.beginPath();
|
|
85
|
+
ctx.moveTo(this.position.x - this.stack * this.beatmap.stackOffset,
|
|
86
|
+
this.position.y - this.stack * this.beatmap.stackOffset);
|
|
87
|
+
for (var i = 1; i < this.curve.path.length; i++)
|
|
88
|
+
{
|
|
89
|
+
ctx.lineTo(this.curve.path[i].x - this.stack * this.beatmap.stackOffset,
|
|
90
|
+
this.curve.path[i].y - this.stack * this.beatmap.stackOffset);
|
|
91
|
+
}
|
|
92
|
+
ctx.shadowBlur = 0;
|
|
93
|
+
ctx.strokeStyle = this.color;
|
|
94
|
+
ctx.lineWidth = (this.beatmap.circleRadius - this.beatmap.circleBorder) * 2;
|
|
95
|
+
ctx.stroke();
|
|
96
|
+
// Border
|
|
97
|
+
ctx.globalCompositeOperation = 'destination-over';
|
|
98
|
+
ctx.shadowBlur = 0;
|
|
99
|
+
ctx.strokeStyle = '#fff';
|
|
100
|
+
ctx.lineWidth = this.beatmap.circleRadius * 2;
|
|
101
|
+
ctx.stroke();
|
|
102
|
+
ctx.restore();
|
|
103
|
+
};
|
|
104
|
+
Slider.prototype.drawFollowCircle = function(repeat, ctx)
|
|
105
|
+
{
|
|
106
|
+
repeat %= 2;
|
|
107
|
+
if (repeat > 1)
|
|
108
|
+
{
|
|
109
|
+
repeat = 2 - repeat;
|
|
110
|
+
}
|
|
111
|
+
var point = this.curve.pointAt(repeat);
|
|
112
|
+
ctx.beginPath();
|
|
113
|
+
ctx.arc(point.x - this.stack * this.beatmap.stackOffset,
|
|
114
|
+
point.y - this.stack * this.beatmap.stackOffset,
|
|
115
|
+
this.beatmap.circleRadius - this.beatmap.circleBorder / 2, -Math.PI, Math.PI);
|
|
116
|
+
ctx.shadowBlur = this.beatmap.shadowBlur;
|
|
117
|
+
ctx.strokeStyle = '#fff';
|
|
118
|
+
ctx.lineWidth = this.beatmap.circleBorder;
|
|
119
|
+
ctx.stroke();
|
|
120
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
function Spinner(data, beatmap)
|
|
2
|
+
{
|
|
3
|
+
HitCircle.call(this, data, beatmap);
|
|
4
|
+
|
|
5
|
+
this.endTime = data[5] | 0;
|
|
6
|
+
this.duration = this.endTime - this.time;
|
|
7
|
+
}
|
|
8
|
+
Spinner.prototype = Object.create(HitCircle.prototype);
|
|
9
|
+
Spinner.prototype.constructor = Spinner;
|
|
10
|
+
Spinner.ID = 8;
|
|
11
|
+
Standard.prototype.hitObjectTypes[Spinner.ID] = Spinner;
|
|
12
|
+
Spinner.FADE_IN_TIME = 500;
|
|
13
|
+
Spinner.FADE_OUT_TIME = 200;
|
|
14
|
+
Spinner.RADIUS = Beatmap.MAX_Y / 2;
|
|
15
|
+
Spinner.BORDER_WIDTH = Spinner.RADIUS / 20;
|
|
16
|
+
Spinner.prototype.draw = function(time, ctx)
|
|
17
|
+
{
|
|
18
|
+
var dt = this.time - time,
|
|
19
|
+
opacity = 1;
|
|
20
|
+
if (dt >= 0)
|
|
21
|
+
{
|
|
22
|
+
opacity = (this.beatmap.approachTime - dt) / Spinner.FADE_IN_TIME;
|
|
23
|
+
}
|
|
24
|
+
else if (time > this.endTime)
|
|
25
|
+
{
|
|
26
|
+
opacity = 1 - (time - this.endTime) / Spinner.FADE_OUT_TIME;
|
|
27
|
+
}
|
|
28
|
+
ctx.globalAlpha = Math.max(0, Math.min(opacity, 1));
|
|
29
|
+
ctx.save();
|
|
30
|
+
// Spinner
|
|
31
|
+
ctx.beginPath();
|
|
32
|
+
ctx.arc(this.position.x, this.position.y,
|
|
33
|
+
Spinner.RADIUS - Spinner.BORDER_WIDTH / 2, -Math.PI, Math.PI);
|
|
34
|
+
ctx.globalCompositeOperation = 'destination-over';
|
|
35
|
+
ctx.shadowBlur = 0;
|
|
36
|
+
ctx.fillStyle = 'rgba(0,0,0,.4)';
|
|
37
|
+
ctx.fill();
|
|
38
|
+
// Border
|
|
39
|
+
ctx.shadowBlur = Spinner.BORDER_WIDTH;
|
|
40
|
+
ctx.strokeStyle = '#fff';
|
|
41
|
+
ctx.lineWidth = Spinner.BORDER_WIDTH;
|
|
42
|
+
ctx.stroke();
|
|
43
|
+
ctx.restore();
|
|
44
|
+
// Approach
|
|
45
|
+
if (dt < 0 && time <= this.endTime)
|
|
46
|
+
{
|
|
47
|
+
var scale = 1 + dt / this.duration;
|
|
48
|
+
ctx.beginPath();
|
|
49
|
+
ctx.arc(this.position.x, this.position.y,
|
|
50
|
+
(Spinner.RADIUS - Spinner.BORDER_WIDTH / 2) * scale, -Math.PI, Math.PI);
|
|
51
|
+
ctx.shadowBlur = 3;
|
|
52
|
+
ctx.strokeStyle = '#fff';
|
|
53
|
+
ctx.lineWidth = (Spinner.BORDER_WIDTH / 2) * scale;
|
|
54
|
+
ctx.stroke();
|
|
55
|
+
}
|
|
56
|
+
};
|