20200310のHTMLに関する記事は16件です。

TSfCM1日目_プログラミング学習初日の初日

はじめに

2020年3月7日からプログラミングを習い始めました。
 Tech Scool for Change Makers
 https://gs4good.tokyo/
というところに半年間通って勉強します。

html,JavaScript,Pythonなど学ぶ予定です。
プログラミングは全くの初心者です。
Pythonがprintと書くことだけは知っていました。

ここでは自分の復習のため、あとQiita投稿に慣れるため
TSfCMの授業メモと学びを書いていきたいと思います。

3/7の教科書
https://qiita.com/njn0te/private/4523e08aa93672e4dda5?fbclid=IwAR0gfUWGfZ2WIMlyTY0oKXTa0KFnYCpgKJ05q0exVqI01DNt5orguhRGkG4

OSはWindows10

登場人物など

ツール

スクリプトを書く → GAS(グーグル・アップス・スクリプト)
プログラミングを書く場所(エディター) → Visual Studio Code

スクリプトの連携先 → LINE Nortify

マークアップ式メモ帳 → Stack Edit

言語

JavaScript
html

Node.js = サーバサイドJavaScript

デプロイ方法

GAS
now

そもそも

そもそもデプロイとは

"ソフトウェア開発の工程のうち、開発した機能やサービスを利用できる状態にする作業を指す語として用いられています。"
https://www.weblio.jp/content/%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4
weblio辞書より

JSONとは

ZEIT now

https://dev.classmethod.jp/server-side/serverless/zero-configuration-zeit-now/
"一言でいうと、シンプルで簡単にそして高速なデプロイを実現するPaaSです。
極端な話をすると、nowと打つだけでデプロイが完了するくらいに簡単です。
他のPaaSと同様に、Node.js、Python、Goといった様々な言語が使用できフロントエンド、バックエンドのデプロイが可能です。
またデプロイ時に固有のURLが発行され、HTTPSのアクセスが可能です。"

やったこと①

GASを使ってLINEと連携させる!

体験学習のときの復習。天気APIを取得してLINEで通知

応用編:Slackと連携させる

やったこと②

nowのインストール

nowとは

https://dev.classmethod.jp/server-side/serverless/zero-configuration-zeit-now
一言でいうと、シンプルで簡単にそして高速なデプロイを実現するPaaSです。
極端な話をすると、nowと打つだけでデプロイが完了するくらいに簡単です。

他のPaaSと同様に、Node.js、Python、Goといった様々な言語が使用できフロントエンド、バックエンドのデプロイが可能です。
またデプロイ時に固有のURLが発行され、HTTPSのアクセスが可能です。

インストール方法

1 .Visual Studio Code?のTerminaiにて下記実行

$ npm install -g now
$ yarn global add now
$ now login
$ now

し・か・し、npmが使えなかったため下記参考に

2.Node.jsのインストール

https://qiita.com/taiponrock/items/9001ae194571feb63a5e

3.yarnもインストール

4.ZEITサインアップ

"Production: https://**********.now.sh
と出ていれば成功です。URLをブラウザで開けるか確認してみてください。そして、開けていたら、Twitterで、「初めてのデプロイ #駆け出しエンジニア #TSfCM #初日」などと呟いてみましょう!"
↑ここまではできてつぶやいてもみたけど

次のGithubでコード更新できなかった

やったこと③

Githubへコードを上げる

gitのインストール
 https://gitforwindows.org/

ここでも上げれたように見えて、実態ファイルがなかった

先生にがんばっていただいてVSコードのterminalでいろいろ
そのhistory
1 git init
2 git add .
3 git commit -m "first commit"
4 git remote add origin https://github.com/honasa21/tsfcm_01.git
5 git push -u origin master
6 git init
7 git commit -m "second commit"
8 git add.
9 git add .
10 git push -u origin master
11 git init
12 git add .
13 git commit -m "first"
14 git push -u origin master
15 git remote add origin https://github.com/honasa21/firstGit.git
16 git push -u origin master
17 history
18 now

nowはVSコードからだとエラーになるのでcmdから実行
 C:\Users\”※姓名”\Desktop\DAY1_20200307の階層

知ったこと

HTML書き方

CSS

JavaScript

デプロイの仕方

プログレッシブ・エンハンスメント

重要度
 html > css > JavaScript

なぜ??
https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B7%E3%83%96%E3%82%A8%E3%83%B3%E3%83%8F%E3%83%B3%E3%82%B9%E3%83%A1%E3%83%B3%E3%83%88
"プログレッシブエンハンスメントは、核となるコンテンツを最重要視するウェブデザイン戦略である。
この戦略では、エンドユーザーのブラウザーやインターネット接続に合わせて、プレゼンテーション面や機能面で微妙に異なる内容や技術的に困難な内容をコンテンツに漸次追加していく。
この戦略の利点として挙げられるのは、すべてのユーザーが任意のブラウザーまたはインターネット接続を用いてウェブページの基本的なコンテンツと機能性にアクセスできることと、
より高度なブラウザーソフトウェアまたはより広帯域の接続を有するユーザーには
同じページの拡張バージョンを提供できることである。"

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Firefoxを改造してみようハンズオン

Firefoxの改造を通してコントリビューター(特にN高生)を増やそうという記事です。

今回の改造ではFirefoxに隠しコマンドを追加します。HTMLとJavaScriptを使うので、N予備校のプログラミング入門コースを終えている人が対象です。

何か分からない事があれば、僕にSlack(圧倒的初心者の極み)かTwitter(u7693)で聞いてください。

とりあえずビルドしてみる

改造する前にFirefoxをビルドできるか確認します。
OSによって変わってきますが、大まかな流れは以下の通りです。詳細はBuilding Firefox - Mozilla | MDNを見てください。

# ソースコードをとってくる
$ hg clone https://hg.mozilla.org/mozilla-central/
$ cd mozilla-central

# 依存関係のインストール
$ ./mach bootstrap

# ビルド
$ ./mach build

# 動かす
$ ./mach run

今回はC、C++、Rustのコードを変更しないので、Artifact buildsを設定することでビルド時間が短縮されます。

目標の確認

今回作るのはAboutダイアログでコナミコマンドを実行するとアラートが表示されるという機能です。
下の画像をクリックするとYouTubeで完成品の動画を視聴できます。

完成品の動画

改造する

Aboutダイアログのソースコードを探す

