Skip to content

Commit 3f05a97

Browse files
committed
速度グラフの表示処理/表示切替処理を実装
1 parent 958752e commit 3f05a97

File tree

4 files changed

+107
-28
lines changed

4 files changed

+107
-28
lines changed

curve_editor/host_object_editor_graph.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ namespace cved {
1515
return result;
1616
}
1717

18+
std::vector<double> GraphEditorHostObject::get_curve_velocity_array(EditMode mode, double start_x, double start_y, double end_x, double end_y, size_t n) {
19+
std::vector<double> result;
20+
for (size_t i = 0u; i < n; i++) {
21+
double x = start_x + (end_x - start_x) * i / (n - 1);
22+
double y = global::editor.editor_graph().get_curve(mode)->get_velocity(x, start_y, end_y);
23+
result.emplace_back(y);
24+
}
25+
return result;
26+
}
27+
1828
std::wstring GraphEditorHostObject::get_curve_type(uintptr_t curve_ptr) {
1929
auto curve = reinterpret_cast<GraphCurve*>(curve_ptr);
2030
if (!curve) {

curve_editor/host_object_editor_graph.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace cved {
1515
class GraphEditorHostObject : public mkaul::wv2::HostObject {
1616
static std::vector<double> get_curve_value_array(EditMode mode, double start_x, double start_y, double end_x, double end_y, size_t n);
17+
static std::vector<double> get_curve_velocity_array(EditMode mode, double start_x, double start_y, double end_x, double end_y, size_t n);
1718
static std::wstring get_curve_type(uintptr_t curve_ptr);
1819

1920
public:
@@ -22,6 +23,10 @@ namespace cved {
2223
return global::editor.editor_graph().get_curve(mode)->get_value(prog, start, end);
2324
});
2425
register_member(L"getCurveValueArray", DispatchType::Method, get_curve_value_array);
26+
register_member(L"getCurveVelocity", DispatchType::Method, +[](EditMode mode, double prog, double start, double end) {
27+
return global::editor.editor_graph().get_curve(mode)->get_velocity(prog, start, end);
28+
});
29+
register_member(L"getCurveVelocityArray", DispatchType::Method, get_curve_velocity_array);
2530
register_member(L"getCurrentCurvePtr", DispatchType::Method, +[] {
2631
return reinterpret_cast<std::uintptr_t>(global::editor.editor_graph().current_curve());
2732
});

curve_editor/ui/css/editor_graph.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
--color-fit-button: rgb(240, 240, 240);
55
--color-fit-button-hover: rgb(224, 224, 224);
66
--color-axis: rgb(0, 0, 0);
7+
--color-velocity-path: rgb(0, 0, 0);
78
--color-rect: rgb(200, 200, 200);
89
--anchor-radius: 4px;
910
}
@@ -13,6 +14,7 @@
1314
--color-fit-button: rgb(35, 35, 35);
1415
--color-fit-button-hover: rgb(52, 52, 52);
1516
--color-axis: rgb(255, 255, 255);
17+
--color-velocity-path: rgb(255, 255, 255);
1618
--color-rect: rgb(17, 17, 17);
1719
}
1820
}
@@ -77,6 +79,11 @@ body {
7779
text-anchor: start;
7880
}
7981

