還暦お婆ちゃんのデザイナー修行
秋も深まり寒くなってきた昨今。
近所の畑の直売所で秋のマニアック野菜を購入してきました。
- ズイキ3本...100円
サトイモの茎です。お店ではまず見ませんね。
乾燥したものは「芋がら」としてスーパーで売られています。
シャキシャキとした歯ごたえで味はクセがなく、汁物、鍋、炒め物、何でも合います。 - オロ大根3本...90円
葉っぱだけ成長した大根に見えますが、よくわかりません。
葉は大根特有の苦味はなく、ほうれん草や小松菜のように使えます。 - ヤーコン4本...200円
食物繊維が多くカロリーが低いイモ類で一時期ダイエットで注目されました。 今はスーパーで見かけることはほとんどないです。ちょっとお高めでした。 - ゆず4個...100円
マニアック野菜ではないですが、不揃いで傷がついてます。
果汁は薬味で、搾かすはお風呂で再利用。いい香りでした。
還暦ばあちゃん仕事の近況
入社してから5ヶ月目になります。
デザインの修正も少なくなりましたが、まだまだ未熟者です。
ようやく会社の空気感が掴めるようになったというか…
従業員は多いのですがほとんどテレワークなので、連絡している相手に滅多に会うことはありません。
入社時は世間が自粛状態で仕事は比較的暇でした。
徐々に仕事が増えてきて、先月くらいからメチャメチャ忙しくなってきています。お国のGoToキャンペーン政策や行事の緩和で。
おばあちゃんの仕事はディレクターさんが進行を仕切ってくれます。
スポットの依頼が来て、案件が重なって、追加依頼も来て、クライアント側の変更が同時に出て頭がクラクラ。
まずは頭をカラにして、ディレクターさんに優先順位と納期を確認。スケジュールを組み直してもらいます。
そして校了をもらえてホッとしたら次の案件へ。
最初はバナーデザインがメインでしたが、最近はちょっとしたwebページのデザインも任されるようになりました。
おばあちゃんの手作りサイト作ったよ
仕事ではデザインがメインですが、コーディングも好きなのでお休みは練習でサンプルサイト作ってます。
チクチクと作業を積み重ねて、ようやくサンプルサイトが完成しました。
コンテンツの内容はおばあちゃんの畑事情。
トップ1pと下層ページ4p、流行りのGoogleマテリアルデザインを意識して作りました。
マテリアルUIコンポーネントとCSSフレームワークbootstrap-material-designをダウンロード。
bootstrapは全体の枠組みのcontainerとrowを、コンテンツはcardを適用。細かいCSSとjsは自分で設計。
ファーストビューのスライドはフツーのだとつまらないので、ズームアップしながらフェードで切替わる仕組みを作りました。
ただページャーを連携させるのは面倒だったのでページャーをクリックしても何も起こりません。
コーディングが済んだらhtmlをphpへ組替えて、headerとfooterをインクルードしました。
そうするとnavとかのリンクが1pで完結するのでメンテが楽になります。
ただ、titleやnavのアクティブはページによって変えたいのでURLのパスを取得してページに合わせて条件分岐で切り替えています。
//パス名取得 $pass = $_SERVER['REQUEST_URI']; //初期値書出し for($i = 0; $i < 5; $i++){ $act[$i] = 'nav-item'; } if($pass === '/hatake/index.php' || $pass === '/hatake/'){ $head_title = '草ぼうぼう サンプルサイト'; $act[0] = 'nav-item active'; } if($pass === '/hatake/works.php'){ $head_title = 'works | 草ぼうぼう サンプルサイト'; $act[1] = 'nav-item active'; } if($pass === '/hatake/access.php'){ $head_title = 'ACCESS | 草ぼうぼう サンプルサイト'; $act[2] = 'nav-item active'; } if($pass === '/hatake/recruit.php'){ $head_title = 'RECRUIT | 草ぼうぼう サンプルサイト'; $act[3] = 'nav-item active'; } if($pass === '/hatake/contact.php'){ $head_title = 'CONTACT | 草ぼうぼう サンプルサイト'; $act[4] = 'nav-item active'; }
あとPhotoshopCCも使いたくてお絵描きしました。
Psは会社で毎日さわってますが、お絵描きで使うツールが全く違います。
プロ仕様のグラフィックソフトは多機能ですね。
休みはwebのコーディングやデザインの練習、お絵描きもしたいし写真も撮りたい。
畑は時間がないので草ぼうぼうの放置状態。
家事もサボってるので田舎では不良お婆ちゃんです。
60歳お婆ちゃんはホームページのお勉強してます
ホームページ作成の為にいろいろ勉強しています。
そんな最中、今まで見たこともない大きなクモに出くわしました。
脚も入れるとCD1枚弱くらいの大きさ。恐怖で身が氷るような感覚に。
蜘蛛は大の苦手ですが、この衝撃的なビジュアルを残したくて怯えながらデジカメを撮る事に。
世間から「不快害虫」として認定されてるので、準備なく見せられると不快に思われるかもしれません。
そこで、見る見ないの選択ができるようスライドの機能をつけてみました。
アシダカ軍曹
※矢印の円形部分をクリックすると画像が現れます。
やっぱり隠す
この大蜘蛛の正体はアシダカ蜘蛛。
アシダカ軍曹と呼ばれているそうです。
なんと軍曹の好物はゴキブリ。
夜な夜なゴキブリを捕まえて、多い時は一晩に20匹捉えることも。
ゴキブリだけでなく、ハエやネズミといった害獣も食べてくれる。
糸を貼ることはなく徘徊性で、毒は持っていないし人を襲うこともない。もちろん人の食べ物にも手を出さない。
しかも見かけによらず、動きはゴキブリより早いらしい。
ゴキブリが普通車だったら、軍曹はF1並みのスピードだという。
どうもここのところゴキブリが少ないなと思っていた。
軍曹のおかげだったのかな…?エコで無料のゴキブリ駆除剤。
だから、地方によっては「家の守り神」と呼ばれているそう。
そしてゴキブリを食べ尽くすと、その家からは去ってくれるらしい。
調べてみると何とも有難い存在だけど、やはり見かけが…
そんな軍曹はネットで購入もできるそうで。
1,500円前後でヤフオクに出展されていました。
飼う人、いるんですね…。
数日後、軍曹の子供らしき2,3cmの同じ型の蜘蛛も発見。
1人前の軍曹になる前だから伍長かな。
どうやら我が家には軍曹の家族が暮らしているようで。
同居するのは構いませんが、どうか遭遇することなく平和な毎日が過ごせるよう願ってる次第です。
スライドのコードについて
ハテナブログの記事入力欄はHTML入力できるので、javascriptも試してみました。
jQueryは効かなかったので、DOMで組み込んでいます。
四角のピースに当たるliはjsから書き出すと、変更しやすくなります。
<script>
const photo = document.querySelector('#wrapper2');
const start = document.querySelector('#start');
const close = document.querySelector('#close p');
let box = document.querySelector('#wrapper2 ul');
//li書出し
for(let i=0; i < 8; i++){
let box = document.createElement('ul');
photo.appendChild(box);
box.classList.add('box');
for(let i=0; i < 10; i++){
let boxItem = document.createElement('li');
box.appendChild(boxItem);
boxItem.classList.add('item');
}
}
//li要素配列で取得
let item = document.getElementsByClassName('item');
const max = item.length;
const speed = 50;
//順番にliを消していく
start.addEventListener('click',function(){
start.style.display = 'none';
for(let i=0; i < max; i++){
setTimeout(function(){
item[i].style.opacity = '0';
}, speed*i);
}
setTimeout(function(){
close.style.display = 'block';
}, speed*(max-10));
});
//逆再生
close.addEventListener('click',function(){
close.style.display = 'none';
let la = 0;
for(let i=max-1; i >= 0; i--){
setTimeout(function(){
item[i].style.opacity = '1';
}, speed*la);
la++;
}
setTimeout(function(){
start.style.display = 'block';
}, speed*max);
});
</script>
createElementでタグを生成し、classList.addでclassを付与します。 getElementsByClassNameで全部のピース要素を配列形式で取得して、出力はsetTimeoutでタイミングをずらしながら、for文で処理を繰り返し。
60歳お婆ちゃんプログラムに挑戦してみた
60歳を間近にウェブデザイナーを目指して独学で勉強しているお婆ちゃんです。
去年の暮れからphpを勉強して、初めてシステムらしきものを作ってみました。
・やりたいこと プチ・クラウドストレージ
ファイルをどこからでもアップ、保管してダウンロードもできる。
セキュリティも兼ねてIDとパスワードでログイン形式にする。
まずはパワーポイントでサイトの系図を設計しました。
Excel、Word、パワポは商工会議所で習いたてホヤホヤです。
それぞれ基礎編までクリアして一ヶ月半くらいかかりました。
全部で5万円くらいはかかったかな。
次は手順を考えてイメージを具体化
これはAdobeのXDを使ってみました。
もうお金がないので無料版。
操作も簡単で、習わなくても感覚的に作れちゃうので便利です。
ページ自体はシンプルにしたかったのでフォントだけで作りました。
コードを書くのもAdobeの無料Brakets。Adobeドップリ。
ログインページ
パスワードとIDはここで決めてます。
空文字はNGの条件も設定。
・login.php
//XSS
function html_escape($word){
return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
}
$logid = '';
$pass = '';
$messege = '';
if($_SERVER['REQUEST_METHOD'] === 'POST'){
//isset入れると空文字条件が効かない
$logid = $_POST['logid'];
$pass = $_POST['pass'];
$logid = html_escape($logid);
$pass = html_escape($pass);
//IDとパスワード設定
if($logid === '' && $pass === ''){
session_start();
$_SESSION['login'] = 1;
//ファイル一覧へリロード
header('Location: file_list.php');
exit();
} elseif ($logid === '' || $pass === ''){
$messege = '<p class="notice">IDとパスワードを空文字にしないで入力してください</p>';
} else {
$messege = '<p class="notice">IDかパスワード、もしくは両方違います</p>';
}
}
?>
<!doctype html>
<!-- headerインクルード -->
<?php require_once(dirname(__FILE__).'/header.php'); ?>
<div id="wrapper">
<header>
<div id="titleVar">
<h1>ファイル預かり処 マイ保管庫</h1>
<p class="tx14">ログインページ</p>
</div>
<div id="topvew">My keep folder</div>
</header>
<main id="topMain">
<form class="clearfix" action="" method="post">
<label>ログインID</label>
<input name="logid" type="text" />
<label>パスワード</label>
<input name="pass" type="password" />
<p id="logBtn"><input type="submit" value="ログイン" /></p>
<?php echo $messege; ?>
</form>
</main>
<!-- footerインクルード -->
<?php require_once(dirname(__FILE__).'/footer.php'); ?>
</div>
ファイルリスト一覧ページ
アップロードとダウンロード、削除ファイルの3つのform
アップロードは同一ページで処理
ダウンロードはチェックページに飛ばしてリロード処理
削除ファイルは確認ページを別に作ってpostデータを渡す
ちなみにダウンロードと削除ファイルはタブ切替。
フォルダーの中身は一緒でアップすると自動でリストが増えて、削除すると減っていきます。
・file_list.php
//ログインしていないとアクセスさせない
session_start();
session_regenerate_id(true);
if(isset($_SESSION['login']) === false){
header('Location: un_login.php');
exit();
}
function html_escape($word){
return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
}
$up_file = '';
$messege = '';
$select_file = '<p id="take">ファイルを選択して下さい</p>';
$restore = '';
$up_before = 'upBefore';//非表示css
$filename = '';
if($_SERVER['REQUEST_METHOD'] === 'POST'){
$up_file = $_FILES['file_up'];
$up_file['name'] = html_escape($up_file['name']);
$up_file['name'] = strtolower($up_file['name']);//英小文字に変換
//var_dump($up_file['name']);
$extension = Pathinfo($up_file['name'],PATHINFO_EXTENSION);//.以降の拡張子を重複しないよう整形
$filename = Pathinfo($up_file['name'],PATHINFO_FILENAME);
$filename = str_replace('.', '', $filename);//ファイル名に.があったら除去
//ファイルがNGの場合条件処理
if($up_file['size'] > 30000000 ){
$messege = '<p id="caution" class="notice"><i class="fas fa-info-circle"></i>ファイルサイズが容量を超えています</p>';
$up_before = 'upBefore';
$restore = '<a id="restore" href="file_list.php">こちらからUPし直してください</a>';
$select_file = '';
//phpよりエラー表示を出すときsubmitのvalue値を空文字に
} else {
$messege = '';
$up_before = 'upAfter';
//fileをアップする関数
move_uploaded_file($up_file['tmp_name'], './up_file/'.$filename.'.'.$extension);
}
}
//upフォルダの中身
$dw_items = glob('./up_file/*');//DL用、同じでも変数変えないとエラーになる
$del_items = glob('./up_file/*');//削除用、grobは配列形式でファイルパスを取得
?>
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>ファイル一覧 | ファイル預かり処・マイ保管庫</title>
<!-- headerインクルード -->
<?php require_once(dirname(__FILE__).'/header.php'); ?>
<div id="wrapper">
<header>
<div id="titleVar">
<h1><i class="fas fa-circle"></i>ファイル預かり処 マイ保管庫</h1>
<p id="logout"><a href="logout.php">ログアウト</a></p>
</div>
<div id="topvew">My keep folder</div>
</header>
<main id="main">
<h2 class="pageTitle">ファイルアップロード</h2>
<!-- ファイルup -->
<form id="upBox" action="" method="post" enctype="multipart/form-data">
<p class="notice">※ファイルsizeは1つにつき30MBまで、名前は英小文字で</p>
<!-- UPし直し表示 -->
<?php echo $restore; ?>
<p id="<?php echo $up_before; ?>">ファイル「<?php echo $filename; ?>」はアップされました。続けてUPできます</p>
<label for="up">
<!-- ファイルを選択ボタン -->
<?php echo $select_file; ?>
<input id="up" type="file" name="file_up">
</label>
<p id="send"><input type="submit" value=""></p>
<!-- エラーメッセージ -->
<?php echo $messege; ?>
</form>
<div id="fileBox">
<p id="fileCount">ファイル数<?php echo count($dw_items); ?>項目</p>
<h3 class="selectFile" id="dowTab">DL用ファイル一覧</h3>
<form id="dowList" action="download_file.php" method="post">
<!-- 飛び先でLocation リダイレクト処理-->
<ul>
<?php if(count($dw_items) === 0): ?>
<li>まだファイルはありません</li>
<?php else: ?>
<?php foreach($dw_items as $items): $dw_name = Pathinfo($items,PATHINFO_BASENAME); ?>
<li><input type="radio" name="dowl" value="<?php echo $dw_name; ?>"><?php echo $dw_name; ?></li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
<p class="notice">※左のラジオボタンにチェックしてダウンロードボタンをクリックしてください</p>
<p class="pibtn"><input type="submit" value="Download"></p>
</form>
<h3 class="selectFile" id="delTab">削除用ファイル一覧</h3>
<form id="delList" action="delete_confilm.php" method="post">
<ul>
<?php if(count($dw_items) === 0): ?>
<li>まだファイルはありません</li>
<?php else: ?>
<?php foreach($del_items as $items): $del_name = Pathinfo($items,PATHINFO_BASENAME); ?>
<li><input type="checkbox" name="del[]" value="<?php echo $del_name; ?>"><?php echo $del_name; ?></li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
<p class="notice">※左のチェックボックスを選択(複数可)して確認ボタンをクリックしてください</p>
<p class="vibtn"><input type="submit" value="削除確認"></p>
</form>
</div><!-- //id="fileBox"-->
</main>
<!-- footerインクルード -->
<?php require_once(dirname(__FILE__).'/footer.php'); ?>
input type="file"は特殊でデフォルトのボタンを使うのはビジュアル面で抵抗があったのでカスタマイズしました。
ファイルが選択されたらボタンがファイル名に変わって、エラーだったら上にメッセージ表示。
OKだったらtype="file"ブロックは非表示になって、type="submit"にすり替え。
見た目は一緒のボタンです。
ファイルアップが成功したらボタンの上にファイル名が表示して下のリストに追加といった仕様。
ただ、ファイル選択時はsubmitボタンは押されてないのでphpでの処理が難しい。
そこでjsのchangeイベントを活用。
ここは頭がこんがらがりました。phpとjsとcssのトリプル連携。
jQuery('#up').on('change',function(){ const upfile = jQuery('#up').get(0).files; console.log(upfile); const fileName = upfile[0].name; //file選択をsubmitにすり替え jQuery('#take').css('display','none'); jQuery('#send').css('display','block'); jQuery('#send input').val(fileName); });
ダウンロードチェックページ
ダウンロードのコードはどうしても分からなかったのでググって動いたものをコピペさせてもらいました。
それまではダウンロードできても開けられなかったり不具合続出でした。
ここのコードが一番難しい。
今の段階では理解できなかったのですが、そのうち自分でも組めるようになりたいです。
・download_file.php
//ダウンロードチェック
session_start();
session_regenerate_id(true);
if(isset($_SESSION['login']) === false){
header('Location: un_login.php');
exit();
}
function html_escape($word){
return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
}
$dowload_file = $_POST['dowl'];
$dowload_file = html_escape($dowload_file);
//var_dump($dowload_file);
//ダウンロードできなかったのでネットから拾ってきた
function download($pPath, $pMimeType = null){
//-- ファイルが読めない時はエラー(もっときちんと書いた方が良いが今回は割愛)
if (!is_readable($pPath)) { die($pPath); }
//-- Content-Typeとして送信するMIMEタイプ(第2引数を渡さない場合は自動判定) ※詳細は後述
$mimeType = (isset($pMimeType)) ? $pMimeType
: (new finfo(FILEINFO_MIME_TYPE))->file($pPath);
//-- 適切なMIMEタイプが得られない時は、未知のファイルを示すapplication/octet-streamとする
if (!preg_match('/\A\S+?\/\S+/', $mimeType)) {
$mimeType = 'application/octet-stream';
}
//-- Content-Type
header('Content-Type: ' . $mimeType);
//-- ウェブブラウザが独自にMIMEタイプを判断する処理を抑止する
header('X-Content-Type-Options: nosniff');
//-- ダウンロードファイルのサイズ
header('Content-Length: ' . filesize($pPath));
//-- ダウンロード時のファイル名
header('Content-Disposition: attachment; filename="' . basename($pPath) . '"');
//-- keep-aliveを無効にする
header('Connection: close');
//-- readfile()の前に出力バッファリングを無効化する ※詳細は後述
while (ob_get_level()) { ob_end_clean(); }
//-- 出力
readfile($pPath);
//-- 最後に終了させるのを忘れない
exit;
}
//選択されたファイルがあったらダウンロード、なかったらそのままリダイレクト
if(isset($_POST['dowl'])){
download('./up_file/'.$dowload_file);
header('Location: file_list.php');
} else {
header('Location: file_list.php');
}
削除確認、完了ページ
削除だけは誤って消してしまって後悔しないように、確認してからの動線にしました。
・delete_done.php
//ログインしていないとアクセスさせない
session_start();
session_regenerate_id(true);
if(isset($_SESSION['login']) === false){
header('Location: un_login.php');
exit();
}
function html_escape($word){
return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
}
$delete_file = '';
//POSTで渡されたファイルを削除
if(isset($_POST['check'])){
for($i = 0; $i < count($_POST['check']); $i++){
unlink('./up_file/'.html_escape($_POST['check'][$i]));
//削除ファイルli書出し
$delete_file .= '<li><i class="far fa-file"></i>'.html_escape($_POST['check'][$i]).'</li>';
}
}
?>
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>ファイル削除完了 | ファイル預かり処・マイ保管庫</title>
<!-- headerインクルード -->
<?php require_once(dirname(__FILE__).'/header.php'); ?>
<div id="wrapper">
<header>
<div id="titleVar">
<h1><i class="fas fa-circle"></i>ファイル預かり処 マイ保管庫</h1>
<p id="logout"><a href="logout.php">ログアウト</a></p>
</div>
<div id="topvew">My keep folder</div>
</header>
<main id="confiBox">
<h2 class="pageTitle">ファイル削除完了</h2>
<p class="confiText">以下のファイルを削除しました</p>
<ul>
<?php echo $delete_file; ?>
</ul>
<p id="toListpage"><a href="file_list.php">ファイル一覧ページへ</a></p>
</main>
<!-- footerインクルード -->
<?php require_once(dirname(__FILE__).'/footer.php'); ?>
完成したのであとは実際のサーバに上げて動作確認。
動いた時は大感動。
あれ?
でもアップできないファイルがある。
色々試して、どうやら日本語名のファイルはアップできないみたい。
XAMPP開発時では日本語のファイル名でも大丈夫だったんですけどね。
そういえば日本語とサーバの相性は良くないと昔から言われてました。
とりあえず注意書きに日本語NGと追加して応急対処。
preg_matchで条件設定した方がいいのかなと思ったりしています。
ひとまず、これで完成として使い込んでみようと思ってます。
お婆ちゃんのweb制作奮闘記でした。