I've dynamically created a fretboard with 6 strings. Each are given a height of 8px using the class of .string:before. How do I give each string a height value taken from the stringGauge array so that as they are created, the strings increase in thickness(height)?
The height needed to be assigned using a pseudo class so I am unable to solve this through the use of inline styling as far as I know.
const root = document.documentElement;
const fretboard = document.querySelector(".fretboard");
// The stringGauge array below contains the values I want to assign to each new string
const stringGauge = [1, 2, 3, 6, 7, 8];
const instrumentTuningPresets = {
Guitar: [4, 11, 7, 2, 9, 4],
};
let selectedInstrument = "Guitar";
let numberOfStrings = instrumentTuningPresets[selectedInstrument].length;
const app = {
init() {
this.setupFretboard();
},
setupFretboard() {
fretboard.innerHTML = "";
// This creates the strings for the fretboard
for (let i = 0; i < numberOfStrings; i ) {
let string = tools.createElement("div");
string.classList.add("string");
fretboard.appendChild(string);
// This loops throught the stringGauge array but only manages to assign the
//last value in the array which is 8. Subtracting 1-5 from i (e.g. stringGauge[i-3])
// does change the height but for all of them.
root.style.setProperty("--string-height", stringGauge[i]);
}
},
};
const tools = {
createElement(el, content) {
el = document.createElement(el);
if (arguments.length > 1) {
el.innerHTML = content;
}
return el;
},
};
app.init();
:root {
--fretboard-height: 300;
--string-height: 8;
}
.fretboard {
display: flex;
flex-direction: column;
background-image: url(../assets/images/maple.jpg);
width: 100%;
min-width: 1500px;
height: calc(var(--fretboard-height) * 1px);
margin-top: 50px;
}
.string {
display: flex;
position: relative;
width: 100%;
height: 100%;
}
.string:before {
content: "";
width: 100%;
height: calc(var(--string-height) * 1px);
background: linear-gradient(#eee, #999);
box-shadow: 76px 3px 10px #806233;
z-index: 1;
position: absolute;
top: calc(var(--string-top-position) * 1px);
}
<div ></div>
CodePudding user response:
The most rudimentary way, without changing much of your existing code, would just be to give the css variables you create a name based off the i
index, and then use the nth-child selector to target each string. I'm doing i 1
for easier reading because nth-child
starts at 1, not 0.
root.style.setProperty(`--string-height-${i 1}`, stringGauge[i]);
.string:nth-child(1):before {
height: calc(var(--string-height-1) * 1px);
}
You could make the nth-child
logic a bit terser by using a Sass loop.
Here's a snippet showing the simple way to get you started.
const root = document.documentElement;
const fretboard = document.querySelector(".fretboard");
// The stringGauge array below contains the values I want to assign to each new string
const stringGauge = [1, 2, 3, 6, 7, 8];
const instrumentTuningPresets = {
Guitar: [4, 11, 7, 2, 9, 4],
};
let selectedInstrument = "Guitar";
let numberOfStrings = instrumentTuningPresets[selectedInstrument].length;
const app = {
init() {
this.setupFretboard();
},
setupFretboard() {
fretboard.innerHTML = "";
// This creates the strings for the fretboard
for (let i = 0; i < numberOfStrings; i ) {
let string = tools.createElement("div");
string.classList.add("string");
fretboard.appendChild(string);
// This loops throught the stringGauge array but only manages to assign the
//last value in the array which is 8. Subtracting 1-5 from i (e.g. stringGauge[i-3])
// does change the height but for all of them.
root.style.setProperty(`--string-height-${i 1}`, stringGauge[i]);
}
},
};
const tools = {
createElement(el, content) {
el = document.createElement(el);
if (arguments.length > 1) {
el.innerHTML = content;
}
return el;
},
};
app.init();
:root {
--fretboard-height: 300;
}
.fretboard {
display: flex;
flex-direction: column;
background-image: url(../assets/images/maple.jpg);
width: 100%;
min-width: 1500px;
height: calc(var(--fretboard-height) * 1px);
margin-top: 50px;
}
.string {
display: flex;
position: relative;
width: 100%;
height: 100%;
}
.string:before {
content: "";
width: 100%;
background: linear-gradient(#eee, #999);
box-shadow: 76px 3px 10px #806233;
z-index: 1;
position: absolute;
top: calc(var(--string-top-position) * 1px);
}
.string:nth-child(1):before {
height: calc(var(--string-height-1) * 1px);
}
.string:nth-child(2):before {
height: calc(var(--string-height-2) * 1px);
}
.string:nth-child(3):before {
height: calc(var(--string-height-3) * 1px);
}
.string:nth-child(4):before {
height: calc(var(--string-height-4) * 1px);
}
.string:nth-child(5):before {
height: calc(var(--string-height-5) * 1px);
}
.string:nth-child(6):before {
height: calc(var(--string-height-6) * 1px);
}
<div ></div>