- 投稿日:2019-08-16T17:18:11+09:00
Vue.jsでチェス盤を作ってみたら8行だった。
チェス盤はなぜ白黒なのか
あの違い互いの白黒盤のせいでちょっと苦戦した話です。
一応チェスを後々作る前提でボードを作ってみました。
今回のゴール
1.見た目的にチェス盤と認識できるものを作る
2.今後チェスを作る前提の構造になっていないとダメ†考察†
実際チェスを作るとなると必須となるのが、
64マスそれぞれに座標が備わっていること。つまりこういうこと。
[1-1, 1-2, 1-3, 1-4, 1-5, 1-6, 1-7, 1-8, 2-1, 2-2, 2-3, 2-4, 2-5, 2-6, 2-7, 2-8, 3-1, 3-2, 3-3, 3-4, 3-5, 3-6, 3-7, 3-8, 4-1, 4-2, 4-3, 4-4, 4-5, 4-6, 4-7, 4-8, 5-1, 5-2, 5-3, 5-4, 5-5, 5-6, 5-7, 5-8, 6-1, 6-2, 6-3, 6-4, 6-5, 6-6, 6-7, 6-8, 7-1, 7-2, 7-3, 7-4, 7-5, 7-6, 7-7, 7-8, 8-1, 8-2, 8-3, 8-4, 8-5, 8-6, 8-7, 8-8]X軸とY軸の数値を合わせてるような感じ。
この配列を作るだけであれば簡単。
let board = []; for(let x = 1; x < 9; x++) { for(let y = 1; y < 9; y++) { board.push(x + "-" + y) } }8×8のループを行えば一瞬でできてしまうので、
Vue.jsでレンダリングするとしても、v-for="n in 8"を二回やればいいだけ。将棋であればここで完成。
だがしかし、チェス盤となると少しやっかい。白黒白黒白黒白黒
ときて、
今度は
黒白黒白黒白黒白!
まあ冒頭でも言ってますが、
つまり、1行目と2行目だと、1列目の色が反転しているということです。えらいこっちゃ~~~となっていろいろ考えて
しばらくしてやっとこちらの文系エンジニアも気づきました。「奇数行と偶数行で出し分けすればいいんだ」
つまりはこういうこと。
<div class="board"> <div v-for="x in 8"> <div v-for="y in 8"> <div class="square-black" :id='`${x}-${y}`' v-if="(x + y) % 2 == 0"></div> <div class="square-white" :id='`${x}-${y}`' v-else></div> </div> </div> </div>おぉ~~~できた!
ちゃんとそれぞれidも1-1から8-8まで振れている。
そしてなによりコードがかなり短く収まった!!一応解説
8回ループを二回するまでは同じ、
そしてそこからは、一回目のループxと二回目のループyそれぞれの値でv-if使って出し分け。xの一回目とyの一回目であれば1と1になるので、
合計が2、偶数なので黒スタート。xの二回目とyの一回目であれば2と1になるので、
合計が3、奇数なので白スタート。最後に
座標もしっかり入っているので、
チェス作りの道も開けたといった感じですね。筆者はこういう閃きみたいなのが圧倒的に欠如している
文系エンジニアなので時間はかかったものの、
法則を見つけて何かをスッキリ書くのはよだれが出てくるぐらい好きです。いつになるかわからないですが、
次はチェスの動きの部分を投稿したいです。スタイルも含めたコードを載せておきます。
Board.vue<template> <div class="board"> <div v-for="x in 8"> <div v-for="y in 8"> <div class="square-black" :id='`${x}-${y}`' v-if="(x + y) % 2 == 0"></div> <div class="square-white" :id='`${x}-${y}`' v-else></div> </div> </div> </div> </template> <style scoped> .board { width: 640px; height: 640px; border: 4px solid black; } .square-black { width: 80px; height: 80px; background-color: black; float: left; } .square-white { width: 80px; height: 80px; background-color: white; float: left; } </style>
- 投稿日:2019-08-16T17:18:11+09:00
Vue.jsでチェス盤を作ってみたら7行だった。
チェス盤はなぜ白黒なのか
あの違い互いの白黒盤のせいでちょっと苦戦した話です。
一応チェスを後々作る前提でボードを作ってみました。
今回のゴール
1.見た目的にチェス盤と認識できるものを作る
2.今後チェスを作る前提の構造になっていないとダメ†考察†
実際チェスを作るとなると必須となるのが、
64マスそれぞれに座標が備わっていること。つまりこういうこと。
[1-1, 1-2, 1-3, 1-4, 1-5, 1-6, 1-7, 1-8, 2-1, 2-2, 2-3, 2-4, 2-5, 2-6, 2-7, 2-8, 3-1, 3-2, 3-3, 3-4, 3-5, 3-6, 3-7, 3-8, 4-1, 4-2, 4-3, 4-4, 4-5, 4-6, 4-7, 4-8, 5-1, 5-2, 5-3, 5-4, 5-5, 5-6, 5-7, 5-8, 6-1, 6-2, 6-3, 6-4, 6-5, 6-6, 6-7, 6-8, 7-1, 7-2, 7-3, 7-4, 7-5, 7-6, 7-7, 7-8, 8-1, 8-2, 8-3, 8-4, 8-5, 8-6, 8-7, 8-8]X軸とY軸の数値を合わせてるような感じ。
この配列を作るだけであれば簡単。
let board = []; for(let x = 1; x < 9; x++) { for(let y = 1; y < 9; y++) { board.push(x + "-" + y) } }8×8のループを行えば一瞬でできてしまうので、
Vue.jsでレンダリングするとしても、v-for="n in 8"を二回やればいいだけ。将棋であればここで完成。
だがしかし、チェス盤となると少しやっかい。白黒白黒白黒白黒
ときて、
今度は
黒白黒白黒白黒白!
まあ冒頭でも言ってますが、
つまり、1行目と2行目だと、1列目の色が反転しているということです。えらいこっちゃ~~~となっていろいろ考えて
しばらくしてやっとこちらの文系エンジニアも気づきました。「奇数行と偶数行で出し分けすればいいんだ」
つまりはこういうこと。
<div class="board"> <div v-for="x in 8"> <div v-for="y in 8"> <div v-bind:class="(x + y) % 2 == 0 ? 'square-black' : 'square-white'" :id='`${x}-${y}`' > </div> </div> </div> </div>おぉ~~~できた!
ちゃんとそれぞれidも1-1から8-8まで振れている。
そしてなによりコードがかなり短く収まった!!一応解説
8回ループを二回するまでは同じ、
そしてそこからは、一回目のループxと二回目のループyそれぞれの値でv-if使って出し分け。xの一回目とyの一回目であれば1と1になるので、
合計が2、偶数なので黒スタート。xの二回目とyの一回目であれば2と1になるので、
合計が3、奇数なので白スタート。最後に
座標もしっかり入っているので、
チェス作りの道も開けたといった感じですね。筆者はこういう閃きみたいなのが圧倒的に欠如している
文系エンジニアなので時間はかかったものの、
法則を見つけて何かをスッキリ書くのはよだれが出てくるぐらい好きです。いつになるかわからないですが、
次はチェスの動きの部分を投稿したいです。スタイルも含めたコードを載せておきます。
Board.vue<template> <div class="board"> <div v-for="x in 8"> <div v-for="y in 8"> <div v-bind:class="(x + y) % 2 == 0 ? 'square-black' : 'square-white'" :id='`${x}-${y}`' > </div> </div> </div> </div> </template> <style scoped> .board { width: 640px; height: 640px; border: 4px solid black; } .square-black { width: 80px; height: 80px; background-color: black; float: left; } .square-white { width: 80px; height: 80px; background-color: white; float: left; } </style>追記:
もともと、v-ifとv-else使ってdomを出し分けしようと書いていたのですが、v-bind:classを使えばDOMが一つにまとまると思い、修正しました。
なので、\8行から7行に変わりました/
そもそも、出し分けするとはいえ、全く同じidを両方に振っていたのもなんだが危なっかしいので、
classの切り替え処理のほうが正しい気がします。元のコード:
<template> <div class="board"> <div v-for="x in 8"> <div v-for="y in 8"> <div class="square-black" :id='`${x}-${y}`' v-if="(x + y) % 2 == 0"></div> <div class="square-white" :id='`${x}-${y}`' v-else></div> </div> </div> </div> </div> </template>
- 投稿日:2019-08-16T14:53:47+09:00
俺的CSSの便利なProperty・Value・Selector 50連発!
最近すごくHTMLやCSSを書いている気がするので、ここらでCSSのよく使うプロパティや知っていると便利なプロパティをまとめてみることにしました。早速行ってみましょう!
よく使うもの
1. ::before, ::after
これを指定した要素の子要素として挿入される疑似要素。子要素を持てない要素(img, inputなど)には指定不可能。
contentプロパティを指定しない限り挿入されない。なにも入れるcontentがない場合はcontent: ""を指定する。2. min-height, min-width
高さや幅の最小値を指定する。mainコンテナのように、必ずある大きさ以上の大きさが必要な要素に指定すると、コンテンツの大きさにかかわらず設定した大きさより小さくならない。
3. max-height, max-width
上の
min-系とは逆に、高さや幅の最大値を設定する。指定すると、コンテンツの大きさにかかわらず、設定した大きさより大きくならない。4. order
HTMLの要素の兄弟順をオーバーライドする。これを指定すると、強制的に兄弟要素の中でその順番になるように表示される。
nth-系には影響しない。5. visibility
display: noneと違って、表示したくないけれど領域は確保したいという場合に使える。6. z-index
要素の描画順を設定するプロパティ。
position: fixed;と使うことが多い。7. clip-path
要素の見かけの外形を設定するプロパティ。うまく使えばCSSだけでいろんな表現が可能に。
8. will-change
要素のCSSプロパティがアニメーションで変化することをあらかじめブラウザに知らせる。パフォーマンス爆上がり。
9. transform
要素を移動、回転、拡縮、変形させるプロパティ。ちょっと場所がずれるときとか、アニメーションで動かしたいときに便利。
10. :root
root疑似クラス。document.documentElementを指し示すセレクタ。カスタムプロパティと組み合わせると応用範囲は無限大。メディアクエリと組み合わせるとモバイルビュー判定にも使える。
@media screen and (max-width: 960px) { :root { --is-mobile: yes; } } @media screen and (min-width: 961px) { :root { --is-mobile: no; } }11. transform-origin
transformプロパティの基準になる点を指定するプロパティ。ローディング画面のスピナなどを作るときなど、意外と使える場面が多い。
12. position: relative
position: absoluteが親要素を基準とした位置取りにならない!?って思ったときは大概こいつの設定忘れが原因。これが設定された要素の子要素にposition: absoluteが指定された場合、これが設定された要素を基準とした位置取りになる。13. appearance: none
デフォルトの見た目をなくすプロパティ。input要素に独自のスタイルを当てたいときなど、これを設定するとうまくいくことが多い。
14. box-shadow
要素が落とす影を設定するプロパティ。背景が設定されていない要素につけると違和感マシマシ。そういうインラインなテキスト要素に影をつけたい場合は、
text-shadowプロパティを使うこと。15. background-clip
きれいなタイトル文字の修飾をしたいときに。ヘッディング要素の
background-imageプロパティに適当な画像を設定して、このプロパティの値をtextにすると、背景が文字の形で切り抜かれる。16. background-attachment: fixed
要素内のコンテンツが動いても、背景を動かしたくない場合に使う。サイトの背景に設定するといい感じになるかも。
17. border-radius
要素を角丸にできる。もはや説明不要。
18. :not
セレクタにマッチしない要素にマッチする。例えば、
:not(.not-select)というセレクタは、not-selectクラスを持たない要素にマッチする。19. :first-child, :last-child, :nth-child, :nth-last-child
指定された順番にある兄弟要素にマッチする疑似クラス。
20. :first-of-type, :last-of-type, :nth-of-type, nth-last-of-type
指定された順番にある同じタグ(spanどうし、divどうしなど)の兄弟要素にマッチする疑似クラス。
21. :required
required属性のあるformパーツにマッチする。
22. :invalid
入力された値が要求された形式に従っていないformパーツにマッチする。
23. outline
borderの外側に描画されるborderみたいなやつ。borderと違って、それ専用に場所が確保されない。
24. attr()
print画面でだけ
::after疑似要素にurlを表示したいときなど、CSSのプロパティに特定のHTML属性を設定したいときに使用する。25. user-select
ユーザーが要素を選択可能かどうかを設定する。spanにclickイベントを設定したときなど、選択されるのが鬱陶しかったり、要素を選択してほしくないときに使う。
26. pointer-events
要素のどこがマウスイベントをキャプチャするか指定するプロパティ。オーバーレイなど、ほかの要素より前に出るがマウスイベントをキャプチャしたくない要素には
noneを設定すると吉。27. cursor
要素の上に乗ったカーソルの表示の種類を設定する。ユーザビリティが上がるらしい。
28. :checked
チェックが入っているチェックボックスにマッチする。うまく活用するとHTML/CSSだけで開閉するメニューなどの2つの状態を持つUIが記述できる。
29. display: flex
要素をflexboxにする。子要素の数によって、自動でいい感じに配置を決めてくれる。すごく便利。ついつい多用しがち。
30. justify-content
要素の配置を決めるプロパティ。上の
display: flexと組み合わせて使うことが多い。31. flex-flow
flexboxで、要素を配置する向きを決める。
32. flex
flexboxの子要素に指定するプロパティ。flex-grow、flex-shrink、flex-basisの3つを一気に指定できる。flex-growは要素がコンテナより小さいときにどれくらい大きくするか、flex-shrinkは逆に要素がコンテナより大きいときにどれくらい小さくするか、flex-basisは要素がコンテナの中でどれくらいの初期サイズを持っているのかを指定する。
そこまで使うわけでもないけど知っていたら便利なもの
33. position: sticky
これを設定された要素が親要素の中でrelative + fixedのような振る舞いをするようになる。Qiitaのいいねボタンやストックボタンのスマホ版みたいな振る舞いがこれ(とtop, bottom, right, leftプロパティのどれか1つ以上)だけで記述可能。
34. text-indent
行頭字下げをするプロパティ。パラグラフの先頭で字下げしたいときに有効。
35. ::first-letter
ある要素の中で、最初の文字にマッチする疑似要素。パラグラフの最初の文字だけ大きくするような表現に使える。
36. ::select
ある要素の中で、現在選択されているものにマッチする疑似要素。選択部分の強調などに使える。
37. ::target
urlのターゲットになっている要素にマッチする。ページ内リンクで飛んだ先の要素を強調するのに使える。
38. perspective
transformと組み合わせて使う。遠近法をどの程度かけるか指定するプロパティ。
39. transform-style: preserve-3d
これを三次元の移動回転変形を指定したtransformプロパティを持つ要素の親に指定することで、3次元的な描写を可能にすることができる。
40. filter
要素に指定したSVGフィルタをかける。
::beforeに指定して背景をぼかしたり、グレイスケール化したり、いろいろな視覚効果を追加することができる。41. ::marker
::marker
リストのマーカーにマッチする疑似要素。
- ←これがリストのマーカー。
42. ::placeholder
formパーツ要素のplaceholderにマッチする。placeholderの色やフォントなどを変えたいときに便利。
43. :defined
任意のCustomElementにマッチする。
44. quotes
<q>~</q>のタグを使ったときに表示される引用符を制御できる。それ以外のタグの場合も、以下のようにして利用できる。blockquote { quotes: "「" "」"; } blockquote::before { content: open-quote; } blockquote::after { content: close-quote; }より正確な動作の説明としては「
open-quoteとclose-quoteの値を制御する」ということになる。45. text-overflow
文字がコンテナのサイズを超過したときの処理を設定する。
...のような記号で省略したり、それ以外の文字で省略したり、あるいはそれ以上を表示しなかったりするような表現が可能。46. writing-mode
文字を縦書きにするか横書きにするか設定できる。サイトの種類によっては多用することもあるかも。
47. text-orientation
writing-modeをvertical-rlまたはvertical-lrにしたときに、文字をどの向きで配置するか設定する。48. clear
浮動要素のまわりの固定要素の配置(回り込み)を指定する。浮動要素しか含まないような要素の高さを維持するために使うこともできる。
.float-only::after { content: ""; display: block; clear: both; }49. all
すべてのプロパティを一気に設定できる。親要素からすべてのスタイルを継承したいときや、逆に継承したくないとき、デフォルトの見た目にしたいときに使える。
50. touch-action
要素に対して可能なタッチアクションの種類を制限できる。たとえば、ズームしてほしくないとか、縦方向のスクロールを制限したいとかそういう場合に便利。Cookie Clickerのタッチ領域にこれを指定してほしいと何度思ったことか。
まとめ
CSS難しい……。MDNの解説ってプロパティごとに内容の質にけっこうばらつきが大きいんですね。
参考
Happy Hacking!
- 投稿日:2019-08-16T12:38:43+09:00
【CSS】改行コードを含む文字列をCSSだけで改行させる。(ばいばいBR)
- 投稿日:2019-08-16T06:00:03+09:00
【日記】DjangoでImageFieldを実装したり、object-fitで画像表示したりした。
Django公式チュートリアルで作るpollsアプリケーションの発展型のようなものを作っています。詳しくはまだないしょです。
今日は各投稿の詳細画面をある程度実装しました。デザインはまだ何もいじっていないので見た目カッコ悪いですが……。あとからやります。
ImageField
今日実装したのは画像を扱うフィールド、ImageFieldです。公式チュートリアルでは触れられておらず、ドキュメントでも詳しく触れられていなかったので困りました。ググったところ、Django BrothersのチュートリアルがImageFieldについて扱っていて、非常にわかりやすかったのでこれに沿って実装しました。
僕の場合、default値を設定したかったのですが、ファイルを指定するパスが良くわからずだいぶ四苦八苦しました。結果的にこうなりました。
models.pychoice_image = models.ImageField(upload_to='polls', default=os.path.join(BASE_DIR, '/polls/default_icon.jpg'))詳しくはDjango Brothersチュートリアルを読んでほしいのですが、settings.pyでMEDIA_ROOTを指定したところからのパスで良いようです。
settings.pyMEDIA_ROOT = os.path.join(BASE_DIR, 'media')つまり、ImageFieldのデフォルト画像のパスは以下のようになります。
/media/polls/default_icon.jpg
object-fit
画像を表示できたは良いものの、画像サイズがそのままなので表示が整いません。縦横比を維持しつつ正方形で表示したかったので調べてみたところ、CSSのobject-fitというものを使えばうまくいきそうです。
1行追加でOK!CSSだけで画像をトリミングできる「object-fit」プロパティー|Webクリエイターボックス
実際に書いたコードはこちら
/polls/static/polls/style.css.choice_image { width: 100px; height: 100px; object-fit: cover; }画像にはchoice_imageクラスを指定しました。
細かい話
スーパーリロードというものについて知りました。キャッシュを消してリロードできるので、CSSを変更したのに反映されない!ってときに使うといいです。
Django開発中にクロームでcssが反映されない場合の対処方法 - 知的好奇心
円グラフを表示したかったがうまくいかない
投票された割合を表示する手段として、円グラフを実装したいのですがこれがうまくいかなかったので持ち越しです。Chart.jsというJSライブラリを使おうと思ったのですが、Pythonのfor文とどのように共存させればよいかわからないのです。もしかしたらviews.pyで作成したほうが良いのかもしれないですね。
今後の課題です。がんばろう。


