Skip to content

Instantly share code, notes, and snippets.

@BerezkovN
Last active January 9, 2024 17:31
Show Gist options
  • Save BerezkovN/1b955093c4f480e5e1cd4fa8caeea877 to your computer and use it in GitHub Desktop.
Save BerezkovN/1b955093c4f480e5e1cd4fa8caeea877 to your computer and use it in GitHub Desktop.
Anki hanzi stroke order
<!-- Paste the following code into your flashcard template -->
<!-- The code will automatically generate stroke animations for the field {{Hanzi}} -->
<!-- Make sure to change this field to whatever you use!! -->
<div id="hanzi-container" class="scrolling-wrapper-flexbox">
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/hanzi-writer.min.js"></script>
<script>
async function getCharacterStrokeCount(hanziChar) {
let unsupportedChar = false
const charData = await HanziWriter.loadCharacterData(hanziChar).catch((error) => {
unsupportedChar = true
});
if (unsupportedChar) {
return -1
}
else {
return charData.strokes.length;
}
}
function createElementFromHTML(htmlString) {
var div = document.createElement('div');
div.innerHTML = htmlString.trim();
// Change this to div.childNodes to support multiple top-level nodes.
return div.firstChild;
}
async function main() {
container = document.getElementById("hanzi-container");
hanzi = "{{Hanzi}}"
strokeCounterArray = [];
for (let ind = 0; ind < hanzi.length; ind++) {
const strokeCount = await getCharacterStrokeCount(hanzi[ind])
if (strokeCount == -1) {
const padding = document.createElement("div")
padding.style.padding = "0px 3px";
container.appendChild(padding)
continue
}
strokeCounterArray.push(0)
const hanziDivID = "hanzi-" + ind
const hanziDiv = document.createElement("div")
container.appendChild(hanziDiv)
const svgElement = createElementFromHTML(
`
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" id="${hanziDivID}">
<line x1="0" y1="0" x2="100" y2="0" stroke="#DDD" />
<line x1="0" y1="0" x2="0" y2="100" stroke="#DDD" />
<line x1="0" y1="100" x2="100" y2="100" stroke="#DDD" />
<line x1="100" y1="0" x2="100" y2="100" stroke="#DDD" />
<line x1="0" y1="0" x2="100" y2="100" stroke="#DDD" />
<line x1="100" y1="0" x2="0" y2="100" stroke="#DDD" />
<line x1="50" y1="0" x2="50" y2="100" stroke="#DDD" />
<line x1="0" y1="50" x2="100" y2="50" stroke="#DDD" />
</svg>
`
)
hanziDiv.appendChild(svgElement)
const writer = HanziWriter.create(hanziDivID, hanzi[ind], {
width: 100,
height: 100,
showCharacter: false,
strokeAnimationSpeed: 4,
padding: 5
});
const strokeCounterInd = ind;
const leftButton = document.createElement("button");
leftButton.textContent = "下一笔"
leftButton.addEventListener('click', function() {
if (strokeCounterArray[strokeCounterInd] > strokeCount) {
writer.hideCharacter()
strokeCounterArray[strokeCounterInd] = 0
}
else {
writer.animateStroke(strokeCounterArray[strokeCounterInd])
strokeCounterArray[strokeCounterInd]++
}
});
hanziDiv.appendChild(document.createElement("br"))
hanziDiv.appendChild(leftButton)
}
}
main()
</script>
<style>
.scrolling-wrapper-flexbox {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
.card {
flex: 0 0 auto;
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment