Last active
July 4, 2022 07:10
-
-
Save motsu0/5f2f7252ed70388d1c7cc3fe5496d294 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.img-sample{ | |
width: 150px; | |
border: 1px solid #777; | |
} | |
/* */ | |
.block{ | |
box-sizing: border-box; | |
padding: 16px; | |
margin: 20px 0; | |
border-radius: 8px; | |
border: 3px outset #ccc; | |
} | |
h3.block__title{ | |
margin: 0 0 16px 0; | |
} | |
/* */ | |
.search-row{ | |
margin: 16px 0; | |
} | |
.icon-google{ | |
vertical-align: middle; | |
} | |
#bt-submit{ | |
padding: 4px 12px; | |
margin-right: 12px; | |
cursor: pointer; | |
} | |
/* */ | |
.list-books-outer{ | |
box-sizing: border-box; | |
max-height: 500px; | |
padding: 16px; | |
overflow-y: auto; | |
background-color: #eee; | |
border: 2px inset #ddd; | |
} | |
.book{ | |
box-sizing: border-box; | |
border: 1px solid #555; | |
background-color: #fff; | |
} | |
.book+.book{ | |
margin: 12px 0; | |
} | |
.book__imgbox{ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
box-sizing: border-box; | |
padding: 8px; | |
} | |
.book__img{ | |
width: 100%; | |
height: 120px; | |
object-fit: contain; | |
} | |
.book__textbox{ | |
box-sizing: border-box; | |
padding: 8px; | |
border: dashed #aaa; | |
border-width: 1px 0; | |
} | |
.book__linkbox{ | |
display: flex; | |
justify-content: center; | |
flex-direction: column; | |
box-sizing: border-box; | |
padding: 8px; | |
} | |
.book__link,.bt-copy{ | |
display: block; | |
margin: 4px 0; | |
cursor: pointer; | |
} | |
/* */ | |
.settings-row{ | |
margin: 12px 0; | |
} | |
.settings-img{ | |
width: 200px; | |
max-width: 100%; | |
max-height: 200px; | |
object-fit: contain; | |
} | |
/* */ | |
#preview,#output{ | |
text-align: center; | |
} | |
#preview__body,#output__body{ | |
margin: 16px auto; | |
} | |
#preview__body{ | |
width: 100%; | |
overflow: hidden; | |
box-shadow: 0 0 0 1px #777 | |
} | |
.preview__title{ | |
text-align: center; | |
} | |
#preview__img{ | |
display: block; | |
max-width: 100%; | |
margin: 0 auto; | |
} | |
#preview__table{ | |
margin: 8px; | |
} | |
.preview__td{ | |
line-height: 1.7em; | |
text-align: left; | |
word-break: break-all; | |
} | |
.preview__td:first-of-type{ | |
word-break: keep-all; | |
white-space: nowrap; | |
} | |
.output__canvas{ | |
display: block; | |
box-sizing: content-box; | |
margin: 0 auto; | |
border: 1px solid #777; | |
} | |
#bt-makeImg,#bt-dlImg{ | |
margin: 16px auto; | |
cursor: pointer; | |
} | |
#bt-makeImg{ | |
display: block; | |
} | |
/* */ | |
.s-invisible{ | |
visibility: hidden; | |
} | |
.s-hide{ | |
display: none; | |
} | |
/* */ | |
@media screen and (min-width:769px) { | |
.book{ | |
display: flex; | |
} | |
.book__imgbox{ | |
width: 15%; | |
} | |
.book__textbox{ | |
flex-grow: 1; | |
width: 0; | |
border-width: 0 1px; | |
} | |
.book__linkbox{ | |
width: 20%; | |
} | |
#preview__body{ | |
width: 400px; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="block"> | |
<h3 class="block__title">Googleブックスから各情報を取得</h3> | |
<form id="search"> | |
<div class="search__row"> | |
検索ワード: <input type="text" id="input-keyword" placeholder="検索ワード" required> | |
</div> | |
<div class="search-row"> | |
<button id="bt-submit">検索</button> | |
<img src="pathto/poweredbygoogle.png" alt="POWERED BY Google" class="icon-google"> | |
</div> | |
<div class="search-row"> | |
<div id="message"></div> | |
</div> | |
</form> | |
<div class="list-books-outer"> | |
<div id="list-books"></div> | |
</div> | |
</div> | |
<div id="block-information" class="block"> | |
<h3 class="block__title">書籍情報登録</h3> | |
<div class="settings-row"> | |
タイトル: <input type="text" id="input-title" data-name="タイトル" placeholder="例:ももたろう"> | |
</div> | |
<div class="settings-row"> | |
ISBN-10: <input type="text" id="input-isbn10" data-name="ISBN-10" placeholder="例:1234567890"> | |
</div> | |
<div class="settings-row"> | |
ISBN-13: <input type="text" id="input-isbn13" data-name="ISBN-13" placeholder="例:1234567890123"> | |
</div> | |
<div class="settings-row"> | |
作者: <input type="text" id="input-author" data-name="作者" placeholder="例:山田太郎"> | |
</div> | |
<div class="settings-row"> | |
レーベル: <input type="text" id="input-label" data-name="レーベル" placeholder="例:◯◯文庫"> | |
</div> | |
<div class="settings-row"> | |
出版社: <input type="text" id="input-publisher" data-name="出版社" placeholder="例:◯✕社"> | |
</div> | |
<div class="settings-row"> | |
出版日: <input type="text" id="input-date" data-name="出版日" placeholder="例:2000年1月1日"> | |
</div> | |
</div> | |
<div class="block"> | |
<h3 class="block__title">書籍画像登録</h3> | |
<div id="settings-imgbox"></div> | |
<input type="file" id="input-img"> | |
</div> | |
<div class="block"> | |
<h3 class="block__title">設定</h3> | |
<div class="settings-row"> | |
フォントサイズ: <input type="number" min="4" max="50" id="input-fontsize" value="16">px | |
</div> | |
<div class="settings-row"> | |
完成画像の最大アスペクト比: | |
<select id="sel-aspect"> | |
<option value="auto">標準(縦16:横9)</option> | |
<option value="device">使用中の機器に合わせる</option> | |
</select> | |
</div> | |
</div> | |
<div id="block-output" class="block"> | |
<h3 class="block__title">出力結果</h3> | |
<div id="preview"> | |
<div class="preview__title">プレビュー</div> | |
<div id="preview__body" style="font-size: 16px;"> | |
<img src="" alt="" id="preview__img" class="s-hide"> | |
<table id="preview__table"></table> | |
</div> | |
<button id="bt-makeImg">画像を生成</button> | |
</div> | |
<div id="output" class="s-hide"> | |
<div class="preview__title">完成画像</div> | |
<div id="output__body"></div> | |
<a href="" id="bt-dlImg" download="book-information.png">画像を保存</a> | |
</div> | |
</div> | |
<script src="pathto/now-loading.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js" integrity="sha256-6H5VB5QyLldKH9oMFUmjxw2uWpPZETQXpCkBaDjquMs=" crossorigin="anonymous"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const nowloading = new nowLoading(); | |
const el_search = document.getElementById('search'); | |
const el_input_keyword = document.getElementById('input-keyword'); | |
const bt_submit = document.getElementById('bt-submit'); | |
const el_message = document.getElementById('message'); | |
const el_list_books = document.getElementById('list-books'); | |
const el_block_information = document.getElementById('block-information'); | |
const els_settings = { | |
title: document.getElementById('input-title'), | |
isbn10: document.getElementById('input-isbn10'), | |
isbn13: document.getElementById('input-isbn13'), | |
author: document.getElementById('input-author'), | |
label: document.getElementById('input-label'), | |
publisher: document.getElementById('input-publisher'), | |
date: document.getElementById('input-date') | |
} | |
const array_settings = ['title','isbn10','isbn13','author','label','publisher','date']; | |
const el_settings_imgbox = document.getElementById('settings-imgbox'); | |
const els_settings_img = document.getElementsByClassName('settings-img'); | |
const el_input_img = document.getElementById('input-img'); | |
const el_input_fontsize = document.getElementById('input-fontsize'); | |
const el_sel_aspect = document.getElementById('sel-aspect'); | |
const el_block_output = document.getElementById('block-output'); | |
const el_preview = document.getElementById('preview'); | |
const el_preview__body = document.getElementById('preview__body'); | |
const el_preview__img = document.getElementById('preview__img'); | |
const el_preview__table = document.getElementById('preview__table'); | |
const el_output = document.getElementById('output'); | |
const el_output__body = document.getElementById('output__body'); | |
const bt_makeImg = document.getElementById('bt-makeImg'); | |
const bt_dlImg = document.getElementById('bt-dlImg'); | |
let is_using = false; | |
let blob_output; | |
el_input_keyword.addEventListener('input',()=>{ | |
if(el_input_keyword.value.length<2){ | |
el_input_keyword.setCustomValidity('キーワードが短すぎます。'); | |
}else{ | |
el_input_keyword.setCustomValidity(''); | |
} | |
}); | |
el_search.addEventListener('submit',e=>{ | |
e.preventDefault(); | |
request(); | |
}); | |
el_input_img.addEventListener('input',checkFile); | |
array_settings.forEach(v=>{ | |
els_settings[v].addEventListener('input',makePreview); | |
}); | |
el_input_fontsize.addEventListener('input',makePreview); | |
el_sel_aspect.addEventListener('change',makePreview); | |
bt_makeImg.addEventListener('click',makeImg); | |
el_preview__img.onload = checkAspect; | |
function request(){ | |
//初期化 | |
if(is_using) return; | |
is_using = true; | |
bt_submit.classList.add('s-invisible'); | |
el_message.textContent = '検索中...'; | |
el_list_books.textContent= ''; | |
// | |
const url_base = 'https://www.googleapis.com/books/v1/volumes'; | |
const params = { | |
maxResults: 30 | |
}; | |
if(el_input_keyword.value!='') params.q = el_input_keyword.value; | |
const str_params = new URLSearchParams(params).toString(); | |
const url = url_base + '?' + str_params; | |
fetch(url).then(response=>{ | |
bt_submit.classList.remove('s-invisible'); | |
el_message.textContent = ''; | |
is_using = false; | |
if(response.ok){ | |
return response.json(); | |
}else{ | |
throw new Error('通信に失敗しました。一日の利用制限数に達した可能性があります。'); | |
} | |
}).then(data=>{ | |
makeList(data); | |
}).catch(error=>{ | |
writeMessage(error); | |
}); | |
} | |
function writeMessage(str){ | |
el_message.textContent = str; | |
} | |
function makeList(res){ | |
if(res==false||res==undefined){ | |
writeMessage('通信に失敗しました。一日の利用制限数に達した可能性があります。'); | |
bt_submit.classList.remove('s-invisible'); | |
is_using = false; | |
return; | |
} | |
res.items.forEach((item,i)=>{ | |
//情報取得 | |
const img_src = item.volumeInfo.imageLinks; | |
const title = item.volumeInfo.title || ''; | |
const authors = item.volumeInfo.authors; | |
const isbn = item.volumeInfo.industryIdentifiers; | |
const date = item.volumeInfo.publishedDate; | |
const link = item.volumeInfo.canonicalVolumeLink; | |
//html作成 | |
const el_book = document.createElement('div'); | |
el_book.classList.add('book'); | |
const el_book__imgbox = document.createElement('div'); | |
el_book__imgbox.classList.add('book__imgbox'); | |
if(img_src==undefined){ | |
el_book__imgbox.textContent = '画像無し'; | |
}else{ | |
const img = document.createElement('img'); | |
img.classList.add('book__img'); | |
img.src = img_src.smallThumbnail; | |
el_book__imgbox.appendChild(img); | |
} | |
el_book.appendChild(el_book__imgbox); | |
// | |
const el_book__textbox = document.createElement('div'); | |
el_book__textbox.classList.add('book__textbox'); | |
if(title!=undefined){ | |
const el_book__title = document.createElement('div'); | |
el_book__title.classList.add('book__text'); | |
el_book__title.textContent = title; | |
el_book__textbox.appendChild(el_book__title); | |
} | |
if(authors!=undefined){ | |
const el_book__author = document.createElement('div'); | |
el_book__author.classList.add('book__text'); | |
el_book__author.textContent = authors.join('/'); | |
el_book__textbox.appendChild(el_book__author); | |
} | |
el_book.appendChild(el_book__textbox); | |
// | |
const el_book__linkbox = document.createElement('div'); | |
el_book__linkbox.classList.add('book__linkbox'); | |
const el_link = document.createElement('a'); | |
el_link.classList.add('book__link'); | |
el_link.href = link; | |
el_link.textContent = 'Googleブックス'; | |
el_book__linkbox.appendChild(el_link); | |
const bt_copy = document.createElement('button'); | |
bt_copy.classList.add('bt-copy'); | |
bt_copy.textContent = '情報を取得'; | |
bt_copy.addEventListener('click',()=>{ | |
copyInfo(bt_copy); | |
}); | |
el_book__linkbox.appendChild(bt_copy); | |
el_book.appendChild(el_book__linkbox); | |
//データ登録 | |
bt_copy.dataset.title = title; | |
if(authors!=undefined) bt_copy.dataset.author = authors.join('/'); | |
if(isbn!=undefined){ | |
isbn.forEach(v=>{ | |
if(v.type=='ISBN_10'){ | |
bt_copy.dataset.isbn10 = v.identifier; | |
}else if(v.type=='ISBN_13'){ | |
bt_copy.dataset.isbn13 = v.identifier; | |
} | |
}); | |
} | |
bt_copy.dataset.date = date; | |
// | |
el_list_books.appendChild(el_book); | |
}); | |
} | |
function copyInfo(el){ | |
array_settings.forEach(v=>{ | |
if(el.dataset[v]==undefined||el.dataset[v]=='undefined'){ | |
els_settings[v].value = ''; | |
}else{ | |
els_settings[v].value = el.dataset[v]; | |
} | |
}); | |
makePreview(); | |
//移動 | |
const x = window.pageXOffset; | |
const y = window.pageYOffset + el_block_information.getBoundingClientRect().top; | |
window.scrollTo({ | |
top:y, | |
left:x, | |
behavior: 'smooth' | |
}); | |
} | |
function checkFile(e){ | |
const files = e.target.files; | |
if(files.length==0) return; | |
const file = files[0]; | |
e.target.value = ''; | |
if(file.type.indexOf('image')==-1){ | |
el_settings_imgbox.textContent = '画像を選択してください。'; | |
return; | |
} | |
el_settings_imgbox.textContent = ''; | |
const reader = new FileReader(); | |
reader.onload = ev=>{ | |
const img = document.createElement('img'); | |
img.classList.add('settings-img'); | |
img.src = ev.target.result; | |
el_settings_imgbox.appendChild(img); | |
makePreview(); | |
} | |
reader.readAsDataURL(file); | |
} | |
function makePreview(){ | |
//初期処理 | |
el_output.classList.add('s-hide'); | |
el_preview.classList.remove('s-hide'); | |
//フォントサイズ | |
const fs = (()=>{ | |
let temp = Number(el_input_fontsize.value); | |
if(temp<4){ | |
return 4; | |
}else if(temp>50){ | |
return 50; | |
}else{ | |
return temp; | |
} | |
})(); | |
el_preview__body.style.fontSize = fs+'px'; | |
//画像 | |
if(els_settings_img.length>0){ | |
el_preview__img.classList.remove('s-hide'); | |
if(el_preview__img.src!=els_settings_img[0].src){ | |
el_preview__img.src = els_settings_img[0].src; | |
el_preview__img.alt = '画像'; | |
} | |
}else{ | |
el_preview__img.classList.add('s-hide'); | |
el_preview__img.alt = ''; | |
} | |
//データテーブル | |
el_preview__table.textContent = ''; | |
array_settings.forEach(v=>{ | |
if(els_settings[v].value=='') return; | |
const el_tr = document.createElement('tr'); | |
const el_td_name = document.createElement('td'); | |
el_td_name.classList.add('preview__td'); | |
el_td_name.textContent = els_settings[v].dataset.name; | |
el_tr.appendChild(el_td_name); | |
const el_td_colon = document.createElement('td'); | |
el_td_colon.classList.add('preview__td'); | |
el_td_colon.textContent = ':'; | |
el_tr.appendChild(el_td_colon); | |
const el_td_val = document.createElement('td'); | |
el_td_val.classList.add('preview__td'); | |
el_td_val.textContent = els_settings[v].value; | |
el_tr.appendChild(el_td_val); | |
el_preview__table.appendChild(el_tr); | |
}); | |
if(el_preview__table.textContent==''){ | |
el_preview__table.classList.add('s-hide'); | |
}else{ | |
el_preview__table.classList.remove('s-hide'); | |
} | |
checkAspect(); | |
} | |
function checkAspect(){ | |
const w_now = el_preview__body.clientWidth; | |
const rate = (()=>{ | |
if(el_sel_aspect.value=='auto'){ | |
return 16/9; | |
}else{ | |
return window.screen.height/window.screen.width; | |
} | |
})(); | |
const h_max = w_now*rate; | |
el_preview__body.style.height = ''; | |
el_preview__img.style.height = '' | |
const diff = el_preview__body.clientHeight - h_max; | |
if(diff>0){ | |
el_preview__img.style.height = Math.max(el_preview__img.clientHeight-diff,0) + 'px'; | |
} | |
if(el_preview__body.clientHeight - h_max>10){ | |
el_preview__body.style.height = h_max+'px'; | |
} | |
} | |
function makeImg(){ | |
if(el_preview__table.textContent==''&&el_preview__img.alt=='') return; | |
//初期処理 | |
nowloading.start(); | |
el_output__body.textContent = ''; | |
// | |
setTimeout(()=>{ | |
html2canvas(el_preview__body,{ | |
scale: 2 | |
}).then(canvas => { | |
canvas.classList.add('output__canvas'); | |
el_output__body.appendChild(canvas); | |
canvas.toBlob(blob=>{ | |
bt_dlImg.href = URL.createObjectURL(blob); | |
URL.revokeObjectURL(blob); | |
}); | |
//後処理 | |
el_preview.classList.add('s-hide'); | |
el_output.classList.remove('s-hide'); | |
//移動 | |
const x = window.pageXOffset; | |
const y = window.pageYOffset + el_block_output.getBoundingClientRect().top; | |
window.scrollTo(x,y); | |
nowloading.stop(); | |
}); | |
},1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment