40
1 © Takahashi Fumiki 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう! WP-D Fes #03

WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

  • Upload
    -

  • View
    4.174

  • Download
    1

Embed Size (px)

Citation preview

Page 1: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

1 © Takahashi Fumiki

2015年のサバイバル学習術

Web開発技術の税引後利益 を最大化しよう!

WP-D Fes #03

Page 2: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

2 © Takahashi Fumiki

高橋 文樹2001年、幻冬舎主催の文学賞を受賞し、大

学在学中に作家デビュー。その後、長い冬

の時代を過ごし、2007年に「自身の作品を

Webで発表する技術を身につける」を目標

にWeb業界に転職。

2010年に独立して株式会社破滅派を設立。趣味は家づくり。

Page 3: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

3 © Takahashi Fumiki

Gruntなるものをはじめた

タスクランナーで業務効率化

Page 4: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

4 © Takahashi Fumiki

なぜGrunt?

• Sassコンパイル, JS圧縮はCodekitで満足していた

• プラグインなどOSSを配布する以上、有償ツール

じゃない方がいいかなと思った

• 共同作業でもCodekit買わない人が多かった

Page 5: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

5 © Takahashi Fumiki

Page 6: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

Grunt終わってた

© Takahashi Fumiki6

http://lab.sonicmoov.com/markup/gulp-instead-of-grunt/

Page 7: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

7 © Takahashi Fumiki

その他の情報によると……• Gruntはかれこれ1年ぐらい新規開発が止まっている

らしい

• Gulpの方が簡潔に書けて、速度も多少早いらしい

• GulpはGoogleのWeb Starter Kitにも採用された

https://developers.google.com/web/starter-kit/

Page 8: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

8 © Takahashi Fumiki

こういうことはよくある

Page 9: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

9 © Takahashi Fumiki

損をしない方法があったのでは?

Page 10: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

10 © Takahashi Fumiki

そんなものはない

Page 11: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

11 © Takahashi Fumiki

収支決算

出資 資産

Grunt学習時間 Gruntの知識

Grunt固有の知識 Grunt終了のお知らせ

タスクランナーの知識

Gulp学習時間 Gulpの知識

Gulp学習時間 Gulp固有の知識

税引後利益 これを最大化しよう!

どんなツールも いつかなくなる

Page 12: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

A Story about FlashFlashにまつわる物語

© Takahashi Fumiki12

Page 13: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

13 © Takahashi Fumiki

2008年、Flashはすごかった (1)• はじめて就職した会社で、「コーダー」「デザイナー」と

「Flasher」の間には明確な給与の差があった

• FlashできないWebデザイナーの給料は額面30万超えないと言

われた

• LoftworkのサイトにFlash+CMS連携で1500万と書いてあった

Page 14: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

14 © Takahashi Fumiki

2008年、Flashはすごかった (2)• ブラウザへのインストール率も95%ぐらいで、もっとも普

及した実行環境だった

• JavascriptでFlashと同等の表現をするのは至難の業だった

• ActionScript 3.0が出た頃で、「まともなプログラミング言

語になった」と言われていた

Page 15: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

15 © Takahashi Fumiki

2008年、Flashはすごかった (3)• TextLayoutFrameworkというプロジェクトがすごかった

• AdobeならではInDesign並の組版(縦書き・フォント・

禁則処理・縦中横)

• 僕は小説家なので、Webで書籍と同じように小説を読め

るようにしたかった

Page 16: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

16 © Takahashi Fumiki

Flash累計学習時間

0

1500

3000

4500

6000

2007年 2008年 2009年 2010年 2011年 2012年 2013年

Page 17: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

2010年こんな感じに(写真参考)http://takahashifumiki.com/web/programing/774/

© Takahashi Fumiki17

Page 18: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

18 © Takahashi Fumiki

完成した結果• WordPressでコンテンツを入稿すると、Flashで縦書き表示。フォントもヒラギノ

