astro-abcjs 1.0.0 → 1.1.0
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.
- package/README.md +45 -5
- package/package.json +1 -1
- package/src/components/AbcjsPlayer.astro +63 -48
package/README.md
CHANGED
|
@@ -1,11 +1,51 @@
|
|
|
1
|
+
|
|
1
2
|
# astro-abcjs
|
|
2
3
|
|
|
3
4
|
An abcjs component for Astro projects.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
+
## Usage
|
|
7
|
+
|
|
8
|
+
### In .astro files
|
|
9
|
+
|
|
10
|
+
Import the component and use it in your Astro page or component:
|
|
11
|
+
|
|
12
|
+
```astro
|
|
13
|
+
---
|
|
14
|
+
import AbcjsPlayer from 'astro-abcjs/AbcjsPlayer.astro';
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<AbcjsPlayer
|
|
18
|
+
notation={`X:1\nT:Scale\nM:4/4\nK:C\nC D E F | G A B c |`}
|
|
19
|
+
showControls={true}
|
|
20
|
+
responsive={true}
|
|
21
|
+
abcjsVersion="6.6.0"
|
|
22
|
+
/>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### In MDX files
|
|
6
26
|
|
|
7
|
-
|
|
27
|
+
First, make sure your project supports MDX and components in MDX.
|
|
28
|
+
|
|
29
|
+
Import the component at the top of your MDX file:
|
|
30
|
+
|
|
31
|
+
```mdx
|
|
32
|
+
import AbcjsPlayer from 'astro-abcjs/AbcjsPlayer.astro';
|
|
33
|
+
|
|
34
|
+
<AbcjsPlayer
|
|
35
|
+
notation={`X:1\nT:Scale\nM:4/4\nK:C\nC D E F | G A B c |`}
|
|
36
|
+
showControls={true}
|
|
37
|
+
responsive={true}
|
|
38
|
+
abcjsVersion="6.6.0"
|
|
39
|
+
/>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
#### Props
|
|
43
|
+
|
|
44
|
+
- `notation` (string, required): The ABC notation string to render.
|
|
45
|
+
- `showControls` (boolean, default: true): Show audio playback controls.
|
|
46
|
+
- `responsive` (boolean, default: true): Make the notation responsive to container size.
|
|
47
|
+
- `abcjsVersion` (string, optional, default: "6.6.0"): The abcjs version to load from CDN. Override to pin or upgrade/downgrade.
|
|
48
|
+
|
|
49
|
+
## Credits & Inspiration
|
|
8
50
|
|
|
9
|
-
|
|
10
|
-
by [Pavlin Gunov](https://www.pavlinbg.com/)
|
|
11
|
-
<https://www.pavlinbg.com/posts/building-a-reusable-music-component-in-astro-using-abcjs>
|
|
51
|
+
This component was inspired by the article [Building a Reusable Music Component in Astro using ABCjs](https://www.pavlinbg.com/posts/building-a-reusable-music-component-in-astro-using-abcjs) by [Pavlin Gunov](https://www.pavlinbg.com/).
|
package/package.json
CHANGED
|
@@ -7,9 +7,15 @@ interface Props {
|
|
|
7
7
|
notation: string;
|
|
8
8
|
showControls?: boolean;
|
|
9
9
|
responsive?: boolean;
|
|
10
|
+
abcjsVersion?: string;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
const {
|
|
13
|
+
const {
|
|
14
|
+
notation,
|
|
15
|
+
showControls = true,
|
|
16
|
+
responsive = true,
|
|
17
|
+
abcjsVersion = "6.6.0",
|
|
18
|
+
} = Astro.props;
|
|
13
19
|
---
|
|
14
20
|
|
|
15
21
|
<div
|
|
@@ -17,58 +23,67 @@ const { notation, showControls = true, responsive = true } = Astro.props;
|
|
|
17
23
|
data-notation={notation}
|
|
18
24
|
data-responsive={responsive}
|
|
19
25
|
>
|
|
20
|
-
<div
|
|
21
|
-
{showControls && <div
|
|
26
|
+
<div class="abcjs-paper"></div>
|
|
27
|
+
{showControls && <div class="abcjs-audio" />}
|
|
22
28
|
</div>
|
|
23
29
|
|
|
24
|
-
<script>
|
|
30
|
+
<script define:vars={{ abcjsVersion }}>
|
|
25
31
|
if (typeof window !== "undefined") {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
// Load abcjs browser build from CDN if not already loaded
|
|
33
|
+
if (!window.ABCJS) {
|
|
34
|
+
const script = document.createElement("script");
|
|
35
|
+
script.src = `https://cdn.jsdelivr.net/npm/abcjs@${abcjsVersion}/dist/abcjs-basic.js`;
|
|
36
|
+
script.onload = initializeAbcjs;
|
|
37
|
+
document.head.appendChild(script);
|
|
38
|
+
} else {
|
|
39
|
+
initializeAbcjs();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function initializeAbcjs() {
|
|
43
|
+
const abcjs = window.ABCJS;
|
|
44
|
+
if (!abcjs) return;
|
|
45
|
+
const containers = document.querySelectorAll(".abcjs-container");
|
|
46
|
+
containers.forEach((container) => {
|
|
47
|
+
if (container.dataset.abcjsInitialized === "true") return;
|
|
48
|
+
const notation = container.getAttribute("data-notation");
|
|
49
|
+
if (!notation) return;
|
|
50
|
+
const isResponsive =
|
|
51
|
+
container.getAttribute("data-responsive") === "true";
|
|
52
|
+
const paperDiv = container.querySelector(".abcjs-paper");
|
|
53
|
+
const audioDiv = container.querySelector(".abcjs-audio");
|
|
54
|
+
// Render music notation
|
|
55
|
+
const visualObj = abcjs.renderAbc(paperDiv, notation, {
|
|
56
|
+
responsive: isResponsive ? "resize" : undefined,
|
|
57
|
+
add_classes: true,
|
|
58
|
+
paddingleft: 0,
|
|
59
|
+
paddingright: 0,
|
|
60
|
+
paddingbottom: 10,
|
|
61
|
+
paddingtop: 10,
|
|
62
|
+
});
|
|
63
|
+
// Audio playback controls
|
|
64
|
+
if (audioDiv && abcjs.synth) {
|
|
65
|
+
const synthControl = new abcjs.synth.SynthController();
|
|
66
|
+
synthControl.load(audioDiv, null, {
|
|
67
|
+
displayLoop: true,
|
|
68
|
+
displayRestart: true,
|
|
69
|
+
displayPlay: true,
|
|
70
|
+
displayProgress: true,
|
|
71
|
+
displayWarp: true,
|
|
45
72
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
displayWarp: true,
|
|
73
|
+
const createSynth = new abcjs.synth.CreateSynth();
|
|
74
|
+
createSynth
|
|
75
|
+
.init({ visualObj: visualObj[0] })
|
|
76
|
+
.then(() => {
|
|
77
|
+
synthControl.setTune(visualObj[0], false);
|
|
78
|
+
})
|
|
79
|
+
.catch((error) => {
|
|
80
|
+
console.warn("Audio synthesis initialization failed:", error);
|
|
55
81
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
})
|
|
62
|
-
.catch((error) => {
|
|
63
|
-
console.warn("Audio synthesis initialization failed:", error);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
container.dataset.abcjsInitialized = "true";
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
initializeAbcjs();
|
|
70
|
-
document.addEventListener("astro:page-load", initializeAbcjs);
|
|
71
|
-
});
|
|
82
|
+
}
|
|
83
|
+
container.dataset.abcjsInitialized = "true";
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
document.addEventListener("astro:page-load", initializeAbcjs);
|
|
72
87
|
}
|
|
73
88
|
</script>
|
|
74
89
|
|