abcjs / examples /dragging.html
KEXEL's picture
Upload 337 files
af6912c verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="examples-styles.css"/>
<title>abcjs: Drag And Drop Demo</title>
<script src="../dist/abcjs-basic.js" type="text/javascript"></script>
<script type="text/javascript">
var renderAbc
function sanitize(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function formatAbc(start, end) {
var abc;
if (start < 0 || end < 0)
abc = sanitize(abcString);
else {
abc = sanitize(abcString.substring(0, start)) +
'<span class="select">' +
sanitize(abcString.substring(start, end)) +
'</span>' +
sanitize(abcString.substring(end));
}
var el = document.getElementById("source");
el.innerHTML = abc.replace(/\n/g,"<br>");
}
function draw() {
var allowDragging = document.getElementById("allowDragging").checked;
var selectAll = document.getElementById("selectAll").checked;
var options = {
add_classes: true,
selectionColor: "green",
dragColor: "blue",
clickListener: clickListener,
dragging: allowDragging,
selectTypes: selectAll ? true : [ 'note', 'bar' ]
};
var start = Date.now();
renderAbc = ABCJS.renderAbc("paper", abcString, options);
var len = Date.now() - start;
var svg = document.getElementById("paper");
var size = svg.innerHTML;
var el = document.getElementById("size");
el.innerText = Math.round(size.length / 1000);
el = document.getElementById("time");
el.innerText = len;
svg.addEventListener('mouseover', hoverListener)
}
var allPitches = [
'C,,,,', 'D,,,,', 'E,,,,', 'F,,,,', 'G,,,,', 'A,,,,', 'B,,,,',
'C,,,', 'D,,,', 'E,,,', 'F,,,', 'G,,,', 'A,,,', 'B,,,',
'C,,', 'D,,', 'E,,', 'F,,', 'G,,', 'A,,', 'B,,',
'C,', 'D,', 'E,', 'F,', 'G,', 'A,', 'B,',
'C', 'D', 'E', 'F', 'G', 'A', 'B',
'c', 'd', 'e', 'f', 'g', 'a', 'b',
"c'", "d'", "e'", "f'", "g'", "a'", "b'",
"c''", "d''", "e''", "f''", "g''", "a''", "b''",
"c'''", "d'''", "e'''", "f'''", "g'''", "a'''", "b'''",
"c''''", "d''''", "e''''", "f''''", "g''''", "a''''", "b''''"
];
function moveNote(note, step) {
var x =allPitches.indexOf(note);
if (x >= 0)
return allPitches[x-step];
return note;
}
function tokenize(str) {
var arr = str.split(/(!.+?!|".+?")/);
var output = [];
for (var i = 0; i < arr.length; i++) {
var token = arr[i];
if (token.length > 0) {
if (token[0] !== '"' && token[0] !== '!') {
var arr2 = arr[i].split(/([A-Ga-g][,']*)/);
output = output.concat(arr2);
} else
output.push(token);
}
}
return output;
}
var selectionCallback;
var currentIndex = -1;
var maxIndex = -1;
function selectPrevious() {
if (selectionCallback && currentIndex > 0)
selectionCallback(currentIndex-1);
}
function selectNext() {
if (selectionCallback && currentIndex < maxIndex)
selectionCallback(currentIndex+1);
}
function hoverListener(event) {
var ret = renderAbc[0].findSelectableElement(event.relatedTarget)
if (ret)
console.log(ret)
}
function clickListener(abcelem, tuneNumber, classes, analysis, drag, mouseEvent) {
if (drag) {
selectionCallback = drag.setSelection;
currentIndex = drag.index;
maxIndex = drag.max;
}
var originalText = abcString.substring(abcelem.startChar, abcelem.endChar);
if (abcelem.pitches && drag && drag.step && abcelem.startChar >= 0 && abcelem.endChar >= 0) {
var arr = tokenize(originalText);
// arr now contains elements that are either a chord, a decoration, a note name, or anything else. It can be put back to its original string with .join("").
for (var i = 0; i < arr.length; i++) {
arr[i] = moveNote(arr[i], drag.step);
}
var newText = arr.join("");
abcString = abcString.substring(0, abcelem.startChar) + newText + abcString.substring(abcelem.endChar);
formatAbc(abcelem.startChar, abcelem.endChar);
draw();
} else if (abcelem.startChar >= 0 && abcelem.endChar >= 0)
formatAbc(abcelem.startChar, abcelem.endChar);
var data = "";
if (abcelem.startChar >= 0)
data += "src: " + originalText + "<br>";
else
data += "src: unknown<br>";
data += "type: " + abcelem.type + "<br>";
data += "el_type: " + abcelem.el_type + "<br>";
data += "name: " + analysis.name + "<br>";
data += "clickedName: " + analysis.clickedName + "<br>";
data += "clickedClasses: " + analysis.clickedClasses + "<br>";
data += "classes: " + analysis.parentClasses + "<br>";
document.getElementById("click-data").innerHTML = data;
}
function optionChanged() {
formatAbc(-1,-1);
draw();
}
function load() {
formatAbc(-1,-1);
draw();
}
var abcString =
'X:1' + '\n' +
'M:4/4' + '\n' +
'L:1/16' + '\n' +
'%%partsfont box' + '\n' +
'%%stretchlast .7' + '\n' +
'%%barnumbers 1' + '\n' +
'T: Selection And Dragging Test' + '\n' +
'T: Demonstrates a lot the different types of elements and their effect.' + '\n' +
'C: Public Domain' + '\n' +
'R: Play steady' + '\n' +
'A: Paul Rosen' + '\n' +
'S: abcjs website' + '\n' +
'W: Now is the time for all good men' + '\n' +
'W:' + '\n' +
'W: To come to the aid of their party.' + '\n' +
'H: This shows every type of thing that can possibly be drawn.' + '\n' +
'H:' + '\n' +
'H: And two lines of history.' + '\n' +
'Q: "Easy Swing" 1/4=140' + '\n' +
'P: AABB' + '\n' +
'%%staves {(RH extra) (LH)}' + '\n' +
'V:RH clef=treble name=RH' + '\n' +
'V:LH clef=bass name=LH' + '\n' +
'K:Bb' + '\n' +
'P:A' + '\n' +
'[V: RH] !mp![b8B8d8] f3g f4|!<(![d12b12] !<)![b4g4]| \\' + '\n' +
'[Q:"left" 1/4=170"right"]z4 !<(! (bfdf) (3B2d2c2 !<)!B4|!f![c4f4] z4 [b8d8]|' + '\n' +
'!p![G8e8] Tu[c8f8]|!<(![d12f12] !<)!g4|!f!a4 [g4b4] z4 =e4|[A8c8f8] d8|' + '\n' +
'|1 [c8F8] [B4G4] z4|[d12B12] A4|!>(![D8A8] Bcde fAB!>)!c|!mp!d16:|' + '\n' +
'w:Strang- ers in the night' + '\n' +
'[V: extra] B,4- B,4- B,4 B,4 | "Bb"{C}B,4 {CD}B,4 B,4 B,4 | B,4 B,4 B,4 B,4 | B,4 B,4 B,4 B,4 |' + '\n' +
'B,4 B,4 B,4 B,4 | B,4 B,4 B,4 B,4 | B,4 B,4 B,4 B,4 | B,4 B,4 B,4 B,4 |' + '\n' +
'B,4 B,4 B,4 B,4 |B,4 B,4 B,4 B,4 |"^annotation"B,4 B,4 B,4 B,4 |B,4 B,4 B,4 B,4 :|' + '\n' +
'[V: LH] B,6 D2 [F,8F8A,8]|B,2B,,2 C,4 D,4 E,F,G,2|F,2A,2 D4 D4 G,2E,2|[C4F,4A,4] z4 [F8B,8]|' + '\n' +
'G,8 A,8|A,12 B,G,D,E,|F,G,A,F, (G,A,B,G,) C4 C4|[C,8A,8] [F8F,8B,8]|' + '\n' +
'A,3C B,3D G,F,E,D, F,2A,2|D,2C,2 B,,2A,,2 G,,4 F,,A,,C,F,|F,,6 D,,2 [D,4G,,4] z4|B,,16:|' + '\n';
</script>
<style>
.side-by-side {
display: flex;
}
.row {
display: flex;
flex-wrap: wrap;
}
#source {
font-size: 13px;
max-width: 700px;
overflow: auto;
font-family: "Lucida Console", Monaco, monospace;
white-space: nowrap;
}
.select {
background-color: #FCF9BB;
box-shadow: 0 0 1px black;
}
ul {
max-width: 700px;
list-style: none;
margin: 0;
padding: 0;
}
li {
margin-top: 10px;
}
label {
font-weight: bold;
}
.click-data {
background: #dddddd;
padding: 10px;
margin-left: 10px;
width: 200px;
}
.click-data h2 {
margin: 0;
padding: 0;
font-weight: normal;
}
</style>
</head>
<body onload="load()">
<header>
<img src="https://paulrosen.github.io/abcjs/img/abcjs_comp_extended_08.svg" alt="abcjs logo">
<h1>Drag and drop demo</h1>
</header>
<div class="container">
<div class="side-by-side">
<div>
<div>Render Time: <span id="time"></span>ms</div>
<div>SVG size: <span id="size"></span>K</div>
<ul>
<li><label><input type="checkbox" id="allowDragging" onclick="optionChanged()" checked>Allow Dragging</label>
<div>When checked, then text is not selectable on the music and notes are draggable. You can
also navigate through the music with the tab key, and change notes with the up and down arrows. When not checked, then items are selectable, but not draggable.
</div>
</li>
<li><label><input type="checkbox" id="selectAll" onclick="optionChanged()">Select All</label>
<div>When this is checked, nearly every visible thing is selectable. When it is not checked, then only
the notes, rests, and measures are selectable.
</div>
</li>
<li><button onclick="selectPrevious()">Previous</button><button onclick="selectNext()">Next</button></li>
</ul>
</div>
<div class="click-data">
<h2>Last Click</h2>
<div id="click-data">
</div>
</div>
</div>
<div class="row">
<div>
<h2>Output</h2>
<div id="paper"></div>
</div>
<div>
<h2>Source</h2>
<div id="source"></div>
</div>
</div>
</div>
</body>
</html>