明朝でアンチエイリアスも効いており、大変美しい。ページめくり。

• 超頑張ってルビ・自動縦中横・自動行頭下げも実現した。

• SEO対策もばっちり。Flashは一度書き出されたHTMLをXMLとして再解釈し、レ

ンダリングするからボットでも安心。

• コピペ対策もばっちりで、お気に入りの箇所をブックマークできた。

• ページ内検索で、検索ワードが作品内に何個登場するかも実現できた。

Page 19: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

本当にがんばった

© Takahashi Fumiki19

Page 20: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

20 © Takahashi Fumiki

ちょうどその頃……

だがしかし

Page 21: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

Steve JobsがFlashを名指しでDisるhttps://www.apple.com/hotnews/thoughts-on-flash/

© Takahashi Fumiki21

Page 22: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

AdobeはAirでFlashいけると主張http://help.adobe.com/ja_JP/air/build/WSfffb011ac560372f3cb56e2a12cc36970aa-8000.html

© Takahashi Fumiki22

Page 23: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

そうこうしているうちにWebブラウザがCSS3対応http://blog.antenna.co.jp/CSSPage/2012/08/koboepub3.html

© Takahashi Fumiki23

Page 24: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

Webフォントも高品質にhttp://fontplustips.com/item/27-logowebfont2.html

© Takahashi Fumiki24

Page 25: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

ここまで言われるようにhttp://readwrite.jp/archives/20117

© Takahashi Fumiki25

Page 26: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

26 © Takahashi Fumiki

もうFlash使わなくなった

2012年

Page 27: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

27 © Takahashi Fumiki

失ったもの• Flash Builder(2回ぐらいアップデートしたので9万ちょい?)

• Flash固有の知識に費やした学習時間

• Flashのライブラリについての知識

• MXMLなどのタグ名

• Font埋め込みに関する知識

Page 28: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

28 © Takahashi Fumiki

得たもの• 暗号化、フォント埋め込みなど、それまで普通にWebサイトを作っているだけでは必要がなかった知識

• 鬼の正規表現

• ライブラリを使うのではなく、作るとはどういうことか

• Nightly Buildを利用することにまつわる苦労。最先端は辛いな! いやー、つれーわ!

• フロントエンドとバックエンドの連携

• 非同期処理についての基本知識(フォント5M、ルビ書き出しのためのレンダリング規則)

• 文字コードに関する深い知識

• タレントを探す嗅覚(クリエイターズクリエイター)

Page 29: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

29 © Takahashi Fumiki

多くを失ったが

多くを得た

結論

Page 30: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

30 © Takahashi Fumiki

