CSS ホバーアニメーション
たまにはcssを...
完成版
https://codepen.io/mitsuru-hashimoto/pen/eYYaJKZ
テキトーにspanタグを用意します
wai
spanにcssをあてます
疑似要素 (Pseudo-elements) を用意します
span自体のpositionをrelativeに、
疑似要素(beforeのこと)のpositionをabsolute、left、topを0, height、widthを100%にすることで、
spanタグにぴったり被さります
// css span { color: #6495ED; font-size: 60px; border: 5px solid #6495ED; padding: 50px 100px; position: relative; } span:before { content: ''; position: absolute; left: 0; top: 0; background-color: #6495ED; height: 100%; width: 100%; }
span:beforeを移動させる
transform: translateX(-100%);を追加することで、width分だけ-100%(spanの左側に)移動します
// css span { color: #6495ED; font-size: 60px; border: 5px solid #6495ED; padding: 50px 100px; position: relative; } span:before { content: ''; position: absolute; left: 0; top: 0; background-color: #6495ED; height: 100%; width: 100%; transform: translateX(-100%); // これを追加 }
beforeがはみ出てみっともないので,span側のcssにoverflow:hiddenを追加してはみ出し部分を見えなくする
spanタグにホバーした時にbefore要素にアニメーションして欲しいので、下を追加
span:hover:before { transform: translateX(0); }
アニメーションが一瞬で切り替わってしまうのでtransition: all 1sを追加してアニメションを滑らかにする
span:before { content: ''; position: absolute; left: 0; top: 0; background-color: #6495ED; height: 100%; width: 100%; transform: translateX(-100%); transition: all 1s; // これを追加 }
文字列がbefore要素で見えなくなったので、ホバー時の文字列の色を変える
before要素がspanタグのz軸に置ける位置を後ろにする
span:before { content: ''; position: absolute; left: 0; top: 0; background-color: #6495ED; height: 100%; width: 100%; transform: translateX(-100%); transition: all 1s; z-index: -1; // これを追加 } span:hover { color: white; }
TypeScript (Constructor)
こういう差があるんだ。。。
constructorの引数でpublicとかprivateの修飾詞つけると、
わざわざ別に変数宣言しなくてもいいんだ
へぇ
// これだとこれだとtitleがないよと怒られる // class Category { // constructor(title: string) {} // getInfo(): void { // console.log(this.title) // } // } class Category1 { private title: string // ここでtitleを宣言しておくと大丈夫 constructor(title: string) {} getInfo(): void { console.log(this.title) } } class Category2 { // publicややprivateなど付けておくと勝手にマッピングしてくれてエラーが出ない constructor(private title: string) {} getInfo(): void { console.log(this.title) } }
TypeScript (Type Guards、Discriminated Unions)
TypeScriptいろいろできるなー
Type Guards
たとえばstring型の数字か,numberの数字を引数に取る想定した場合とかに有効かな
const argNumberOrString = (value: string | number): void => { value.toString() // ここはセーフ value.toFixed() // ここでvalueはstring型と見なされ、toFixedなんてstringにはないよとエラーになる // Type Guardsでそれぞれの型が合うように条件分岐させる if (typeof value === 'string') { value.toString() } if (typeof value === 'number') { value.toFixed() } }
Discriminated Unions
literal型のメンバを使用して、ユニオン型のメンバを特定するのに役立つ
今回はkindでDogかCatを判別できるようにする
>>|
// 文字列指定する
interface Dog {
kind: 'dog',
yelp: () => string
}
interface Cat {
kind: 'cat',
meow: () => string
}
type Pet = Dog | Cat; // Pet型はDogかCatのどちらか
const getVoice = (pet: Pet): string {
// Type Guard
switch (pet.kind) {
case 'dog':
return pet.yelp()
case 'cat':
return pet.meow()
default:
return 'hoge'
}
}
|
switch文で書くとなんとなくreduxのreducerみがある気がする
TypeScript (Intersection Types、 Mapped Types)
へぇと思ったので紹介
Interscetion Types
両方引き継ぐことができる
でorができるんだから、&も当然っちゃ当然か |
interface IHoge { hoge(): void } interface IFuga { fuga(): void } // Intersection Types type IHogeFuga = IHoge & IFuga let hogefuga: IHogeFuga = undefined;
Mapped Types
// 全てのプロパティをreadonlyにする type ReadOnly<T> = { readonly [k in keyof T]: T[k]; } // 全てのプロパティを任意項目にする type Optional<T> = { [k in keyof T]?: T[k]; } // 全てのプロパティをnull許容する type Nullable<T> = { [k in keyof T]: T[k] | null; } // テキトーなinterfaceを用意する interface ITodo { id: number; content: string; isCompleted: boolean } // ITodoに充てる type ReadOnlyTodo = ReadOnly<ITodo> type OptionalTodo = Optional<ITodo> type NullableTodo = Nullable<ITodo> // 全てのプロパティがreadonly const todo1: ReadOnlyTodo = { id: 1, // strictNullChecksががtrueならならnullを使えない content: 'content', isCompleted: false } // 全てのプロパティを任意項目だからこれでエラー出ない const todo2: OptionalTodo = {} // 全てのプロパティをnull許容にする const todo3: NullableTodo = { id: null, content: null, isCompleted: null }
2冊目がわかりやすいよ
1冊目は出版社がよくセールしてる印象ある
TypeScriptいろいろ(型、継承、Interface、Singleton)
整理整理
Interface 継承
interface IFather { fatherName: string // おとんの名前をstring型 } interface IMother { motherName: string // おかんの名前をstring型 } // IFatherとIMotherを継承するIChildrenを定義 interface IChildren extends IFather, IMother { name: string age?: number // ? は任意項目 } const child = <IChildren>{ fatherName: 'tetsu', motherName: 'yoshie', name: 'chie' // age は任意なので設定しなくてもよい }
関数にもinterfaceを
引数と返り値に型付けを
interface ICalc { (value: number): number; } const calcDouble: ICalc = (value: number) => value * 2
Singleton
class Person { private static _instance: Person; private constructor() { } private _name: string; static getInstance(): Person { if (!Person._instance) { Person._instance = new Person(); } return Person._instance } get name(): string { return this._name } set name(name: string) { this._name = name; } } const person = Person.getInstance(); console.log(person) person.name = 'wai' console.log(person.name)
継承の注意点
// IMyArrayを定義する interface IMyArray { // indexがnumberでその値がstring型 [index: number]: string; } // IMyArray型の配列を定義する const days: IMyArray = ["Mon", "Tue"] days.push("Wed") //IMyArrayにpushメソッドなんてないとエラーが起こる