您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Replaces kanji in wanikani with hanzi writer. Licenses for kanji data are found at https://github.com/chanind/hanzi-writer-data-jp/
当前为
// ==UserScript== // @name Wanikani hanzi-writer addition // @namespace https://declanfodor.com // @description Replaces kanji in wanikani with hanzi writer. Licenses for kanji data are found at https://github.com/chanind/hanzi-writer-data-jp/ // @match https://www.wanikani.com/* // @version 0.0.2 // @author Declan Fodor // @resource kanjiJSON https://raw.githubusercontent.com/chanind/hanzi-writer-data-jp/master/data/all.json // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/hanzi-writer.js // @require https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2 // @license MIT // @grant GM_addStyle // @grant GM_getResourceText // ==/UserScript== (function () { 'use strict'; const WK_PAGE = Object.freeze({ REVIEW: Symbol("review_page"), LESSON: Symbol("lesson_page"), DASHBOARD: Symbol("dashboard_page"), LOADING: Symbol("other_page") // Or a page we haven't implemented behavior for yet }); class PageStatus { constructor(previousStatus) { this.page = this.whichPage(unsafeWindow.location.href); this.switched = previousStatus ? previousStatus.page !== this.page : true; } whichPage(url) { switch (url) { case "https://www.wanikani.com/": return WK_PAGE.DASHBOARD; case "https://www.wanikani.com/subjects/review": return WK_PAGE.REVIEW; default: return WK_PAGE.LOADING; } } } class PageObserver { constructor(wk_page, onPage, offPage) { this.status = new PageStatus(null); this.observer = new MutationObserver(() => { if (this.status.switched && this.status.page === wk_page) { onPage(); } else if (this.status.switched) { offPage(); } this.status = new PageStatus(this.status); }); this.observer.observe(document, { childList: true, subtree: true }); } } let hanziWriterSettings = { drawingColor: '#000000', drawingWidth: 20, strokeColor: '#ff9900', quiz: true }; let kanjiJSON = JSON.parse(GM_getResourceText("kanjiJSON")); class ReviewPage { constructor() { this.kanjiElem = null; this.kanji = null; this.writer = null; this.containerdiv = null; } /** * Called whenever the kanji has switched. It creates the hanzi writer instance */ drawHanziWriter() { if (!this.writer) { let characterheader = document.querySelector(".quiz .character-header"); this.containerdiv = document.createElement("div"); this.containerdiv.id = "wkhwa-container-div"; GM_addStyle(`#wkhwa-container-div { position: relative; top: -32px; display: flex; align-items: center; justify-content: center; }`); this.writer = HanziWriter.create(this.containerdiv, this.kanji, { width: 200, height: 200, showCharacter: false, showHintAfterMisses: 3, padding: 5, drawingWidth: hanziWriterSettings.drawingWidth, strokeColor: hanziWriterSettings.strokeColor, drawingColor: hanziWriterSettings.drawingColor, charDataLoader: (char, onLoad) => { onLoad(kanjiJSON[char]); } }); characterheader.append(this.containerdiv); { this.writer.quiz(); } } else { this.writer.setCharacter(this.kanji); } } onReviewPage() { this.observer = new MutationObserver(() => { if (this.refreshKanjiState()) { this.drawHanziWriter(); } }); this.kanjiElem = document.querySelector(".quiz .character-header .character-header__characters"); if (this.refreshKanjiState()) { this.drawHanziWriter(); } this.observer.observe(this.kanjiElem, { childList: true, subtree: true }); } showHanziWriter() { this.kanjiElem.hidden = true; if (this.containerdiv) { this.containerdiv.hidden = false; } } hideHanziWriter() { this.kanjiElem.hidden = false; if (this.containerdiv) { this.containerdiv.hidden = true; } } /** * Returns true if the kanji shown has switched. Returns false otherwise * This function also manages hiding and showing kanji * in the event that the characters shown are either a radical or vocabulary */ refreshKanjiState() { if (document.querySelector(".quiz-input__question-category").innerText.toLowerCase() === "kanji") { if (this.kanjiElem.innerText !== this.kanji) { // We have switched to a new kanji, mayhap away from vocabulary, so we need to set these to be shown this.showHanziWriter(); this.kanji = this.kanjiElem.innerText; return true; } else { return false; } } // The character content has switched to vocabulary or a radical this.hideHanziWriter(); return false; } /** * Cleans up various objects if we switch away from them. */ offReviewPage() { this.kanji = null; this.writer = null; this.containerdiv = null; if (this.observer) { this.observer.disconnect(); } } } let reviewpage = new ReviewPage(); new PageObserver(WK_PAGE.REVIEW, reviewpage.onReviewPage.bind(reviewpage), reviewpage.offReviewPage.bind(reviewpage)); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址