まずはAboutダイアログのソースコードを見つけましょう。

見つける方法は色々あると思いますが、今回はダイアログ内の文字列を使って見つけます。Firefoxで使われている文字列の中でAboutダイアログでしか使われていないものを検索し、該当のソースコードを見つけます。

Aboutダイアログの画面

例えば上の画像にもある「参加しませんか?」という文字列で検索してみましょう。先ほど取得したリポジトリやソースコード閲覧ツール『Mozilla DXR』を使って検索してみてください。おそらく見つからないでしょう。

文字列を使って検索するにはコツが必要です。
「参加しませんか?」という文字列は日本語です。Firefoxは多言語対応なので他にも様々な言語がありますが、それらは全て別のリポジトリで管理されています。皆さんが先ほど取得したリポジトリはFirefox自体のリポジトリ『mozilla-central』で、これには英語版だけが管理されています。
よって文字列を使って検索する場合は、英語で検索するか翻訳したテキストを管理するリポジトリ『l10n-central』を検索する必要があります。

先ほど紹介したMozilla DXRというツールはMozillaの様々なリポジトリを閲覧でき、もちろんl10nのリポジトリも閲覧できます。
Switch Treeからl10n-centralを選択してリポジトリを切り替えてください。

Mozilla DXRの画面

ここで「参加しませんか?」という文字列を検索してみましょう。

"参加しませんか?"の検索結果

出てきましたね。どうやら「参加しませんか?」という文字列はhelpusという文字列の一部だったようです。

このhelpusというのはl10nデータを指定するためのIDです。
今度はmozilla-centralhelpusを検索してみましょう。

"helpus"の検索結果

Aboutダイアログのソースコードとl10nの英語データが出てきました。
これでAboutダイアログのソースコードはaboutDialog.xhtmlだと分かりました。

念のためにaboutDialog.xhtmlを変更して確認してみましょう。
helpusを含むdescriptionタグを削除してビルドした後、Aboutダイアログから消えるか確かめてみてください。

"helpus"削除後のAboutダイアログ

ちゃんと消えていますね!!

コナミコマンドを実装してみる

Aboutダイアログにコナミコマンドを実装してみましょう。

aboutDialog.xhtmlを読んでいくとJavaScriptやCSSのファイルを読み込んでいるのが分かりますが、パスがよく分かりません。例えばchrome://browser/content/aboutDialog.jsというURLはソースコードではどのファイルなのでしょうか。

このURLを定義しているファイルは場合によりますが、aboutDialog.jsの場合はbrowser/base/jar.mnに定義されています。
jar.mnJAR Manifestsのことでchrome://で始まるファイルを登録するのに使います。詳しくはJAR Manifests - Mozilla Source Tree Docsを見てください。
これでaboutDialog.jsbrowser/base/content/aboutDialog.jsにある事がわかりました。

ではaboutDialog.jsにコナミコマンドを実装していきましょう。コナミコマンドの実装については詳しく書きませんが、patchファイルを貼っておきます。

Gist: u7693/Firefox_KonamiCode.patch

diff --git a/browser/base/content/aboutDialog.js b/browser/base/content/aboutDialog.js
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -12,6 +12,21 @@ var { AppConstants } = ChromeUtils.impor
   "resource://gre/modules/AppConstants.jsm"
 );

