⬅ ギャラリーに戻る
✏️ '
eigo2.html
' を修正中... (終わったら保存を押してね)
📷 素材アップロード
アップロード
🛠️ プログラム作成
[修正モード]
ファイル名:
.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ProVocab - 縦スクロール暗記版</title> <style> :root { --primary: #4a90e2; --secondary: #8e44ad; --bg: #f4f7f6; --card-bg: #ffffff; --text-main: #2c3e50; } body { font-family: 'Helvetica Neue', Arial, sans-serif; background: var(--bg); margin: 0; padding-bottom: 90px; color: var(--text-main); } .container { max-width: 600px; margin: 0 auto; padding: 20px; } /* ナビゲーション */ nav { position: fixed; bottom: 0; width: 100%; background: #fff; display: flex; border-top: 1px solid #ddd; z-index: 1000; padding-bottom: env(safe-area-inset-bottom); } nav button { flex: 1; padding: 12px; border: none; background: none; cursor: pointer; font-weight: bold; color: #999; font-size: 0.75rem; display: flex; flex-direction: column; align-items: center; } nav button span { font-size: 1.2rem; margin-bottom: 3px; } nav button.active { color: var(--primary); background: #f0f7ff; } .mode-section { display: none; animation: fadeIn 0.3s; } .mode-section.active { display: block; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } /* 検索・共通 */ .search-area { position: sticky; top: 0; background: var(--bg); padding: 10px 0; z-index: 100; } .search-box { display: flex; gap: 10px; } input { flex: 1; padding: 15px; border: 2px solid #ddd; border-radius: 12px; font-size: 16px; outline: none; transition: 0.2s; } input:focus { border-color: var(--primary); } .show-all-btn { background: none; border: none; color: var(--primary); text-decoration: underline; cursor: pointer; width: 100%; margin-top: 10px; } /* 共通カードデザイン */ .card { background: var(--card-bg); padding: 20px; border-radius: 16px; box-shadow: 0 4px 15px rgba(0,0,0,0.05); margin-bottom: 15px; position: relative; border-left: 5px solid transparent; } .card.registered { border-left-color: var(--primary); } .header-row { display: flex; justify-content: space-between; align-items: flex-start; } .word-info h3 { font-size: 1.6rem; margin: 0; color: var(--text-main); } .pronounce { font-size: 0.9rem; color: #888; font-weight: normal; font-family: sans-serif; } .emoji-big { font-size: 2.5rem; line-height: 1; } .tag { display: inline-block; background: #eee; padding: 3px 8px; border-radius: 4px; font-size: 0.75rem; margin: 5px 0; color: #555; font-weight: bold; } .meaning-box { margin: 10px 0; font-weight: bold; font-size: 1.1rem; border-left: 3px solid var(--primary); padding-left: 8px; } .etymology-box { background: #f3e5f5; border-radius: 8px; padding: 8px; margin: 10px 0; border-left: 4px solid var(--secondary); font-size: 0.9rem; color: #4a235a; } .example-box { font-style: italic; color: #666; background: #f9f9f9; padding: 10px; border-radius: 8px; font-size: 0.85rem; margin-top: 10px; } .btn { padding: 12px; border: none; border-radius: 8px; cursor: pointer; background: var(--primary); color: white; font-weight: bold; width: 100%; margin-top: 10px; } .btn:disabled { background: #ccc; cursor: default; } .btn-del { background: transparent; color: #e74c3c; border: 1px solid #e74c3c; padding: 4px 10px; font-size: 0.8rem; border-radius: 4px; cursor: pointer; float: right; } /* --- 縦スクロール暗記モード用スタイル --- */ .memo-card-container { perspective: 1000px; margin-bottom: 20px; cursor: pointer; height: 280px; /* カードの高さ */ } .memo-card { width: 100%; height: 100%; position: relative; transition: transform 0.6s; transform-style: preserve-3d; } .memo-card.flipped { transform: rotateY(180deg); } .memo-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; border-radius: 16px; background: white; box-shadow: 0 5px 15px rgba(0,0,0,0.1); padding: 20px; box-sizing: border-box; display: flex; flex-direction: column; } .memo-front { justify-content: center; align-items: center; text-align: center; background: linear-gradient(135deg, #ffffff 0%, #f8fbff 100%); border: 2px solid #eef; } .memo-back { transform: rotateY(180deg); overflow-y: auto; border: 2px solid var(--primary); } .mastery-row { display: flex; gap: 5px; margin-top: auto; padding-top: 10px; border-top: 1px solid #eee; } .m-btn { flex: 1; padding: 8px; border: none; border-radius: 4px; color: white; font-size: 0.8rem; cursor: pointer; } .status-badge { position: absolute; top: 10px; right: 10px; font-size: 1.2rem; } </style> </head> <body> <div class="container"> <section id="search-mode" class="mode-section active"> <div class="search-area"> <h2 style="text-align:center; margin:0 0 10px 0;">🔍 辞書検索</h2> <div class="search-box"> <input type="text" id="searchInput" placeholder="英単語を入力... (例: ab)" oninput="searchDict()"> </div> <button class="show-all-btn" onclick="showAllDict()">全単語リストを表示 (100語収録)</button> </div> <div id="searchResult"></div> </section> <section id="study-mode" class="mode-section"> <h2 style="text-align:center;">📖 My単語帳</h2> <div id="studyList"></div> </section> <section id="memorize-mode" class="mode-section"> <h2 style="text-align:center;">🧠 暗記リスト</h2> <p style="text-align:center; font-size:0.8rem; color:#888;">タップで裏返して答え合わせ</p> <div id="memoList"></div> </section> </div> <nav> <button onclick="changeMode('search-mode')" id="nav-search" class="active"><span>🔍</span>検索</button> <button onclick="changeMode('study-mode')" id="nav-study"><span>📖</span>勉強</button> <button onclick="changeMode('memorize-mode')" id="nav-memorize"><span>🧠</span>記憶</button> </nav> <script> // --- Gemini厳選辞書 (100語) --- // w:単語, p:発音, pos:品詞, m:意味, ety:語源, ex:例文, em:絵文字 const geminiDictionary = [ {w:"abandon",p:"/əˈbæn.dən/",pos:"動",m:"捨てる、断念する",ety:"a(~へ)+ban(布告)→管理下から追放する",ex:"He abandoned his car in the snow.",em:"🚮"}, {w:"abundant",p:"/əˈbʌn.dənt/",pos:"形",m:"豊富な",ety:"ab(離れて)+unda(波)→波があふれ出る",ex:"This river is abundant in fish.",em:"🌾"}, {w:"acquire",p:"/əˈkwaɪɚ/",pos:"動",m:"習得する、獲得する",ety:"ad(~へ)+quaerere(求める)→探し求める",ex:"She acquired new skills.",em:"🎒"}, {w:"adapt",p:"/əˈdæpt/",pos:"動",m:"適応させる",ety:"ad(~へ)+aptare(合わせる)",ex:"We must adapt to change.",em:"🦎"}, {w:"advocate",p:"/ˈæd.və.keɪt/",pos:"動",m:"主張する、支持する",ety:"ad(~へ)+vocare(呼ぶ)→声援を送る",ex:"He advocates human rights.",em:"📢"}, {w:"aesthetic",p:"/esˈθet̬.ɪk/",pos:"形",m:"美的な",ety:"aisthētikos(感覚の)→美を感じる",ex:"The building has aesthetic appeal.",em:"🎨"}, {w:"affection",p:"/əˈfek.ʃən/",pos:"名",m:"愛情",ety:"ad(~へ)+facere(作用する)→心に作用すること",ex:"She has deep affection for him.",em:"🥰"}, {w:"agenda",p:"/əˈdʒen.də/",pos:"名",m:"議題、予定表",ety:"agere(行う)→行われるべきこと",ex:"What's on the agenda today?",em:"📋"}, {w:"aggressive",p:"/əˈɡres.ɪv/",pos:"形",m:"攻撃的な、積極的な",ety:"ad(~へ)+gradi(歩む)→向かっていく",ex:"He is an aggressive salesman.",em:"🐅"}, {w:"ambiguous",p:"/æmˈbɪɡ.ju.əs/",pos:"形",m:"曖昧な",ety:"ambi(両方)+agere(導く)→どちらとも取れる",ex:"The instructions were ambiguous.",em:"🌫️"}, {w:"ambitious",p:"/æmˈbɪʃ.əs/",pos:"形",m:"野心的な",ety:"ambi(周り)+ire(行く)→票を求めて歩き回る",ex:"She is ambitious for success.",em:"🦁"}, {w:"analyze",p:"/ˈæn.əl.aɪz/",pos:"動",m:"分析する",ety:"ana(解いて)+lyein(緩める)→分解する",ex:"We analyzed the data.",em:"📊"}, {w:"anticipate",p:"/ænˈtɪs.ə.peɪt/",pos:"動",m:"予想する",ety:"ante(前に)+capere(取る)→先取りする",ex:"We anticipate a large crowd.",em:"🔮"}, {w:"apparent",p:"/əˈper.ənt/",pos:"形",m:"明らかな、うわべの",ety:"ad(~へ)+parere(現れる)",ex:"It was apparent that she was sad.",em:"👀"}, {w:"appreciate",p:"/əˈpriː.ʃi.eɪt/",pos:"動",m:"感謝する、評価する",ety:"ad(~へ)+pretium(価値)→価値を認める",ex:"I appreciate your help.",em:"🙏"}, {w:"appropriate",p:"/əˈproʊ.pri.ət/",pos:"形",m:"適切な",ety:"ad(~へ)+proprius(自身の)→自分の用途に合わせる",ex:"Is this dress appropriate for the party?",em:"👌"}, {w:"aspect",p:"/ˈæs.pekt/",pos:"名",m:"側面、局面",ety:"ad(~へ)+specere(見る)→見え方",ex:"We considered every aspect.",em:"💎"}, {w:"assemble",p:"/əˈsem.bəl/",pos:"動",m:"集める、組み立てる",ety:"ad(~へ)+simul(一緒に)→一つにする",ex:"They assembled in the hall.",em:"🧩"}, {w:"assess",p:"/əˈses/",pos:"動",m:"評価する、査定する",ety:"ad(~へ)+sedere(座る)→そばに座って判断する",ex:"Assess the damage carefully.",em:"⚖️"}, {w:"assign",p:"/əˈsaɪn/",pos:"動",m:"割り当てる",ety:"ad(~へ)+signare(印す)",ex:"I was assigned a difficult task.",em:"🏷️"}, {w:"assume",p:"/əˈsuːm/",pos:"動",m:"仮定する、引き受ける",ety:"ad(~へ)+sumere(取る)→自分の考えに取り込む",ex:"I assume he is coming.",em:"🤔"}, {w:"authority",p:"/əˈθɔːr.ə.t̬i/",pos:"名",m:"権威、当局",ety:"auctor(創始者)→生み出す力を持つ人",ex:"She is an authority on biology.",em:"👮"}, {w:"banish",p:"/ˈbæn.ɪʃ/",pos:"動",m:"追放する",ety:"ban(布告)→命令で追い出す",ex:"He was banished from the country.",em:"🚪"}, {w:"benefit",p:"/ˈben.ə.fɪt/",pos:"名",m:"利益",ety:"bene(良い)+facere(行う)",ex:"The benefits of exercise are clear.",em:"🎁"}, {w:"bias",p:"/ˈbaɪ.əs/",pos:"名",m:"偏見",ety:"フランス語「斜め」から",ex:"He has a bias against technology.",em:"🕶️"}, {w:"candidate",p:"/ˈkæn.dɪ.dət/",pos:"名",m:"候補者",ety:"candidus(白)→白い服を着た候補者",ex:"She is a candidate for mayor.",em:"🙋"}, {w:"capable",p:"/ˈkeɪ.pə.bəl/",pos:"形",m:"能力がある",ety:"capere(つかむ)+able(できる)",ex:"He is capable of doing it.",em:"💪"}, {w:"collapse",p:"/kəˈlæps/",pos:"動",m:"崩壊する",ety:"col(共に)+labi(落ちる)",ex:"The bridge collapsed.",em:"🏚️"}, {w:"commit",p:"/kəˈmɪt/",pos:"動",m:"委ねる、犯す、約束する",ety:"com(共に)+mittere(送る)",ex:"He committed a crime.",em:"🤝"}, {w:"compensate",p:"/ˈkɑːm.pən.seɪt/",pos:"動",m:"補償する",ety:"com(共に)+pendere(吊るす)→重さを合わせる",ex:"Compensate for the loss.",em:"💰"}, {w:"competent",p:"/ˈkɑːm.pə.t̬ənt/",pos:"形",m:"有能な",ety:"com(適した)+petere(求める)→ふさわしい",ex:"She is a competent manager.",em:"🌟"}, {w:"complex",p:"/ˈkɑːm.pleks/",pos:"形",m:"複雑な",ety:"com(共に)+plectere(編む)→編み合わされた",ex:"It is a complex problem.",em:"🕸️"}, {w:"comply",p:"/kəmˈplaɪ/",pos:"動",m:"従う",ety:"com(完全に)+plere(満たす)",ex:"Please comply with the rules.",em:"🆗"}, {w:"component",p:"/kəmˈpoʊ.nənt/",pos:"名",m:"構成要素",ety:"com(共に)+ponere(置く)",ex:"Key components of the plan.",em:"🔩"}, {w:"concentrate",p:"/ˈkɑːn.sən.treɪt/",pos:"動",m:"集中する",ety:"con(共に)+centrum(中心)",ex:"Concentrate on your work.",em:"🎯"}, {w:"conclude",p:"/kənˈkluːd/",pos:"動",m:"結論づける",ety:"con(完全に)+claudere(閉じる)",ex:"The meeting concluded at 5.",em:"🏁"}, {w:"conflict",p:"/ˈkɑːn.flɪkt/",pos:"名",m:"衝突、対立",ety:"con(共に)+fligere(打つ)",ex:"A conflict between two countries.",em:"⚔️"}, {w:"consequence",p:"/ˈkɑːn.sə.kwens/",pos:"名",m:"結果",ety:"con(共に)+sequi(続く)",ex:"Face the consequences.",em:"📉"}, {w:"consistent",p:"/kənˈsɪs.tənt/",pos:"形",m:"一貫した",ety:"con(共に)+sistere(立つ)→不動の",ex:"He is consistent in his views.",em:"📏"}, {w:"construct",p:"/kənˈstrʌkt/",pos:"動",m:"建設する",ety:"con(共に)+struere(積み上げる)",ex:"Construct a new building.",em:"🏗️"}, {w:"context",p:"/ˈkɑːn.tekst/",pos:"名",m:"文脈、背景",ety:"con(共に)+texere(織る)",ex:"Understand the word in context.",em:"📖"}, {w:"contradict",p:"/ˌkɑːn.trəˈdɪkt/",pos:"動",m:"矛盾する",ety:"contra(反対に)+dicere(言う)",ex:"Don't contradict me.",em:"🙅"}, {w:"contribute",p:"/kənˈtrɪb.juːt/",pos:"動",m:"貢献する、寄付する",ety:"con(共に)+tribuere(与える)",ex:"Contribute to society.",em:"🤲"}, {w:"convince",p:"/kənˈvɪns/",pos:"動",m:"納得させる",ety:"con(完全に)+vincere(征服する)→議論で勝つ",ex:"I convinced him to go.",em:"🗣️"}, {w:"cooperate",p:"/koʊˈɑː.pə.reɪt/",pos:"動",m:"協力する",ety:"co(共に)+operari(働く)",ex:"We need to cooperate.",em:"🤝"}, {w:"crucial",p:"/ˈkruː.ʃəl/",pos:"形",m:"重大な",ety:"crux(十字架)→分かれ道→決定的",ex:"A crucial decision.",em:"⚠️"}, {w:"decade",p:"/ˈdek.eɪd/",pos:"名",m:"10年間",ety:"dekas(10の組)",ex:"Over the past decade.",em:"🗓️"}, {w:"decisive",p:"/dɪˈsaɪ.sɪv/",pos:"形",m:"決定的な",ety:"de(離れて)+caedere(切る)",ex:"A decisive victory.",em:"🔪"}, {w:"decline",p:"/dɪˈklaɪn/",pos:"動",m:"断る、衰退する",ety:"de(離れて)+clinare(傾く)",ex:"Sales declined this month.",em:"📉"}, {w:"define",p:"/dɪˈfaɪn/",pos:"動",m:"定義する",ety:"de(完全に)+finire(終わらせる/境界)",ex:"Define the meaning.",em:"📝"}, {w:"demonstrate",p:"/ˈdem.ən.streɪt/",pos:"動",m:"証明する、実演する",ety:"de(完全に)+monstrare(示す)",ex:"He demonstrated how to use it.",em:"👨🏫"}, {w:"deny",p:"/dɪˈnaɪ/",pos:"動",m:"否定する",ety:"de(完全に)+negare(「No」と言う)",ex:"He denied the rumor.",em:"✖️"}, {w:"depress",p:"/dɪˈpres/",pos:"動",m:"落胆させる",ety:"de(下に)+premere(押す)",ex:"Looking at the news depressed me.",em:"😞"}, {w:"derive",p:"/dɪˈraɪv/",pos:"動",m:"引き出す、由来する",ety:"de(~から)+rivus(川)→水を引き入れる",ex:"Many words derive from Latin.",em:"🏞️"}, {w:"detect",p:"/dɪˈtekt/",pos:"動",m:"探知する",ety:"de(除いて)+tegere(覆い)→覆いを取る",ex:"Detect a virus.",em:"🕵️"}, {w:"determine",p:"/dɪˈtɝː.mɪn/",pos:"動",m:"決定する",ety:"de(完全に)+terminare(境界をつける)",ex:"Determine the cause.",em:"🏁"}, {w:"devote",p:"/dɪˈvoʊt/",pos:"動",m:"捧げる",ety:"de(離れて)+vovere(誓う)",ex:"She devoted her life to science.",em:"🙏"}, {w:"distinct",p:"/dɪˈstɪŋkt/",pos:"形",m:"はっきりした、異なる",ety:"dis(別々に)+stinguere(刺す/印す)",ex:"There is a distinct difference.",em:"🔆"}, {w:"distribute",p:"/dɪˈstrɪb.juːt/",pos:"動",m:"分配する",ety:"dis(別々に)+tribuere(与える)",ex:"Distribute the papers.",em:"📤"}, {w:"diverse",p:"/dɪˈvɝːs/",pos:"形",m:"多様な",ety:"dis(離れて)+vertere(向く)",ex:"Diverse cultures.",em:"🌈"}, {w:"domestic",p:"/dəˈmes.tɪk/",pos:"形",m:"国内の、家庭の",ety:"domus(家)",ex:"Domestic products.",em:"🏠"}, {w:"dominate",p:"/ˈdɑː.mə.neɪt/",pos:"動",m:"支配する",ety:"dominus(主人)",ex:"He dominated the conversation.",em:"👑"}, {w:"efficient",p:"/ɪˈfɪʃ.ənt/",pos:"形",m:"効率的な",ety:"ex(外へ)+facere(作る)→力を出し切る",ex:"Efficient use of energy.",em:"⚡"}, {w:"eliminate",p:"/iˈlɪm.ə.neɪt/",pos:"動",m:"取り除く",ety:"ex(外へ)+limen(敷居)→家の外へ出す",ex:"Eliminate errors.",em:"🗑️"}, {w:"emerge",p:"/iˈmɝːdʒ/",pos:"動",m:"現れる",ety:"ex(外へ)+mergere(沈む)→水から出る",ex:"A problem emerged.",em:"🐣"}, {w:"emphasis",p:"/ˈem.fə.sɪs/",pos:"名",m:"強調",ety:"en(中へ)+phainein(見せる)",ex:"Put emphasis on quality.",em:"❗️"}, {w:"encounter",p:"/ɪnˈkaʊn.t̬ɚ/",pos:"動",m:"遭遇する",ety:"in(中へ)+contra(対して)",ex:"Encounter difficulties.",em:"🚧"}, {w:"endure",p:"/ɪnˈdʊr/",pos:"動",m:"耐える",ety:"in(中へ)+durus(硬い)",ex:"Endure the pain.",em:"😣"}, {w:"enormous",p:"/əˈnɔːr.məs/",pos:"形",m:"巨大な",ety:"ex(外へ)+norma(標準)→桁外れの",ex:"An enormous amount of money.",em:"🐘"}, {w:"ensure",p:"/ɪnˈʃʊr/",pos:"動",m:"確実にする",ety:"en(中へ)+sure(確かな)",ex:"Ensure safety.",em:"🔒"}, {w:"essential",p:"/ɪˈsen.ʃəl/",pos:"形",m:"不可欠な",ety:"esse(存在する)→本質",ex:"Water is essential for life.",em:"💧"}, {w:"establish",p:"/ɪˈstæb.lɪʃ/",pos:"動",m:"設立する",ety:"stare(立つ)→安定させる",ex:"Establish a company.",em:"🏢"}, {w:"estimate",p:"/ˈes.tə.meɪt/",pos:"動",m:"見積もる",ety:"aestimare(価値を決める)",ex:"Estimate the cost.",em:"🧮"}, {w:"evidence",p:"/ˈev.ə.dəns/",pos:"名",m:"証拠",ety:"ex(外へ)+videre(見る)→外に見えているもの",ex:"Scientific evidence.",em:"👣"}, {w:"evolve",p:"/ɪˈvɑːlv/",pos:"動",m:"進化する",ety:"ex(外へ)+volvere(巻く)→展開する",ex:"Animals evolve over time.",em:"🐒"}, {w:"exaggerate",p:"/ɪɡˈzædʒ.ə.reɪt/",pos:"動",m:"誇張する",ety:"ex(強調)+agger(積み上げる)",ex:"Don't exaggerate the story.",em:"🐡"}, {w:"exhibit",p:"/ɪɡˈzɪb.ɪt/",pos:"動",m:"展示する",ety:"ex(外へ)+habere(持つ)",ex:"Exhibit paintings.",em:"🖼️"}, {w:"expand",p:"/ɪkˈspænd/",pos:"動",m:"拡大する",ety:"ex(外へ)+pandere(広げる)",ex:"Expand the business.",em:"🎈"}, {w:"expose",p:"/ɪkˈspoʊz/",pos:"動",m:"さらす",ety:"ex(外へ)+ponere(置く)",ex:"Expose the skin to the sun.",em:"☀️"}, {w:"factor",p:"/ˈfæk.tɚ/",pos:"名",m:"要因",ety:"facere(作る)→結果を作るもの",ex:"A key factor.",em:"🔑"}, {w:"feature",p:"/ˈfiː.tʃɚ/",pos:"名",m:"特徴",ety:"facere(作る)→作り、顔立ち",ex:"Special features.",em:"✨"}, {w:"federal",p:"/ˈfed.ɚ.əl/",pos:"形",m:"連邦の",ety:"foedus(盟約・条約)",ex:"Federal government.",em:"🏛️"}, {w:"financial",p:"/faɪˈnæn.ʃəl/",pos:"形",m:"財政の",ety:"finis(終わり→決済)",ex:"Financial support.",em:"💵"}, {w:"focus",p:"/ˈfoʊ.kəs/",pos:"動",m:"焦点を合わせる",ety:"focus(炉・家庭の中心)",ex:"Focus on the target.",em:"🔭"}, {w:"function",p:"/ˈfʌŋk.ʃən/",pos:"名",m:"機能",ety:"functio(遂行)",ex:"The function of the heart.",em:"⚙️"}, {w:"fundamental",p:"/ˌfʌn.dəˈmen.t̬əl/",pos:"形",m:"基本的な",ety:"fundus(底)",ex:"Fundamental rules.",em:"🧱"}, {w:"generate",p:"/ˈdʒen.ə.reɪt/",pos:"動",m:"生み出す",ety:"genus(種・生まれ)",ex:"Generate electricity.",em:"💡"}, {w:"guarantee",p:"/ˌɡer.ənˈtiː/",pos:"動",m:"保証する",ety:"warant(防衛・許可)",ex:"I guarantee it works.",em:"🛡️"}, {w:"hesitate",p:"/ˈhez.ə.teɪt/",pos:"動",m:"ためらう",ety:"haerere(くっつく)→動けない",ex:"Don't hesitate to ask.",em:"😓"}, {w:"identify",p:"/aɪˈden.t̬ə.faɪ/",pos:"動",m:"特定する",ety:"idem(同じ)→同一とみなす",ex:"Identify the problem.",em:"🆔"}, {w:"ignore",p:"/ɪɡˈnɔːr/",pos:"動",m:"無視する",ety:"in(否定)+gnoscere(知る)→知らないふり",ex:"Ignore the noise.",em:"🙉"}, {w:"illustrate",p:"/ˈɪl.ə.streɪt/",pos:"動",m:"説明する、挿絵を入れる",ety:"in(中へ)+lustrare(照らす)",ex:"Illustrate with examples.",em:"🖍️"}, {w:"impact",p:"/ˈɪm.pækt/",pos:"名",m:"影響、衝撃",ety:"in(中へ)+pangere(打ち込む)",ex:"A big impact on society.",em:"💥"}, {w:"imply",p:"/ɪmˈplaɪ/",pos:"動",m:"ほのめかす",ety:"in(中へ)+plicare(折る)→中に織り込む",ex:"Are you implying I'm wrong?",em:"😉"}, {w:"indicate",p:"/ˈɪn.də.keɪt/",pos:"動",m:"指し示す",ety:"in(中へ)+dicare(宣言する)",ex:"Research indicates that...",em:"👉"}, {w:"inevitable",p:"/ɪˈnev.ə.t̬ə.bəl/",pos:"形",m:"避けられない",ety:"in(不)+ex(外)+vitare(避ける)",ex:"Change is inevitable.",em:"🌪️"}, {w:"initial",p:"/ɪˈnɪʃ.əl/",pos:"形",m:"最初の",ety:"in(中へ)+ire(行く)→入り口",ex:"My initial reaction.",em:"1️⃣"}, {w:"injure",p:"/ˈɪn.dʒɚ/",pos:"動",m:"怪我をさせる",ety:"in(不)+jus(正義/法)→不当な扱い",ex:"He injured his leg.",em:"🩹"}, {w:"innovate",p:"/ˈɪn.ə.veɪt/",pos:"動",m:"革新する",ety:"in(中へ)+novus(新しい)",ex:"Innovate technology.",em:"🚀"}, {w:"inquire",p:"/ɪnˈkwaɪr/",pos:"動",m:"尋ねる",ety:"in(中へ)+quaerere(求める)",ex:"Inquire about the price.",em:"❓"}, {w:"insight",p:"/ˈɪn.saɪt/",pos:"名",m:"洞察力",ety:"in(中)+sight(視界)",ex:"Deep insight into nature.",em:"👁️"}, ]; let myWords = JSON.parse(localStorage.getItem('myWordsRoot100')) || []; // --- 初期化 --- window.onload = function() { searchDict(); }; // --- 検索機能 --- function searchDict() { const input = document.getElementById('searchInput').value.trim().toLowerCase(); const resultDiv = document.getElementById('searchResult'); resultDiv.innerHTML = ""; if (input.length === 0) { resultDiv.innerHTML = `<p style="text-align:center; color:#888;">単語を入力してください</p>`; return; } // 100語の中から検索 const matches = geminiDictionary.filter(d => d.w.toLowerCase().includes(input) || d.m.includes(input) ); renderDictList(matches, resultDiv); } function showAllDict() { document.getElementById('searchInput').value = ""; const resultDiv = document.getElementById('searchResult'); renderDictList(geminiDictionary, resultDiv); } function renderDictList(list, container) { if (list.length === 0) { container.innerHTML = `<p style="text-align:center; color:#999;">見つかりませんでした。</p>`; return; } container.innerHTML = list.map(d => { const isReg = myWords.some(w => w.w === d.w); return ` <div class="card ${isReg ? 'registered' : ''}"> <div class="header-row"> <div class="emoji-big">${d.em}</div> <div style="flex:1; margin-left:15px;"> <h3>${d.w}</h3> <span class="pronounce">${d.p}</span> <div><span class="tag">${d.pos}</span></div> </div> </div> <div class="meaning-box">${d.m}</div> <div class="etymology-box">🌱 ${d.ety}</div> <div class="example-box">${d.ex}</div> <button class="btn" onclick="toggleRegister('${d.w}')" ${isReg ? 'disabled' : ''}> ${isReg ? '✅ 登録済み' : '単語帳に追加'} </button> </div> `; }).join(''); } // --- 登録機能 --- function toggleRegister(wordStr) { const existing = myWords.find(w => w.w === wordStr); if (existing) return; const data = geminiDictionary.find(d => d.w === wordStr); if (data) { myWords.push({ ...data, mastery: 0 }); saveData(); if(document.getElementById('searchInput').value) { searchDict(); } else { showAllDict(); } } } function saveData() { localStorage.setItem('myWordsRoot100', JSON.stringify(myWords)); } // --- 勉強モード (削除・一覧) --- function renderStudyList() { const listDiv = document.getElementById('studyList'); if (myWords.length === 0) { listDiv.innerHTML = `<p style="text-align:center; margin-top:50px; color:#888;">単語帳は空です。<br>検索タブから追加してください。</p>`; return; } listDiv.innerHTML = myWords.map((w, idx) => ` <div class="card"> <button class="btn-del" onclick="deleteWord(${idx})">🗑️</button> <div style="display:flex; align-items:center; gap:10px;"> <span style="font-size:1.5rem;">${w.em}</span> <h3 style="margin:0;">${w.w}</h3> <span style="font-size:0.8rem; color:#888;">${getMasteryIcon(w.mastery)}</span> </div> <div class="meaning-box" style="font-size:1rem; margin-top:10px;">${w.m}</div> <div style="font-size:0.85rem; color:#666;">🌱 ${w.ety}</div> </div> `).join(''); } function deleteWord(idx) { if(confirm("削除しますか?")) { myWords.splice(idx, 1); saveData(); renderStudyList(); } } // --- 記憶モード (縦スクロール・フリップ式) --- function startMemorize() { const listDiv = document.getElementById('memoList'); if (myWords.length === 0) { listDiv.innerHTML = `<p style="text-align:center; margin-top:50px;">単語帳に登録すると<br>ここにカードが表示されます。</p>`; return; } listDiv.innerHTML = myWords.map((w, idx) => ` <div class="memo-card-container" onclick="flipItem(this)"> <div class="memo-card"> <div class="memo-face memo-front"> <div style="font-size:0.9rem; color:#888; position:absolute; top:15px; left:15px;">${w.pos}</div> <div class="status-badge">${getMasteryIcon(w.mastery)}</div> <h2 style="font-size:2.5rem; margin:0; color:#333;">${w.w}</h2> <p style="color:#666;">${w.p}</p> <p style="font-size:0.8rem; color:#aaa; margin-top:20px;">TAP TO CHECK</p> </div> <div class="memo-face memo-back"> <div style="display:flex; gap:10px; align-items:center; border-bottom:1px solid #eee; padding-bottom:10px;"> <span style="font-size:2rem;">${w.em}</span> <h2 style="margin:0;">${w.w}</h2> </div> <div class="meaning-box" style="color:#e74c3c; margin-top:15px;">${w.m}</div> <div class="etymology-box">🌱 ${w.ety}</div> <div class="example-box">${w.ex}</div> <div class="mastery-row" onclick="event.stopPropagation()"> <button class="m-btn" style="background:#e74c3c;" onclick="updateMastery(${idx}, 0)">❌ 忘</button> <button class="m-btn" style="background:#f39c12;" onclick="updateMastery(${idx}, 1)">⚠️ 悩</button> <button class="m-btn" style="background:#2ecc71;" onclick="updateMastery(${idx}, 2)">⭕ 覚</button> </div> </div> </div> </div> `).join(''); } function flipItem(el) { // カードの要素(.memo-card)を取得して回転クラスをつけ外し const card = el.querySelector('.memo-card'); card.classList.toggle('flipped'); } function updateMastery(idx, level) { myWords[idx].mastery = level; saveData(); // 現在のリストを再描画せずに、ボタンの見た目だけ変えるなどの処理も可能だが、 // わかりやすく再描画する(ただしフリップ状態は戻る) startMemorize(); } function getMasteryIcon(level) { return ['❌','⚠️','⭕'][level] || '🆕'; } // --- モード切替 --- function changeMode(modeId) { document.querySelectorAll('.mode-section').forEach(s => s.classList.remove('active')); document.querySelectorAll('nav button').forEach(b => b.classList.remove('active')); document.getElementById(modeId).classList.add('active'); document.getElementById('nav-' + modeId.split('-')[0]).classList.add('active'); if(modeId === 'study-mode') renderStudyList(); if(modeId === 'memorize-mode') startMemorize(); } </script> </body> </html>
上書き保存する
キャンセルして新規作成に戻る
📂 APP の作品
ProVocab - 縦スクロール暗記版
eigo2.html (01/15 10:37)
✏️ 修正
🌏 公開
🗑️
ProVocab - 語源マスター版
eigo.html (01/15 10:37)
✏️ 修正
🌏 公開
🗑️
進化版!わんわんタイマー
timer3.html (01/14 13:38)
✏️ 修正
🌏 公開
🗑️
わんわん応援タイマー
timer.html (01/14 12:49)
✏️ 修正
🌏 公開
🗑️
進化版!わんわんタイマー
timer2.html (01/14 12:17)
✏️ 修正
🌏 公開
🗑️