82+
.velocity-path {
83+
stroke: var(--color-velocity-path);
84+
opacity: 0.3;
85+
}
86+
8087
#fit {
8188
position: absolute;
8289
top: 15px;
@@ -90,19 +97,27 @@ body {
9097
color: var(--color-content);
9198
transition: all 0.2s ease-out;
9299
}
100+
93101
#fit:hover {
94102
background-color: var(--color-fit-button-hover);
95103
opacity: 0.8;
96104
}
105+
97106
#fit:active {
98107
background-color: var(--color-control-active);
99108
opacity: 0.8;
100109
}
110+
111+
#fit:focus {
112+
outline: none;
113+
}
114+
101115
.visible {
102116
visibility: visible;
103117
opacity: 0.5;
104118
transition: 0.3s;
105119
}
120+
106121
.hidden {
107122
visibility: hidden;
108123
opacity: 0;

curve_editor/ui/js/editor_graph.js

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,15 @@ class ImageObject {
4747
}
4848

4949
// D3.js用のデータを生成
50-
const createCurvePathData = (startGraphX, endGraphX) => {
50+
const createCurvePathData = (startGraphX, endGraphX, velocity = false) => {
5151
const n = config.curveResolution;
52-
let data = []
53-
const yArray = graphEditor.getCurveValueArray(config.editMode, startGraphX, 0, endGraphX, 1, n);
52+
let data = [];
53+
let yArray;
54+
if (velocity) {
55+
yArray = graphEditor.getCurveVelocityArray(config.editMode, startGraphX, 0, endGraphX, 1, n);
56+
} else {
57+
yArray = graphEditor.getCurveValueArray(config.editMode, startGraphX, 0, endGraphX, 1, n);
58+
}
5459
for (let i = 0; i < n; i++) {
5560
const x = startGraphX + (endGraphX - startGraphX) / (n - 1) * i;
5661
data.push({
@@ -62,25 +67,42 @@ const createCurvePathData = (startGraphX, endGraphX) => {
6267
}
6368

6469
// 描画するカーブの内容を更新
65-
const updateCurvePath = (t = null) => {
66-
const startGraphX = Math.max(0, currentScaleX.invert(0));
67-
const endGraphX = Math.min(1, currentScaleX.invert(width));
70+
const updateCurvePath = (t = null, zoom = false) => {
71+
const startGraphX = Math.max(0, currentScaleX.invert(zoom ? -200 : 0));
72+
const endGraphX = Math.min(1, currentScaleX.invert(width + (zoom ? 200 : 0)));
6873

69-
path.datum(createCurvePathData(startGraphX, endGraphX));
70-
(t ? path.transition(t) : path).attr('d', d3.line()
74+
curvePath.datum(createCurvePathData(startGraphX, endGraphX));
75+
(t ? curvePath.transition(t) : curvePath).attr('d', d3.line()
7176
.x(d => originalScaleX(d.x))
7277
.y(d => originalScaleY(d.y))
7378
.curve(curve));
7479

75-
const editMode = config.editMode;
76-
if (editMode == 2 || editMode == 3 || editMode == 4) {
77-
window.top.postMessage({
78-
to: 'panel-editor',
79-
command: 'updateParam'
80-
});
80+
if (!zoom) {
81+
const editMode = config.editMode;
82+
if (editMode == 2 || editMode == 3 || editMode == 4) {
83+
window.top.postMessage({
84+
to: 'panel-editor',
85+
command: 'updateParam'
86+
});
87+
}
8188
}
8289
}
8390

91+
// 描画するカーブの内容を更新
92+
const updateVelocityPath = (t = null) => {
93+
if (!config.showVelocityGraph) {
94+
return;
95+
}
96+
const startGraphX = Math.max(0, currentScaleX.invert(0));
97+
const endGraphX = Math.min(1, currentScaleX.invert(width));
98+
99+
velocityPath.datum(createCurvePathData(startGraphX, endGraphX, true));
100+
(t ? velocityPath.transition(t) : velocityPath).attr('d', d3.line()
101+
.x(d => originalScaleX(d.x))
102+
.y(d => originalScaleY(d.y))
103+
.curve(curve));
104+
}
105+
84106
const updateHandles = () => {
85107
handles.remove();
86108
handles = createHandles(getCurrentCurve(), g, currentScaleX, currentScaleY);
@@ -90,33 +112,43 @@ const updateHandleVisibility = () => {
90112
$('.anchor, .handle, .handle-line').css('visibility', config.showHandle ? 'visible' : 'hidden');
91113
}
92114

115+
const updateVelocityGraphVisibility = () => {
116+
velocityPath.style('visibility', config.showVelocityGraph ? 'visible' : 'hidden');
117+
updateVelocityPath();
118+
}
119+
93120
window.addEventListener('message', function(event) {
94121
switch (event.data.command) {
95122
case 'changeId':
96123
updateCurvePath();
124+
updateVelocityPath();
97125
fit(0);
98126
updateHandles();
99127
break;
100128

101129
case 'updateCurvePath':
102130
updateCurvePath();
131+
updateVelocityPath();
103132
break;
104133

105134
case 'updateHandles':
106135
updateHandles();
107136
updateCurvePath();
137+
updateVelocityPath();
108138
break;
109139

110140
case 'updateHandlePos':
111141
if (handles instanceof NormalHandles && handles.segmentHandlesArray.length > 1) {
112142
updateHandles();
113143
updateCurvePath();
144+
updateVelocityPath();
114145
}
115146
else {
116147
const duration = config.enableAnimation ? 180 : 0;
117148
const t = d3.transition().duration(duration).ease(d3.easeCubicOut);
118149
handles.updateHandles(t);
119150
updateCurvePath(t);
151+
updateVelocityPath(t);
120152
}
121153
break;
122154

@@ -129,11 +161,16 @@ window.addEventListener('message', function(event) {
129161
updateHandleVisibility();
130162
break;
131163

164+
case 'updateVelocityGraphVisibility':
165+
updateVelocityGraphVisibility();
166+
break;
167+
132168
case 'applyPreferences':
133169
image.load(config.setBackgroundImage ? config.backgroundImagePath : '');
134-
path.attr('stroke', config.curveColor)
170+
curvePath.attr('stroke', config.curveColor)
135171
.attr('stroke-width', config.curveThickness);
136172
updateCurvePath();
173+
updateVelocityPath();
137174
break;
138175
}
139176
});
@@ -158,6 +195,7 @@ const svg = d3.select('#canvas')
158195
if (handles instanceof NormalHandles && x >= 0 && x <= 1) {
159196
handles.curve.addCurve(x, y, currentScaleX(1) - currentScaleX(0));
160197
updateCurvePath();
198+
updateVelocityPath();
161199
updateHandles();
162200
}
163201
})
@@ -233,8 +271,17 @@ const line = d3.line()
233271
.y(d => originalScaleY(d.y))
234272
.curve(curve);
235273

274+
const velocityPath = zoomContainer.append('path')
275+
.datum(createCurvePathData(0, 1, true))
276+
.attr('fill', 'none')
277+
.attr('class', 'velocity-path')
278+
.attr('stroke-width', config.curveThickness)
279+
.attr('d', line);
280+
281+
updateVelocityGraphVisibility();
282+
236283
// カーブ
237-
const path = zoomContainer.append('path')
284+
const curvePath = zoomContainer.append('path')
238285
.datum(createCurvePathData(0, 1))
239286
.attr('fill', 'none')
240287
.attr('stroke', config.curveColor)
@@ -319,14 +366,8 @@ const zoom = d3.zoom()
319366
const duration = config.enableAnimation ? 180 : 0;
320367
const t = d3.transition().duration(duration).ease(d3.easeCubicOut);
321368

322-
const startGraphX = Math.max(0, currentScaleX.invert(-200));
323-
const endGraphX = Math.min(1, currentScaleX.invert(width + 200));
324-
325-
path.datum(createCurvePathData(startGraphX, endGraphX));
326-
path.attr('d', d3.line()
327-
.x(d => originalScaleX(d.x))
328-
.y(d => originalScaleY(d.y))
329-
.curve(curve));
369+
updateCurvePath(null, true);
370+
updateVelocityPath();
330371

331372
if (event.sourceEvent && event.sourceEvent.type === 'wheel') {
332373
gridX.transition(t).call(axisX.scale(currentScaleX));
@@ -337,7 +378,9 @@ const zoom = d3.zoom()
337378
gLabelY.transition(t).call(axisLabelY(currentScaleY));
338379
zoomContainer.transition(t)
339380
.attr('transform', event.transform);
340-
path.transition(t)
381+
curvePath.transition(t)
382+
.attr('stroke-width', config.curveThickness / event.transform.k);
383+
velocityPath.transition(t)
341384
.attr('stroke-width', config.curveThickness / event.transform.k);
342385
leftRect.transition(t)
343386
.attr('width', Math.max(0, currentScaleX(0)));
@@ -384,7 +427,9 @@ const fit = (customDuration = 700) => {
384427
const t = d3.transition().duration(duration);
385428
svg.transition(t)
386429
.call(zoom.transform, d3.zoomIdentity);
387-
path.transition(t)
430+
curvePath.transition(t)
431+
.attr('stroke-width', config.curveThickness);
432+
velocityPath.transition(t)
388433
.attr('stroke-width', config.curveThickness);
389434
}
390435

@@ -431,7 +476,7 @@ $(window).on('keydown', event => {
431476
command: 'goForwardId'
432477
}, '*');
433478
break;
434-
}
479+
}
435480
});
436481

437482
$(window).on('resize', () => {
@@ -471,7 +516,11 @@ $(window).on('resize', () => {
471516
.attr('height', height);
472517
handles.rescaleX(currentScaleX);
473518
handles.rescaleY(currentScaleY);
474-
path.attr('d', d3.line()
519+
curvePath.attr('d', d3.line()
520+
.x(d => originalScaleX(d.x))
521+
.y(d => originalScaleY(d.y))
522+
.curve(curve));
523+
velocityPath.attr('d', d3.line()
475524
.x(d => originalScaleX(d.x))
476525
.y(d => originalScaleY(d.y))
477526
.curve(curve));

0 commit comments

Comments
 (0)