+const konamiCode = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
+let konamiCodePos = 0;
+
+document.addEventListener("keydown", function(event) {
+  if (event.keyCode == konamiCode[konamiCodePos]) {
+    konamiCodePos++;
+    if (konamiCodePos == konamiCode.length) {
+      alert("Firefoxが強化されました");
+      konamiCodePos = 0;
+    }
+  } else {
+    konamiCodePos = 0;
+  }
+});
+
 async function init(aEvent) {
   if (aEvent.target != document) {
     return;

ビルドして実行してみましょう。

Firefox_KonamiCode

無事コナミコマンドが実装できました!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

よく使うけどちょっとニッチなcss

よく使うけど、いつもググってるので、まとめました。

3番目のみ

style.scss
li:nth-child(3){
  margin-bottom: 20px;
}

2の倍数のみ

style.scss
:nth-child(2n)

奇数

style.scss
:nth-child(odd)
:nth-child(2n+1)

偶数

style.scss
:nth-child(even)
:nth-child(2n)

最後以外

style.scss
li:not(:last-child) {
    margin-bottom: 20px;
}

最初と最後のみ

style.scss
.wrap > li:first-of-type,
.wrap > li:last-of-type {
   margin-bottom: 20px;
}

最初と最後以外

style.scss
.wrap > li:nth-child(n+2):nth-last-child(n+2)  {
   margin-bottom: 20px;
}

最後の要素以外に擬似要素

style.scss
div > span:not(:last-child):after{
  content:",";
}

pタグの直前後にulがある時のみ適応(隣接関係)

style.scss
p + ul {
  margin-top: 50px;
}

pタグの直後にある要素がulタグじゃなかった場合はstyleが指定されない

親要素の直接の子要素飲みに適応(親子関係)

style.scss
p > ul {
  margin-top: 50px;
}

.main と .textどっちのclassも持ってる要素を指定

style.scss
.main {
 &.text {
   margin-top: 50px;
 }
}

単純にclass名の追加→.main_textを指定

style.scss
.main {
 &_text {
   margin-top: 50px;
 }
}

target="_blank"のついた要素にstyleを指定

style.scss
.button a[target="_blank"]::after {

}

ちなみに、タグに「target=”_blank”」を付与する場合「rel=”noopener”」を付けた方がいいらしい。

classを持ってないpタグを指定

style.scss
 p:not([class]) {
}

divタグ配下の全ての要素にstyleを適応

style.scss
 div * {
 margin: 10px;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Django】axiosを使って自作Like機能を作ってみた

はじめに

今回はDjangoで作ったWebサイトにaxiosを使っていいね機能が作れないかと調べてみました。
案の定、Ajaxを使うか画面リロード付きいいね機能の作り方しかなかったので、参考サイトを見ながらaxiosでいいね機能を作ってみました。

参考サイト

いいね機能を実装したサイトのチュートリアルサイト

https://tutorial.djangogirls.org/ja/

いいね機能参考

https://jyouj.hatenablog.com/entry/2018/07/22/232911

本題

記事の順序に従って実装していきます。
この機能が欲しい人はそこそこコードを読めると信じているので簡単な説明は省きました。

Model.py

PostクラスなどはDjango Girls Tutorialのモデルを参照しています。

from django.db import models
from django.conf import settings
from django.utils import timezone
from django.contrib.auth.models import User   #追加


class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    text = models.TextField()
    created_at = models.DateTimeField(default=timezone.now)
    published_date = models.DateTimeField(blank=True, null=True)
    like_num = models.IntegerField(default=0)  #追加

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title

以下コードがいいね機能モデル ↓追加
class Like(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='like_user')
    post = models.ForeignKey(Post, on_delete=models.CASCADE)

View.py

今回はクラスベースで書いていますので、関数ベースで作りたい方は工夫してください
#like #unlikeのJsonResponseの引数に関しては渡したいJsonデータを設定してください

class Like_Detail(View):
    def get(self, request, pk, *args, **kwargs):
        post = Post.objects.get(id=pk)
        is_like = Like.objects.filter(user=self.request.user).filter(post=post).count()
        # unlike
        if is_like > 0:
            liking = Like.objects.get(post__id=pk, user=self.request.user)
            liking.delete()
            post.like_num -= 1
            post.save()
            post = get_object_or_404(Post, pk=pk)
            json = {'like_value': post.like_num}     #ここのJsonデータに関してはご自由に
            return JsonResponse(json)
        # like
        post.like_num += 1
        post.save()
        like = Like()
        like.user = self.request.user
        like.post = post
        like.save()
        post = get_object_or_404(Post, pk=pk)
        json = {'like_value': post.like_num}         #ここのJsonデータに関してはご自由に
        return JsonResponse(json)

URL.py


from django.urls import path
from . import views
from .views import Like_Detail # View.pyで設定したクラス名をインポートさせてください

app_name = 'application'    #アプリケーション名で合わせてください
urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
    path('post/new/', views.post_new, name='post_new'),
    path('post/<int:pk>/edit/', views.post_edit, name='post_edit'),
    path('post/<int:pk>/like/',Like_Detail.as_view(), name='get'),   #追加
]

POST_Detail.html

最後に一番重要なHTML内のJavaScript処理について説明します。

< 記事サイトに飛んだ時の処理の流れです >

1.記事詳細ページに飛んだClientユーザーの情報をView.pyに渡す様に命令をします。
2.Javascript側にView.py側から渡されたClientユーザーがいいねしているか、していないかと記事の総合いいね数の情報を受け取ります。
3.もし、記事に対してユーザーがいいねをしていない場合は<input>タグのclassにunlikeタグを追加します。(いいねしている場合はlikeを追加させる処理が書かれています。)

< いいねボタンが押された際の処理の流れです >

1.いいねボタンを押すとaxiosを利用して画面リロードなしてリクエストを送ります。
2.View.py側でユーザーの記事のいいね処理を行います。
3.HTML側ではJavascriptが押されたら数値を変更するので毎回View.py側からデータを受け取る必要がなくなることになります

{% extends 'application/base.html' %}

{% block content %}
    <div class="post">
        {% if post.published_date %}
            <div class="date">
                {{ post.published_date }}
            </div>
        {% endif %}
        {% if user.is_authenticated %}
            <a class="btn btn-default" href="{% url 'application:post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
            <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
            <input type="button" value="Check" onclick="like()" id="like-data"> いいね<span id="like-count">{{ post.like_num }}</span>
            <script>
                var likeinfo = {{ is_like }};
                var likecount = {{ post.like_num }};
                window.onload = function () {
                    if (likeinfo > 0){
                        document.getElementById("like-data").classList.add("unlike");
                    }else{
                        document.getElementById("like-data").classList.add("like");
                    }
                };
                var like = function () {
                    const response = axios.get('/post/{{ post.pk }}/like/');
                    console.log(response);
                    console.log( document.getElementById('like-count').innerText);
                    if (likeinfo > 0){
                        likeinfo = likeinfo - 1;
                        likecount = likecount - 1;
                        document.getElementById('like-count').innerText=likecount;
                    }else{
                        likeinfo = likeinfo + 1;
                        likecount = likecount + 1;
                        document.getElementById('like-count').innerText=likecount;
                    }
                        document.getElementById("like-data").classList.toggle("unlike");
                        document.getElementById("like-data").classList.toggle("like");
                }
            </script>
        {% endif %}
        <h2>{{ post.title }}</h2>
        <p>{{ post.text|linebreaksbr }}</p>
    </div>
{% endblock %}

補足 CSS

<input>タグのclassにlikeunlikeをタグで付け替える意味はいいねしているか、してないかでCSSのデザインを変更する設定をしているからです。
.unlike {
    color:red;
}
.like {
    color: black;
}

最後に

自分用に書いてはいますが、
参考になりましたらいいね?よろしくお願いします。
色んな人に見ていただければ次回allauthに関しても書こうかなと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【CSS】CSS で作ったハンコのようなもの

世が令和になっても歴史は繰り返されます。
[CSS] CSSで作る印影(印鑑、ハンコ、判子)っぽいもの と同じような経緯から CSS ハンコを作成することになりました。

やはり要望は多くはないと思いますが上記記事とは別パターンでの CSS ハンコの作成方法ということで記しておきます。

See the Pen eYNyrEd by ari3der (@ari3der) on CodePen.

特に特殊なことはしていないと思いますがせめてハンコの大きさに応じて font-size がいい感じになるようにだけ調整しました。

hanko.html
<div class="hanko">
  <span>営業1課</span>
  <hr noshade>
  <span>2020/03/01</span>
  <hr noshade>
  <span>たかし</span>
</div>
hanko.scss
$hanko-size: 100px;
.hanko {
  font-size: 16px * ($hanko-size / 100px);
  border:3px * ($hanko-size / 100px) double #f00;
  border-radius: 50%;
  color: #f00;
  width: $hanko-size;
  height: $hanko-size;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  hr {
    width: 100%;
    margin: 0;
    border-color: #f00;
  }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

行数の指定、その行数を超えた場合に非表示にする(cssのみ)

cssだけで行数の指定をするやり方
①2行以上の時は文字を非表示にする
②2行以上の時は二行目の最後に三点リーダーをつける

※jsでもできます。
②のやり方だとIE11非対応です。(多分)

index.html
<p class="line_wrap">テキストの文章を2行を超えたら表示したく無いです。且つ、レスポンシブ対応にしたいです。</p>

①2行以上の時は文字を非表示にする

style.css
.line_wrap {
  overflow: hidden;
  height: 3.6em /* 2em(行)x line-heightの1.8 */
  font-size: 16px;
  line-height: 1.8;
}

表示したい行数 * line-height
をheight(単位em)にしてoverflow:hiddenするだけ。
3天リーダーはありませんが、2行以上の場合は文字が表示されません。
スクリーンショット 2020-03-10 17.42.29.png

②2行以上の時は二行目の最後に三点リーダーをつける

style.css
.line_wrap {
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}

2行以上の場合はちゃんと三点リーダーが表示されます。(レスポンシブ対応)
スクリーンショット 2020-03-10 17.40.59.png
どちらがいいかはお好みで。

参考サイト

https://coliss.com/articles/build-websites/operation/css/css-line-clamp-property.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Wordpress自作テーマ ヘッダーの画像とテキストを設定 + 変更可能にする

はじめに

この記事ではwordpressの自作テーマでヘッダー画像をセットしたい場合、どうるれば良いかを紹介。

functions.php

結論、functions.phpを編集します。
これを追加することで、管理画面>外観>ヘッダーが選択できるようになる。

functions.php
//ヘッダーテキストの色を変更可能にする
function wphead_cb() {
  echo '<style type="text/css">';
  echo '.topimg-pc h1, .topimg-pc h6 { color: #'.get_header_textcolor().' }';
  echo '</style>';
}

// カスタムヘッダー
$custom_header = array(
'random-default' => false,
'width' => 1000,
'height' => 300,
'flex-height' => true,
'flex-width' => true,
'default-text-color' => '',
'header-text' => true,
'uploads' => true,
// ヘッダーテキストのデフォルトの色
  'default-text-color' => '000',
  'wp-head-callback' => 'wphead_cb',
                         // デフォルト画像へのパス
'default-image' => get_bloginfo('template_url').'/src/img/top_img.jpg',
'admin-head-callback'    => '',      // 管理画面で、[外観 - カスタマイズ]をプレビューするためのコールバック
    'admin-preview-callback' => '',
);
add_theme_support( 'custom-header', $custom_header );

スクリーンショット 2020-03-04 20.46.28.jpg

ヘッダー画像を出力

どこにヘッダー画像を出力するかは人によるけど、私は共通化してあるheader.phpにした。

header.php
 <div class="topimg-pc">

 <!-- もしヘッダー画像が設定されていたら -->
       <?php if ( get_header_image() ) : ?>
          <img src="<?php header_image(); ?>" height="<?php echo get_custom_header()->height; ?>" width="<?php echo get_custom_header()->width; ?>" alt="" />

 <!-- もしヘッダー画像が設定されていないなら -->
          <?php else: ?>
           <img src="<?php echo get_template_directory_uri(); ?>/src/img/top_img.jpg">
        <?php endif; ?>

        <h1><?php bloginfo( 'name' ); ?></h1>
        <h6><?php bloginfo('description'); ?></h6>

  </div>

ヘッダーテキストの色を変更

echoで何を吐き出すかは、HTMLタグとCSSによって変わる。

functions.php
//ヘッダーテキストの色を変更可能にする
function wphead_cb() {
  echo '<style type="text/css">';
  echo '.topimg-pc h1, .topimg-pc h6 { color: #'.get_header_textcolor().' }';
  echo '</style>';
}

スクリーンショット 2020-03-10 20.28.28.jpg

これで管理画面>外観>ヘッダー>色からヘッダーテキストの色を変更可能になった!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Tecpitの教材「【Go】技術ブログサイトを自作してみよう!」を試してみました / TechCommit企画

テックコミットさんのお年玉企画でTecpitさんの「【Go】技術ブログサイトを自作してみよう!」を試してみましたので、情報をまとめて見ました!

自分の知識

GoはTour of Goを一度なぞった程度

完成物

https://damp-journey-45035.herokuapp.com/

教材の概要

マークダウンに対応した、記事投稿システムです

この教材で学べる知識

  • echoでサーバーたてる
  • Modulesでモジュール管理
  • pongo2
  • sqlx
  • goose(マイグレーションツール)
  • freshでホットリロード
  • basic認証のかけ方
  • 多対多のリレーション
  • herokuデプロイ

※Goの文法自体の説明はありません!

教材の注意書きにもありますが、Goの文法自体の説明はありません!
そこらは抑えている前提で話が進みます

感想

Goの文法はわかったけど、実際どうやって組み立てていくの?って人にはかなりいい感じの教材だと思いました。
またコードの随所に何をやっているのかという説明が記載されているのもとても分かりやすかったです。
難点をあげるとすれば、HTML、CSS、JavaScriptのパートが多かった気がします。。。プロダクトの性質上仕方ないのですが。
とはいえ、Go楽しかった!

教材をありがとうございます
TechCommitさん
Tecpitさん

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Progate で学んだ html、css を使って自分のプロフィールWEBページを7日間で制作しました。

これです↓
https://toshiki89.github.io/suzuki-toshiki./suzukitoshiki.html

はじめに

現在、大学3年生で未経験からエンジニアを目指して就職活動中です。

昨年の12月、1ヶ月間携帯アプリでProgateを一通り触り、
2月に入ってからMacでVisual Studio Code(VS Code)で
コードを書きはじめ、Githubアカウントを作成し、WEBページを公開しました。

理解できたこと

【html】


スクリーンショット 2020-03-10 10.27.34.png
このコードでSNSのURLを呼び出すこと。


スクリーンショット 2020-03-10 10.38.42.png

githubにアップロードした画像を載せる時は自分のアカウントURL(https://toshiki89.github.io/suzuki-toshiki.) の後に画像のファイル名 (/657264B1-F3FB-41F0-AD52-C68F1BA43E94_1_201_a.jpeg)
を書くこと。


スクリーンショット 2020-03-10 10.43.59.png

スクリーンショット 2020-03-10 10.45.57.png
と表示でき、クリックするとリンク先を開けること。

【css】

①object-fit: cover;
で画像の中心部をトリミングできること

理解できていないこと

【html】


スクリーンショット 2020-03-10 11.34.34.png  

スクリーンショット 2020-03-10 11.34.10.png
上の画像のように・と文字の間に変な隙間があくこと。

【css】

IMG_7170.jpg

携帯電話でページを開くとこのように画像が半分になること。


スクリーンショット 2020-03-10 11.50.35.png
ここで color:skyblue;
としているが、
スクリーンショット 2020-03-10 11.50.59.png
上の画像のように紫色で表示されること。

これから

PHP ruby 等で機能を追加し、このページを更新していきます!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTMLでPixi.js

20200310cover.png

Pixi.js とは、ブラウザ上で動作するWebGLを用いた2Dグラフィックスライブラリです。

Pixi.js は、JavaScript から使用するライブラリで、以下のようなプログラムを書くことで使用できます。

const app = new PIXI.Application()

document.body.appendChild(app.view)

// スプライトを追加
const sprite = PIXI.Sprite.from("hoge.png")
app.stage.addChild(sprite)

上記の例では、Pixi.js の初期化と、スプライト(画像)の表示を行っています。PIXI.Sprite.fromで新たなスプライトのオブジェクトを生成し、それをapp.stageに対してaddChildで追加することで、画像の表示が行われる、という例です。

Pixi.js は、表示物の情報を階層構造で保持し、その情報に従って画面の表示を行います。これは、HTMLの構造とよく似ています。

そこで、Custom Element の機能を用いれば、HTML で Pixi.js の表示物を宣言的に定義して Pixi.js による画面表示が行えるのではないかと考えて、試してみました。

Custom Element を使った要素の定義

まずは、PIXI.Applicationを指す<pixi-app>という要素を定義してみます。とりあえず動作させられることだけを確認したいため、内部の実装は雑です。

customElements.define("pixi-app", class PixiApplication extends HTMLElement {
 constructor() {
   super()
   this.pixiObj = new PIXI.Application()
   const shadow = this.attachShadow({mode: "open"})

   shadow.appendChild(this.pixiObj.view)

   const style = document.createElement("style")
   style.textContent = `
     :host {
       display: inline-block;
     }
   `
   shadow.appendChild(style)
 }
})

Shadow DOM で、内部に Pixi.js の<canvas>要素を追加しています。

次に、画像リソースを表すPIXI.Textureの要素として<pixi-texture>を定義します。

customElements.define("pixi-texture", class PixiTexture extends HTMLElement {
 constructor() {
   super()
   const pixiApp = getPixiApp(this)
   if (pixiApp === null) {
     return
   }
   const src = this.getAttribute("src")
   this.pixiObj = new PIXI.Texture.from(src)
 }
})

次に、画像の表示を行う要素であるPIXI.Spriteの要素として<pixi-sprite>を定義します。親要素から<pixi-app>要素を探す関数としてgetPixiApp()関数も定義して使用しています。

const getPixiApp = (elem) => {
 let node = elem.parentElement
 while (node !== null) {
   if (node.tagName === "PIXI-APP") {
     return node
   }
   node = node.parentElement
 }
 return null
}

customElements.define("pixi-sprite", class PixiSprite extends HTMLElement {
 constructor() {
   super()
   const pixiApp = getPixiApp(this)
   const pixiTexture = pixiApp.querySelector(`#${this.getAttribute("texture")}`)
   this.pixiObj = new PIXI.Sprite(pixiTexture.pixiObj)

   const parentPixiObj = this.parentElement.pixiObj
   if (parentPixiObj instanceof PIXI.Application) {
     parentPixiObj.stage.addChild(this.pixiObj)
   } else if (parentPixiObj instanceof PIXI.Container) {
     parentPixiObj.addChild(this.pixiObj)
   }
 }
})

<pixi-sprite>texture属性の値は、表示の対象としたい<pixi-texture>要素のid属性の値が設定される想定です。

これで、とりあえず何らかの表示を行うための最小限の要素の定義ができました。

実際に使用した例は以下のようになります。

<pixi-app>
 <pixi-texture id="bunny" src="bunny.png"></pixi-texture>
 <pixi-sprite texture="bunny"></pixi-sprite>
</pixi-app>

<pixi-app>の子要素として<pixi-texture><pixi-sprite>を追加する形を想定しています。

とりあえず表示だけはされるのかの実験をするために、PIXI.Spriteの各プロパティを操作するための仕組みの実装は省略しました。

定義した要素を使用する

動作を試しますと、以下のように黒い<canvas>の左上に小さな画像が表示されます。

pixi-element-debug.png

うまくできました。

この Pixi.js の要素を HTML の要素として記述できる仕組みが本格的に実装できれば(されれば)、ReactPreactSuperfine などの仮想DOMの仕組みを持ったフレームワークを用いて Pixi.js プログラミングができそうです。

すでに React のコンポーネントで Pixi.js の要素を扱えるようにするライブラリとして React PIXI というものがありますが、こちらは React 限定になります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 258日目

100日チャレンジの258日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
258日目は、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ほーむぺーじのソースをこまかくみて判別

ネット上にあるサイトを開いて「これと同じで良い」みたいな
ムチャブリをされた時に、できるだけ効率的に、このサイトが
何で作られているのか?を判別して、似たようなサイトを作るための方法です。

ちなみにChrome拡張のVue/ReactのDevToolを入れておくと、
もろにVueやReactの場合は反応する。一番早い判別はコレ。

■sitesucker

https://nuconeco.net/sitesucker/
まず構造とかちゃんと見る。CSSとJSは最近はほぼ圧縮されてると思うので、
コレだけで何かを特定するのは難しいですが、
JSで書かれてるヤツは、バーチャルなルーティングなので
実物のディレクトリとかDOMが書かれたhtmlは落ちて来ないです。
DOMが落ちてくるという事は静的サイトジェネレーターか、SSRかな〜と推測。

■Prepros

https://prepros.io/
とりあえずローカル立ちあげて、ブラウザのデベロッパーツールで見る。(一番速い)
細かいパーツのCSSはコレで見たほうが速いかもですが、
全部のパーツをデベロッパーツールで拾うのは地獄なのでやらない。

■Sourcetree

https://www.sourcetreeapp.com/
弄くり回す場合は、ローカルに初期状態を保存する。(一番ラク)

■Snappy Snippet

https://github.com/kdzwinel/SnappySnippet
htmlとcssを逆展開する拡張を入れる。入れ方は下記とほぼ同じ。
でもクラス名が本物と違うようになる。
https://naokixtechnology.net/javascript/2851
HTMLとCSSだけをちゃんとマネしたい場合は「ウェブページ、完全」でダウンロードした方が
安定しそうですな。

■codePen

https://codepen.io/pen/
ココに貼ってhtmlとCSSを見る。昔のサイトならコレで大概理解できるが
最近のはJSで制御されてるので、ほぼ動かない。
※ほぼ動かないって事はJSフレームワークっぽい何かを使ってる。

このやり方は、HTMLとCSSは独自のクラスに置き換わるが、圧縮されてない感じに見える。
表面のスタイルだけをマネしたい、という場合はコレで一旦やる。

■chromeの「デベロッパーツール」から「ソース」を見る

https://ascii.jp/elem/000/000/999/999122/
Webpackやらなんやらのツールは著作権表記は残すので、
そこからある程度予測する。例えば、こんな表記がある

/*!
 * VERSION: 2.1.3 //←ココ
 * DATE: 2019-05-17
 * UPDATES AND DOCS AT: http://greensock.com //←ココ
 *
 * @license Copyright (c) 2008-2019, GreenSock. All rights reserved.
 * This work is subject to the terms at http://greensock.com/standard-license or for
 * Club GreenSock members, the software agreement that was issued with your membership.
 *
 * @author: Jack Doyle, jack@greensock.com
 */

サイト名を指定してバージョン番号で検索します。

site:http://greensock.com VERSION: 2.1.3

大概の場合、これで何を使っているのか分かる。上の場合はgsapですよね。
https://greensock.com/gsap-plugins/

/*!
 * UAParser.js v0.7.19
 * Lightweight JavaScript-based User-Agent string parser
 * https://github.com/faisalman/ua-parser-js
 *
 * Copyright © 2012-2016 Faisal Salman <fyzlman@gmail.com>
 * Dual licensed under GPLv2 or MIT

こちらは、ちゃんとURLが載ってました。モバイルなどの判別ですね。
https://github.com/faisalman/ua-parser-js

/*
object-assign
(c) Sindre Sorhus
@license MIT

なんかのポリフィルですね。あとコレnpmのパッケージ以外配布してないので、
このサイト、やっぱり何かの「jsフレームワーク」を使ってるっぽい。
https://www.npmjs.com/package/object.assign

■圧縮されたmain.jsをできる限りみる。

多分NuxtNextで作ってるんだろうと予想してみる。
(サクサクなパフォーマンスからもReactっぽい何かだと感じる。)

この圧縮されたjsは目で見ることは不可能ですので整頓する。
https://beautifier.io/
とりあえず圧縮されたJSを引き伸ばしてみて、「雰囲気」を感じ取ります。
雰囲気から元のソースを想像して何を使ってるんだろな〜を予測します。

■※ここから先、さらにおそろしく地味な作業です。

そして開いている元ソースを書けないから、多分ワケわからんと思うんで、
あとは興味あったら読んでくだせぇ…。

$("#で検索して、なんとなくjQuery使って動かしてるっぽいDOMを特定する。
jQueryをminifyしただけの場合はコレで簡単にコピーできるんですが、
...あ、あんまりjQueryを使ってないかも。シンタックスシュガー的な使い方に。

addEventListener("mouseenter"
addEventListener("mouseleave"
addEventListener("click"

clickで検索してイベント系の周りを見渡していると、
addEventListerに変換されているので、元はonClick的な感じだったのかも。

で、その下のほうに何かの残骸が見えてきます。

WebGLRenderer(100, 100, {

あ〜これ、上記の書き方はthree.jsですよね。。メニューはこれで表示してるのかな。。?

              key: "show",
              value: function() {
                  this.container.dataset.state = "show", s.b.fromTo(this.logo, .8, {
                      opacity: 0,
                      x: -40
                  }, {
                      opacity: 1,
                      x: 0,
                      ease: u
                  })
              }
          }, {
              key: "hide",
              value: function() {
                  T.hide(), this.container.dataset.state = "hide", s.b.to(this.logo, .8, {
                      opacity: 0,
                      x: 40,
                      ease: u
                  })
              }

変数は圧縮されちゃってますが、上記はgsapの設定ですね。
アニメーションは、ほぼこのツールで設定されてるっぽいですね。

gsapなのかcssなのか見極めが難しいですが、
CSSのtransitionの設定が分かれば、パラメーターを入れてみるとこれで再現できそうです。
 ↓
http://ds-overdesign.com/transform/matrix.html

regeneratorRuntime.mark
new Promise

これbabeles6.promiseがセットで使われてそう。。

throw new ReferenceError("this hasn't been initialised - super() hasn't been called");

このエラーコードはbabel-plugin-transform-es2015-classesの物ですね。。
ES6の拡張で、クラス構文で書いているんじゃなかろうか。。

TypeError("Cannot call a class as a function")
this.btnNext = $("#PageTop .section-news .arrow-next"),
this.btnPrev = $("#PageTop .section-news .arrow-prev"),
this.btnNext.addEventListener("click", this.change.bind(this, 1))

あ、これはreact-slickかな??多分。

Super expression must either be null or a function

このエラー文章は、、Reactの系統ですよね。。

(n.parallax = new Q("[data-parallax]"))

react-parallax的な感じのものも必要そう?

後はDOMをコメントアウトしながら、対応するJSを割り出していく。
例えば、「更新情報」を差し込んでるコンテナを消してみる。

Error: Barba.js: no container found

なるほど、ココはBarba.jsで差し込んでいるのか。。

あと、お問い合わせフォームに文字打ち込んでみて、リロードしてみる。
リロードしたら消えてるっぽいのでreduxみたいなのは使ってないと思う。

スクロールにも、なめらかになる工夫がされているような気がする。
これかな??
https://min30327.github.io/luxy.js/
いや、多分tweenmax(GSAP)っぽいな。
https://inertia-momentum-scroll.webflow.io/tweenmax-js

React系の何か+ES6(Babel)で、gsapとthree.jsとslick

この場合だとNext.jsかGatsby.jsか分からないけど、Reactっぽいどっちか。
Reactから派生してる技術を使っていけば、似たようなものが作れます。

…と、いうわけで、

依頼主「これと同じで良い」
→「Next.jsを使うので、その日数で工数を算出します」または
→「ウチはReactのエンジニア居ないんで無理です」

と回答ができる。
「jQueryでなんとかできそうですね〜」とか答えちゃうと、もうヤバい。
その後はもう地獄です。工数算出する時はキチッとソースまで見て答えましょう。

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTMLの大枠

HTMLの大枠

HTMLの大枠にはheader/div/footerなどがあります。
【例】

<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="style.css">
    <title>Qiita</title>
  </head>
  <body>
    <header>
    </header>

    <div class="contents">
    </div>

    <footer>
    </footer>
  </body>
</html>

<header>...</header>

ヘッダーを示す専用の要素です。

<div>...</div>

classセレクタを付与して使用します。

<footer>...</footer>

フッターを示す専用の要素です.

heightプロパティ

要素の高さを決めるプロパティです。px数や%などで指定することができます。

widthプロパティ

要素の幅を決めるプロパティです。px数や%などで指定することができます。
【例】

.contents {
  height: 400px;
  width: 960px;
}

これで高さと幅を指定できます。
プロパティはいろいろあるのでその時々で調べながらやっていきましょう
参考

img要素

img要素を使うと、Webサイトで画像を表示させることができます。画像がどこにあるのかという場所を指定するsrc属性、画像が表示されなかった場合に代替テキストなどを表示するためのalt属性を指定して使います。
【例】

<img src="image.jp"alt="imagename"class="contents"

form要素

お問い合わせフォームなどを表すブロック要素です。

input要素

フォームの入力欄や実行ボタンなどを作成することができる要素です。input要素にはtype属性があり、それを指定します。

type属性 用途
text 1行のテキスト入力欄を作成します
checkbox チェックボックスを複数作成することができます
radio 複数の中から1つしか選択できない、ラジオボタンを作ります
submit 送信ボタンを作ります

textarea要素

複数行のテキスト入力欄を作成する要素です。

value属性

送信ボタンを押したときに、どの値が送られるのかを決めることができます。

placeholder属性

入力フォームに仮の文字列を入れることができます。

label要素

フォームのtype属性、例えばラジオボタンとテキストをlabel要素で囲むことによって、文字の部分をクリックしたときもラジオボタンを選択することができます。

select要素

フォームの選択メニューを表す要素です。選択肢全体を囲みます。

option要素

メニューの選択肢を作成するときに使用します。option要素で指定する選択肢は、select要素の間に記述します。
【例】

        <form>
          <input type="text" placeholder="文字の入力"><br>
          <textarea placeholder="複数行の文字"></textarea><br>
          <label>
            <input type="radio" name="RadioGroup" value="0">男性
          </label><br>
          <label>
            <input type="radio" name="RadioGroup" value="1">女性
          </label><br>
          <select>
            <option value="0">20才未満</option>
            <option value="1">20才以上</option>
          </select>
          <div class="contents">
            おはようございます<br>
            <label>
              <input type="checkbox" name="Checkbox" value="0">
                こんにちわ
            </label>
            <label>
              <input type="checkbox" name="Checkbox" value="1">
                おやすみ
            </label><br>
          </div>
          <input type="submit" value="送信">
        </form>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Progate無料版をやってみる【HTML & CSS 初級編】#2

シリーズ

Progate無料版をやってみる【HTML & CSS 初級編】#1

第13章から

前回の続きになります。

ヘッダーの構造

・特記事項はないので即演習へ

演習
image.png
image.png

プレビューも見本もなんでこんなにちっちゃいの?w
→初期表示している画面のサイズが悪いかも。全画面にしたり縮めたりしていたらある程度大きくなった。

header-logoとheader-listのクラスを参照した意味は・・・?

ヘッダーのレイアウト

・横並びを実現するにはfloatプロパティ。ぐぐったら「浮く」ってでてきた・・・。

演習
image.png
image.png
たしかに横並びに

ヘッダーの余白

・余白を作りたい場合はpadding。要素の外側にスペースが開くイメージ。内側らしいw

演習
image.png
余白があるほうが見た目がいいですね。

フッターの構造

・CSSに「.header-list li」と定義することで、「クラス=header-listの下層のli要素に対して」という意味になる。
JavaScriptで要素を取得するときに、よく上記のような要素を限定するセレクタ指定が出てきた

演習
image.png
image.png

フッターのレイアウト

・左寄せと右寄せ→float leftとright

演習
やばい、そろそろ写りきらない
image.png
image.png

メインのレイアウト

・文字列内の一部にCSSを適用させたい場合は<span>を使用するとのこと。意識したことなかったなぁ。お決まりなんでしょうか。
・ブロック要素とインライン要素。
 ブロック要素 → div,h1,p
 インライン要素 → span,a

演習
image.png
image.png
image.png

コンテンツの構造

演習
即演習。また、ソースが冗長になってきたため、一部しか結果載せません。
image.png

ボーダー

・罫線を引く。borderを使用する。
 「border: 太さ 種類 色 」でいっぺんに定義できる。
image.png

paddingとmargin

・paddingはborderの内側。
・marginはborderの外側。
・HTMLのすべての要素にはborderがあり、それの内側がpaddingで外側がmarginとのこと。
→初めて知った・・・。

演習
image.png
だんだん見た目が良くなってきた!
ホームページ等を自作するときに参考にできそう。

お問い合わせフォームのレイアウト

以下のようなフォームを作成する
image.png

演習
image.png
淡々と進めます

お問い合わせフォームのレイアウト(2)

・入力するためのタグがでてくる。inputやtextarea等・・・。
・CSSはカンマ区切りで定義することで、それらに同じスタイルを適用できる。例:h1,p { color: red; }

演習
image.png
ここまでだったらまだ全然できる・・・と思う。

あ、なんか初級編おわった。
image.png

総括

・業務である程度触っていたので、サクサクとは進められた。
・業務でフワフワと使用していた技術が、少しだけ理解が深まった。
 →「すべてのHTML要素にはborderがあり、borderの内側がpaddingで外側がmarginである」は勉強になった!
・自分でHTMLのレイアウトを作成するときって何から手を付けて、どのタグを使用すればいいのかわからなかったが、本レッスンを参考にしていきたいと思う。

次回はHTML&CSSの中級編をやっていきたいと思います。
20200310追記
有料の為、受講しませんでした。
その代わりJavaScriptのレッスンをやり始めました。
次回

後から読み返してみて・・・

演習結果だけ貼っていると、超わかりにくいですね・・・
もし見てくれる方がいましたら、その時は自身もProgateをやりながらがいいかもしれません。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTMLとCSSの基本的なこと

HTML

ウェブサイトに表示される情報です。

css

HTMLに記載された情報を装飾する機能です。

head要素

ウェブサイトの情報や、参照するCSSファイルを記載する部分です。記述した情報は画面上には表示されません。

body要素

画面上に表示したい情報を記載します。
HTMLはタグで囲みます。例えば

記述する内容となります。終了タグには「/」を必ず入れます。

<!DOCTYPE HTML>

HTML文章であることを宣言する要素です。

<html>...</html>

HTML文章の始まりと終わりを示す要素です。

<span>〜<span>

<span>~</span>で囲った部分をインライン要素としてグループ化することができるタグです。

<meta>

文章に関する情報を指定する時に使用します。charset="UTF-8"は文字コードを指定するもので、この記述が無いと文字化けしてしまいます。
【例】

<meta charset="UTF-8">  #閉じタグはないです

<title>...</title>

ウェブサイトのタイトルを記述する場所です。
【例】

<title>Qiita</title>
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Qiita</title>
  </head>
  <body>
  </body>
</html>

上記みたいな感じです。

head要素からCSSを呼ぶ

head要素内に、HTMLとペアになるCSSのファイルを指定します。
【例】

<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Qiita<</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
  </body>
</html>

上記でstyle.cssを呼び出せるようにしました。
<link rel="stylesheet">でCSSファイルを指定し、hrefには実際のファイル名を記載します。hrefはリンク先の場所を指定します。

body要素の中身の記述

【例】

〜省略〜
 <body>
    <h1>
      おはよう
    </h1>
    <p>
      こんにちわ
    </p>
    <b>
      おやすみ
    </b>
  </body>
〜省略〜

上記で記述した文字が出ます。

<h1>...</h1>

文章の見出しを指定します。<h1>...</h1>で囲むと文字が太く大きく表示されます。h1〜h6まであり、h1が一番大きくh6になるにつれ文字が小さくなります。

<p>...</p>

文章の段落を表します。

<b>...</b>

文字を太くします。

ブロックレベル要素

ウェブデザインにおける箱となる要素の事をです。<h1>...</h1>や<p>...</p>はブロックレベル要素です。

インライン要素

主には文字の修飾です。<b>...</b>インライン要素です。

cssの記述

基本の形はセレクタ { プロパティ: 値; }となります。
【例】

style.css
p {
  color: red;
}

上記の記述でp要素のこんにちわの色が赤になりました。もしp要素が他にも記述してあったら全ての要素が適応されます。

class属性

要素に対して名前がつけられます。
【例】

<p class="top">
  おはよう
</p>

classセレクタ

class名をセレクタとして使用することができます。記述するときは.クラス名で指定します。
【例】

.top {
  color: red;
}

これでp要素内のclass="top"の色が赤くなります。

id属性とidセレクタ

【例】id属性

<p id="top">
  おはよう
</p>

さっきと違うのはclassがidになっています。
【例】idセレクタ

#top {
  color: red;
}

さっきと違うのは.が#になっています。
classとidの使いはclassは同じクラス名を複数回使えます。idは複数回使えないので、重要なところに使う感じです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

javascriptで連長圧縮された文字列を解凍してみた。

今回は、前回の記事で圧縮したデータを解凍するアルゴリズムについて解説して行きます。

前回の記事:javascriptで連長圧縮してみた。

“連長圧縮”という圧縮処理を経た文字列を、解答していくわけですが、前回同様に、
はじめに例をお見せします。

まずは例から。。。

自作のローカルページに「3A5B-2CD2E-2FG」と入力すると、前回の記事で圧縮処理をかけた「AAABBBBBCDEEFG」というオリジナルの文字列が表示されます。
image.png
正の数字は連続の文字の回数を表しているので、その回数分、文字を連続して出力します。
(ex. 3A → AAA(解凍)となるわけです!)

負の数字は不連続文字の数を表しており、その回数分、不連続の文字を続けて出力します。
(ex. -5CDEFG → CDEFG(解凍)となり、解凍後の方が情報量が少ないですね...笑)

やはり、「連続する文字が多い」という特性を持った情報でないと、効果を発揮する場面が無さそうですね。

解凍のアルゴリズム(JavaScript)

Rentyo.js
function doDecompress(charData){ //連長圧縮に対する復号処理
    var decompressedText = []; //解凍結果を格納する場所
    var minusFlag = false; //連続か不連続かの状態を決定する
    var countStock = 0; //文字の数を数えるようの変数
    var preNumStock = []; //前回までの文字のストック(2桁以上に対応)

    for(i=0;i<charData.length;i++){
        if(charData[i]=="-"){ //マイナスの符号を検知
            minusFlag = true;
        }
        else if(charData[i].match(/[a-z]/gi)){ //アルファベットを検知

            if(minusFlag==true){ //不連続だったら
                countStock = parseInt(preNumStock.join(""));
                for(j=0;j<countStock;j++){
                    decompressedText.push(charData[i+j]); //不連続の文字の回数出力
                }
                i = i + countStock - 1; //ループを次の状態まで飛ばす
                minusFlag = false; //諸々初期化しとく
                preNumStock = [];
                countStock = 0;
            }else{ //連続だったら
                countStock = parseInt(preNumStock.join(""));
                for(j=0;j<countStock;j++){
                    decompressedText.push(charData[i]); //連続の回数分、同じ文字を出力
                }
                preNumStock = []; //諸々初期化しとく
                countStock = 0;
            }
        }else{ //数字だったら
                countStock = parseInt(charData[i]); //int型に変換
                preNumStock.push(countStock); //2桁以上の場合に備えて保持しておく
        }
    }    
    var resultText = decompressedText.join(""); //配列を文字列に変換
    document.getElementById("show_result").textContent = "Decompressed Result: " + resultText;
}

注意すること

デコーダーにおいて一番私が躓いたのは、1文字ずつ調べるが故に、普通にやってたら2桁以上の数字に対応できない!という点でした。笑
そのためpreNumStockという配列を用意し、数字をどんどん貯め、アルファベットが始まった段階で初期化して2桁以上に対応しました。

真価を発揮するとき。。。

連長圧縮は、2進数のように情報の種類がAとBの2種類しかない場合では、かなり圧縮率を高く出来ます!
「ABBBBABABAAAAAA」という文字列があるとしましょう。最初にAが来ることを前提とすると、
「-1,4,-4,6」というふうに数字だけで表せます。
この数字からなる情報だけで、オリジナルの文字列を解読出来ちゃいますね!
最初の文字がAかBかを決定するだけで、あとは数字のみで表せてしまうのです。

GitHubはコチラ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む