たとえば、正規表現public  static  function  tcy(xml:XML,  textToTcy:String):XML{          //すべてのノードにアクセス  

       for(var  idx:String  in  xml..*){                  //テキストノードにのみ処理を行う  

               if(xml..*[idx].nodeKind()  ==  "text"){                          var  replacedTcy:String  =  xml..*[idx].toString();                          //  FIXME:  とりあえず1~2文字の場合だけ変換  

                       if(replacedTcy.match(/^[a-­‐zA-­‐Z0-­‐9!?]{1,2}$/)){                                  replacedTcy  =  replacedTcy.replace(/([a-­‐zA-­‐Z0-­‐9!?]{1,2})/,  "<flow:tcy>$1</flow:tcy>");                          }else{                                  //中間を修正  

                               replacedTcy  =  replacedTcy.replace(/([^a-­‐zA-­‐Z0-­‐9,  .&!?'"  \-­‐])([a-­‐zA-­‐Z0-­‐9!?]{1,2})([^a-­‐zA-­‐Z0-­‐9!?,  .&'"  \-­‐])/g,"$1<flow:tcy>$2</flow:tcy>$3");                                  //FIXME:  一字挟んでtcyがあった場合(22~23など。行頭・行末はうまく行く)  

                               replacedTcy  =  replacedTcy.replace(/(<\/flow:tcy>[^a-­‐zA-­‐Z0-­‐9!?,  .&'"  \-­‐])([a-­‐zA-­‐Z0-­‐9!?]{1,2})([^a-­‐zA-­‐Z0-­‐9!?,  .&'"  \-­‐])/g,  "$1<flow:tcy>$2</flow:tcy>$3");                                  //先頭だけを修正  

                               replacedTcy  =  replacedTcy.replace(/(^[a-­‐zA-­‐Z0-­‐9!?]{1,2})([^a-­‐zA-­‐Z0-­‐9,  .&!?'"])/,"<flow:tcy>$1</flow:tcy>$2");                                  //最後だけを修正  

                               replacedTcy  =  replacedTcy.replace(/([^a-­‐zA-­‐Z0-­‐9,  .&!?'"])([a-­‐zA-­‐Z0-­‐9!?]{1,2})$/,"$1<flow:tcy>$2</flow:tcy>");                          }                          //横に寝てしまう文字を起こす  

                       //参考情報  http://forums.adobe.com/thread/646184?tstart=0  

                       //FIXME:  UTF-­‐8でEast  Asian  Widthがambiguousであるかどうかを知るにはどうしたら?  

                       //tcyが連続になっていると横につながってしまうので、spanに修正  

                       var  regStr:String  =  "▲△▼▽☆★*①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅨⅩⅰⅱⅲⅳⅴⅵⅶⅷαβγΩ‰

℃Å♪♩♫♬";  

                       if(textToTcy  !=  "")                                  regStr  +=  textToTcy;                          var  reg:RegExp  =  new  RegExp("(["  +  regStr  +  "])",  "g");                          replacedTcy  =  replacedTcy.replace(reg,"<flow:span  textRotation=\"rotate270\">$1</flow:span>");                          replacedTcy  =  replacedTcy.replace(/(°F)/g,  "<flow:span  textRotation=\"rotate270\">$1</flow:span>");                          //元のノードに入れ直す  

                       xml..*[idx]  =  replacedTcy;                  }          }          return  new  XML(xml.toXMLString().replace(/&lt;(\/?)flow:([^&]*?)&gt;/g,"<$1flow:$2>"));  }

Page 31: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

31 © Takahashi Fumiki

たとえば、暗号化package  com.hametuha.cypher  {                    import  flash.utils.ByteArray;                    import  com.hurlant.crypto.symmetric.*;          import  com.hurlant.crypto.prng.Random;          import  com.hurlant.crypto.Crypto;          import  com.hurlant.crypto.hash.*;          import  com.hurlant.util.Hex;          import  com.hurlant.util.Base64;  

       public  class  Crypto          {                  /**                    *  暗号を解読して返す  

                 *  @param  data  ByteArray                    *  @return  String                    */                  public  static  function  decrypt(data:ByteArray,  pswd:String):String  {                          var  pad:IPad  =  new  NullPad();                          var  cipher:ICipher  =  com.hurlant.crypto.Crypto.getCipher("blowfish-­‐ecb",Hex.toArray(Hex.fromString(pswd)),pad);                          pad.setBlockSize(cipher.getBlockSize());                          if  (cipher  is  IVMode)  {                                  var  ivmode:IVMode  =  cipher  as  IVMode;                                  ivmode.IV  =  Hex.toArray("");                          }                          cipher.decrypt(data);                          data.position  =  0;                          return  data.readMultiByte(data.length,  "utf-­‐8");                  }          }  }

Page 32: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

32 © Takahashi Fumiki

たとえば、アニメーションpackage  com.hametuha.utils.Math  {          import  flash.geom.Point;  

       public  class  Dimension          {                  public  function  Dimension()                  {                  }                                    /**                    *  内容物が縦横比を保ったままコンテナの中に収まるようサイズを取得する  

                 *  @param  content  内容物の幅と高さ  

                 *  @param  container  コンテナの幅と高さ  

                 *  @return  Point 新しい内容物の幅と高さ  

                 */                  public  static  function  rectangleMaxLimit(content:Point,  container:Point):Point                  {                          var  adjustedContent:Point  =  new  Point();                          //内容物の方が縦長の場合、高さで制限する  

                       if(isHigher(content,  container)){                                  if(content.y  >  container.y){                                          adjustedContent.y  =  container.y;                                          adjustedContent.x  =  content.x  /  content.y  *  container.y;                                  }else{                                          adjustedContent.x  =  content.x;                                          adjustedContent.y  =  content.y;                                  }                          }                          //内容物の方が横長の場合、幅で制限する          

                       else{                                  if(content.x  >  container.x){                                          adjustedContent.x  =  container.x;                                          adjustedContent.y  =  content.y  /  content.x  *  container.x;                                  }else{                                          adjustedContent.y  =  content.y;                                          adjustedContent.x  =  content.x;                                  }                          }                          return  adjustedContent;                  }                                    /**                    *  オブジェクトがどんな形をしているかを返す  

                 *  @param  content  形を知りたいオブジェクト  

                 *  @return  String  "square",  "high",  "broad"のいずれか  

                 */                  public  static  function  getShape(content:Point):String                  {                          var  shape:String;                          if(content.x  ==  content.y)                                  shape  =  "square";                          else  if(content.x  <  content.y)                                  shape  =  "high";                          else                                  shape  =  "broad";                          return  shape;                  }                                    /**                    *  2つのオブジェクトを比較して、1つ目のオブジェクトの方が縦長だったらtrue  

                 *  @param  sub  比較したいオブジェクト  

                 *  @param  obj  比較対象のオブジェクト  

                 *  @return  Boolean                    */                  private  static  function  isHigher(sub:Point,  obj:Point):Boolean                  {                          if(sub.y  /  sub.x  >  obj.y  /  obj.x)                                  return  true;                          else                                  return  false;                  }          }  }

package  com.hametuha.book.animation  {          import  com.hametuha.book.events.PagenatorEvent;                    import  flash.display.Sprite;          import  flash.events.Event;          import  flash.events.EventDispatcher;          import  flash.events.IEventDispatcher;          import  flash.events.TimerEvent;          import  flash.geom.Point;          import  flash.utils.Timer;                    public  class  PagenatorFlip  extends  EventDispatcher          {                                    private  var  originalPoint:Point  =  new  Point(0,0);                  private  var  leftPoint:Point  =  new  Point(-­‐100,0);                  private  var  rightPoint:Point  =  new  Point(100,  0);                                    private  var  accel:Number  =  1.5;                  private  var  timer:Timer;                  private  var  interval:int  =  33;                                    private  var  vanishSpeed:Number;                  private  var  showSpeed:Number;                  private  var  buffer:Number  =  5;                                    private  var  from:Sprite;                  private  var  to:Sprite;                  private  var  tategaki:Boolean;                  private  var  showPoint:Point;                  private  var  vanishPoint:Point;                                    public  function  next(_from:Sprite,  _to:Sprite,  _tategaki:Boolean):void                  {                          from  =  _from;                          to  =  _to;                          tategaki  =  _tategaki;                                                    //消失点と表示点を設定  

                       showPoint  =  (tategaki)  ?  leftPoint  :  rightPoint;                          vanishPoint  =  (tategaki)  ?  rightPoint  :  leftPoint;                                                    pageMove();                  }                                    public  function  previous(_from:Sprite,  _to:Sprite,  _tategaki:Boolean):void                  {                          from  =  _from;                          to  =  _to;                          tategaki  =  _tategaki;                                                    //消失点と表示点を設定  

                       showPoint  =  (tategaki)  ?  rightPoint  :  leftPoint;                          vanishPoint  =  (tategaki)  ?  leftPoint  :  rightPoint;                          pageMove();                  }                                    private  function  pageMove():void                  {                          //表示設定  

                       from.alpha  =  1;                          to.alpha  =  0;                          to.visible  =  from.visible  =  true;                          setPoint(from,  originalPoint);                          setPoint(to,  showPoint);                                                    //スピードの設定  

                       vanishSpeed  =  (vanishPoint.x  -­‐  originalPoint.x)  /  10;                                                    timer  =  new  Timer(interval);                          timer.addEventListener(TimerEvent.TIMER,vanishHandler);                          timer.start();                          dispatchEvent(new  Event(PagenatorEvent.PAGENATION_START));                  }                                    private  function  vanishHandler(event:TimerEvent):void                  {                          //アニメーションが終了していたら  

                       if(isAnimationFinish(from,  vanishPoint,  vanishSpeed)){                                  //表示を元に戻す  

                               from.visible  =  false;                                  from.alpha  =  0;                                  setPoint(from,  originalPoint);                                                                    //速度を設定  

                               showSpeed  =  vanishSpeed;                                                                    //リスナーを削除  

                               timer.removeEventListener(TimerEvent.TIMER,vanishHandler);                                  timer.addEventListener(TimerEvent.TIMER,showHandler);                          }                          //アニメーションを実行  

                       else{                                  vanishSpeed  *=  accel;                                  from.x  +=  vanishSpeed;                                  from.alpha  /=  accel;                                  dispatchEvent(new  Event(PagenatorEvent.PAGENATION_EXECUTING));                          }                  }                                    private  function  showHandler(event:TimerEvent):void                  {                          //アニメーションが終了していたら、イベントを発行  

                       if(isAnimationFinish(to,  originalPoint,  showSpeed)){                                  //表示を元に戻す  

                               to.visible  =  true;                                  to.alpha  =  1;                                  setPoint(to,  originalPoint);                                  //リスナーを削除  

                               timer.removeEventListener(TimerEvent.TIMER,  showHandler);                                  timer.stop();                                  timer  =  null;                                  dispatchEvent(new  Event(PagenatorEvent.PAGENATION_ENDS));                          }                          //アニメーションを実行  

                       else{                                  showSpeed  /=  accel;                                  to.x  +=  showSpeed;                                  if(to.alpha  ==  0)                                          to.alpha  +=  .2;                                  else  

Page 33: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

33 © Takahashi Fumiki

たとえば、目標とするクリエイターの発見"新藤愛大(Yoshihiro Shindo)――19

歳という若さでありながら、国内でも屈

指のActionScripterとして活躍する彼は、

フリーランスとしてFlash/ActionScript

にその身をささげている。"

http://www.itmedia.co.jp/enterprise/

articles/0805/12/news007.html

Page 34: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

34 © Takahashi Fumiki

収支決算

出資 資産

flash学習時間 flashの知識

flash固有の知識 flash終了のお知らせ

GUI設計の知識

Xの学習時間 Xに固有の知識

税引後利益 ものすごくたくさんの

知識=資産

Xが何かはまだ わからない

Page 35: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

35 © Takahashi Fumiki

スキル習得の秘訣• 実戦投入する

• 情報の荒野まで邁進する

• 学習曲線の坂を登ることを厭わない

Page 36: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

36 © Takahashi Fumiki

1. 実戦投入それとも 

お前何十年も修行して

達人にでもなるのを待ってから

戦場に出るつもりか?

気の長なげェ話だな

ベルセルク 第24巻

Page 37: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

37 © Takahashi Fumiki

2. 情報の荒野まで邁進する

https://forums.adobe.com/thread/646184

Page 38: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

38 © Takahashi Fumiki

3. 学習曲線の坂を登ることを厭わない

せめてこれぐらいまでは やらないと成果はでない

Page 39: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

39 © Takahashi Fumiki

上り終えた梯子は

捨て去られねばならないルートヴィヒ・ウィトゲンシュタイン『論理哲学論考』より

Page 40: WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!

40 © Takahashi Fumiki

なにかすごいものを作ろう!

終わりに