20200603のHTMLに関する記事は15件です。

2020/06/03 プログラミング(WEBデザイン)学習4日目 メモ

本日の学習範囲

ドットインストール

・はじめてのCSS #08〜#10
(学習時間:1.5時間)

CSS学習メモ

Flexbox

Flexible Box Layout Moduleの略。
ボックスを柔軟にレイアウトできる

displayプロパティ

{display: ○○;}
要素の表示形式を指定する
{display: flex;}
で指定した要素の子要素を横並びにする

border-radiusプロパティ

{border-radius: 長さor○%}
ボックスの四つ角の角丸をまとめて指定する
%は指定された要素の幅と高さに基づいたものになる
{border-radius: 50%}
の場合、正円になる

border-styleプロパティ

{border-style: ○○;}
ボーダーのスタイルをまとめて指定する
{border-style: solid;}
の場合、一本の実線になる

font-weightプロパティ

{font-weight: ○○;}
フォントの太さを指定する
{font-weight: normal;}
の場合、通常の太さになる

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

PA-API v5で商品情報を取得する

PA-APIの利用

PA-API を使ってアマゾン商品情報をとってみよう。そこからアフィリエイトなどで収益化ができたら良いね。

 PA-APIはアマゾンで一ヶ月以内に売上が発生していないと使えません。なので、アマゾンの商品リンク作成ツールや、ブログのアフィリエイトツールなどで売上を得られるように頑張ろう。ここが一番難易度が高い気がする。

 アフィリエイトで売上が発生したら次に、ISBNやASINが必要となる。ただ、ASINを具体的にどのように取るかの選択が少ないので、アマゾンのサイトをクロールしている。

Amazonの検索結果からasinをスクレイピング
https://qiita.com/99nyorituryo/items/c5d53a3ca8a4967b5927

ASINから商品情報のJSONを取得する

 ここでは、ISBNやASINという本の情報から、アマゾンの表紙画像や、タイトル著者名、出版社、価格、本の種類などの情報を取得してサイトとして出力する方法を書く。
 PAAPIでは、様々な言語用にツールが配布されているが、私はnode.jsが一番慣れているので、node.jsを用いた方法について書いていきます。

node.jsのやり方は公式のページから見てみると良いのだけど。

https://affiliate.amazon.co.jp/help/node/topic/GZH32YX29UH5GACM

ここで得られたISBNをsampleGetItemsApi.jsを使ってアマゾンから書誌情報を取得する。
sampleGetItemsApi.jsは下記アドレスのnode.jsからダウンロードできる。
https://webservices.amazon.com/paapi5/documentation/quick-start/using-sdk.html

  • paapi5-nodejs-sdk-and-samplesをダウンロードして展開して
  • さっきのファイルを解凍したフォルダーで、npm install paapi5--nodejs-sdk --saveでインストール
  • アクセスキーやシークレットキーをsampleGetItemsApi.jsなどのサンプルに追加
  • またアフィリエイト用のパートナータグも追加(-22で終わるやつ)
  • sampleGetItemsApi.jsを実行してみよう

というようなことが書かれています。

sampleGetItemsApi.jsを自分の目的に合うように書き換える。

初期状態では、amazon.co.jpになっていないので修正する必要がある。アクセスキーやシークレットキーを入力しないと実行できない。それから一度に取得できるasinは10個までになっている。それと待ち時間を設定しないとすぐエラーを吐くようである。

  • 100個の情報を取得しようとすると、待ち時間を設定して取得している。
  • key.jsonにアクセスキーやシークレットキー、アソシエイトタグにまとめている。
  • dateが開始日でtodateが終了日になっていてまとめて取得できる。
  • asinの配列は下の方法で作っている。

Amazonの検索結果からasinをスクレイピング
https://qiita.com/99nyorituryo/items/c5d53a3ca8a4967b5927


{"accessKey":"アクセスキー","secretKey" :"シークレットキー","PartnerTag":"パートナータグ"}
fs = require('fs');
var json = fs.readFileSync(__dirname + '/key.json', 'utf-8');
key = JSON.parse(json);

function sleep(second) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve()
        }, second * 1000)
    })
}


var ProductAdvertisingAPIv1 = require('./src/index');
var defaultClient = ProductAdvertisingAPIv1.ApiClient.instance;
defaultClient.accessKey =key.accessKey//
defaultClient.secretKey = key.secretKey//
defaultClient.host = 'webservices.amazon.co.jp';
defaultClient.region = 'us-west-2';
var api = new ProductAdvertisingAPIv1.DefaultApi();
var getItemsRequest = new ProductAdvertisingAPIv1.GetItemsRequest();
getItemsRequest['PartnerTag'] =key.PartnerTag//
getItemsRequest['PartnerType'] = 'Associates';


getItemsRequest['Resources'] =[
  "BrowseNodeInfo.BrowseNodes",
  "BrowseNodeInfo.BrowseNodes.Ancestor",
  "BrowseNodeInfo.BrowseNodes.SalesRank",
  "BrowseNodeInfo.WebsiteSalesRank",
  "Images.Primary.Small",
  "Images.Primary.Medium",
  "Images.Primary.Large",
  "ItemInfo.ByLineInfo",
  "ItemInfo.ContentRating",
  "ItemInfo.Classifications",
  "ItemInfo.ExternalIds",
  "ItemInfo.ManufactureInfo",
  "ItemInfo.ProductInfo",
  "ItemInfo.Title",
  "Offers.Listings.Price"];

var callback = function (error, data, response) {
    if (error) {
        console.log('Error calling PA-API 5.0!');
        console.log('Printing Full Error Object:\n' + JSON.stringify(error, null, 1));
        console.log('Status Code: ' + error['status']);
        if (error['response'] !== undefined && error['response']['text'] !== undefined) {
            console.log('Error Object: ' + JSON.stringify(error['response']['text'], null, 1));
        }
    } else {
    //    console.log('API called successfully.');
        var getItemsResponse = ProductAdvertisingAPIv1.GetItemsResponse.constructFromObject(data);
        console.log(JSON.stringify(getItemsResponse, null, 1));
jsondata=jsondata.concat(getItemsResponse.ItemsResult.Items);
        fs.writeFileSync(__dirname + '/json/kindle_paapi/'+filename, JSON.stringify(jsondata, null, 1),'utf-8')
//console.log("test"+jsondata)
        if (getItemsResponse['Errors'] !== undefined) {
            console.log('\nErrors:');
            console.log('Complete Error Response: ' + JSON.stringify(getItemsResponse['Errors'], null, 1));
            console.log('Printing 1st Error:');
            var error_0 = getItemsResponse['Errors'][0];
            console.log('Error Code: ' + error_0['Code']);
            console.log('Error Message: ' + error_0['Message']);
        }
    }
};

(async function(){

date=20200602
todate=20200602
for (date; date <= todate; date++) {
var json = fs.readFileSync(__dirname + '/json/kindle_asin/'+date+'k.json', 'utf-8');
asinarry = JSON.parse(json);

//c=a.ItemsResult.Items.concat(b.ItemsResult.Items);
jsondata=[];
filename=date +'.json'

for (let i = 0; i < asinarry.length; i += 10) {
 await sleep(3) 
asin =asinarry.slice(i, i+10)
getItemsRequest['ItemIds'] = asin


try {
api.getItems(getItemsRequest, callback);
} catch (ex) {
  console.log("Exception: " + ex);
}
}}
})();

これらを利用して作ったのが下のサイトである。

https://kyukyunyorituryo.github.io/new_epub/

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

PA-API v5でAmazonの商品情報を取得する

PA-APIの利用

PA-API を使ってアマゾン商品情報をとってみよう。そこからアフィリエイトなどで収益化ができたら良いね。

 PA-APIはアマゾンで一ヶ月以内に売上が発生していないと使えません。なので、アマゾンの商品リンク作成ツールや、ブログのアフィリエイトツールなどで売上を得られるように頑張ろう。ここが一番難易度が高い気がする。

 アフィリエイトで売上が発生したら次に、ISBNやASINが必要となる。ただ、ASINを具体的にどのように取るかの選択が少ないので、アマゾンのサイトをクロールしている。

Amazonの検索結果からasinをスクレイピング
https://qiita.com/99nyorituryo/items/c5d53a3ca8a4967b5927

ASINから商品情報のJSONを取得する

 ここでは、ISBNやASINという本の情報から、アマゾンの表紙画像や、タイトル著者名、出版社、価格、本の種類などの情報を取得してサイトとして出力する方法を書く。
 PAAPIでは、様々な言語用にツールが配布されているが、私はnode.jsが一番慣れているので、node.jsを用いた方法について書いていきます。

node.jsのやり方は公式のページから見てみると良いのだけど。

https://affiliate.amazon.co.jp/help/node/topic/GZH32YX29UH5GACM

ここで得られたISBNをsampleGetItemsApi.jsを使ってアマゾンから書誌情報を取得する。
sampleGetItemsApi.jsは下記アドレスのnode.jsからダウンロードできる。
https://webservices.amazon.com/paapi5/documentation/quick-start/using-sdk.html

  • paapi5-nodejs-sdk-and-samplesをダウンロードして展開して
  • さっきのファイルを解凍したフォルダーで、npm install paapi5--nodejs-sdk --saveでインストール
  • アクセスキーやシークレットキーをsampleGetItemsApi.jsなどのサンプルに追加
  • またアフィリエイト用のパートナータグも追加(-22で終わるやつ)
  • sampleGetItemsApi.jsを実行してみよう

というようなことが書かれています。

アクセスキーやシークレットキーは下から取得する。
https://affiliate.amazon.co.jp/assoc_credentials/home

sampleGetItemsApi.jsを自分の目的に合うように書き換える。

初期状態では、amazon.co.jpになっていないので修正する必要がある。アクセスキーやシークレットキーを入力しないと実行できない。それから一度に取得できるasinは10個までになっている。それと待ち時間を設定しないとすぐエラーを吐くようである。

  • 100個の情報を取得しようとすると、待ち時間を設定して取得している。
  • key.jsonにアクセスキーやシークレットキー、アソシエイトタグにまとめている。
  • dateが開始日でtodateが終了日になっていてまとめて取得できる。
  • asinの配列は下の方法で作っている。

Amazonの検索結果からasinをスクレイピング
https://qiita.com/99nyorituryo/items/c5d53a3ca8a4967b5927


{"accessKey":"アクセスキー","secretKey" :"シークレットキー","PartnerTag":"パートナータグ"}
fs = require('fs');
var json = fs.readFileSync(__dirname + '/key.json', 'utf-8');
key = JSON.parse(json);

function sleep(second) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve()
        }, second * 1000)
    })
}


var ProductAdvertisingAPIv1 = require('./src/index');
var defaultClient = ProductAdvertisingAPIv1.ApiClient.instance;
defaultClient.accessKey =key.accessKey//
defaultClient.secretKey = key.secretKey//
defaultClient.host = 'webservices.amazon.co.jp';
defaultClient.region = 'us-west-2';
var api = new ProductAdvertisingAPIv1.DefaultApi();
var getItemsRequest = new ProductAdvertisingAPIv1.GetItemsRequest();
getItemsRequest['PartnerTag'] =key.PartnerTag//
getItemsRequest['PartnerType'] = 'Associates';


getItemsRequest['Resources'] =[
  "BrowseNodeInfo.BrowseNodes",
  "BrowseNodeInfo.BrowseNodes.Ancestor",
  "BrowseNodeInfo.BrowseNodes.SalesRank",
  "BrowseNodeInfo.WebsiteSalesRank",
  "Images.Primary.Small",
  "Images.Primary.Medium",
  "Images.Primary.Large",
  "ItemInfo.ByLineInfo",
  "ItemInfo.ContentRating",
  "ItemInfo.Classifications",
  "ItemInfo.ExternalIds",
  "ItemInfo.ManufactureInfo",
  "ItemInfo.ProductInfo",
  "ItemInfo.Title",
  "Offers.Listings.Price"];

var callback = function (error, data, response) {
    if (error) {
        console.log('Error calling PA-API 5.0!');
        console.log('Printing Full Error Object:\n' + JSON.stringify(error, null, 1));
        console.log('Status Code: ' + error['status']);
        if (error['response'] !== undefined && error['response']['text'] !== undefined) {
            console.log('Error Object: ' + JSON.stringify(error['response']['text'], null, 1));
        }
    } else {
    //    console.log('API called successfully.');
        var getItemsResponse = ProductAdvertisingAPIv1.GetItemsResponse.constructFromObject(data);
        console.log(JSON.stringify(getItemsResponse, null, 1));
jsondata=jsondata.concat(getItemsResponse.ItemsResult.Items);
        fs.writeFileSync(__dirname + '/json/kindle_paapi/'+filename, JSON.stringify(jsondata, null, 1),'utf-8')
//console.log("test"+jsondata)
        if (getItemsResponse['Errors'] !== undefined) {
            console.log('\nErrors:');
            console.log('Complete Error Response: ' + JSON.stringify(getItemsResponse['Errors'], null, 1));
            console.log('Printing 1st Error:');
            var error_0 = getItemsResponse['Errors'][0];
            console.log('Error Code: ' + error_0['Code']);
            console.log('Error Message: ' + error_0['Message']);
        }
    }
};

(async function(){

date=20200602
todate=20200602
for (date; date <= todate; date++) {
var json = fs.readFileSync(__dirname + '/json/kindle_asin/'+date+'k.json', 'utf-8');
asinarry = JSON.parse(json);

//c=a.ItemsResult.Items.concat(b.ItemsResult.Items);
jsondata=[];
filename=date +'.json'

for (let i = 0; i < asinarry.length; i += 10) {
 await sleep(3) 
asin =asinarry.slice(i, i+10)
getItemsRequest['ItemIds'] = asin


try {
api.getItems(getItemsRequest, callback);
} catch (ex) {
  console.log("Exception: " + ex);
}
}}
})();

これらを利用して作ったのが下のサイトである。

https://kyukyunyorituryo.github.io/new_epub/

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

Javascriptで値が数値かどうかチェック→スペースかどうかもチェック

Wano株式会社で社内のもろもろを担当しているakibinです。

ヒゲ男ばかり聴いて、少しでも若返ったつもりでいる今日このごろです。でも好きだなーこのちょっと縦ノリっぽい楽曲と声。

今回やってみたこと

Javascriptで値が数値かどうかチェックするのにこちらの記事を参照させてもらいました!(分かりやすかったです!!)

がしかし!

スペースを数字と認識してしまうので、スペースかどうかもチェックするようにしてみました。

こんな感じ

正規表現の\S(空白文字以外の文字)と、!で論理値を反転させてif文で判定。当てはまった(true)場合はtry…catch文を使用して終了する。(JSにはexitが無いので)
※htmlは参照させていただいた記事と変わりないのですが、念の為載せておきます。

check.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>check</title>
  <script src="check.js"></script>
</head>
<body>
  数値を入力して下さい:
  <input type="text" id="input01">
  <input type="button" value="check" onclick="check();">
</body>
</html>
check.js
'use strict';

var check = function() {
    var num = document.getElementById('input01').value;

    try {
        if (!num.match(/\S/g)){
            alert("スペースが入ってますよ!");
            throw new Error("スペースありのため終了します");
        }

        if(!isNaN(num)){
            alert("入力された数は" + num + "です。");
        } else {
              alert("数値以外が入力されています");
        }
    } catch(e) {
        console.log(e.message);
    }
}

これで…

これでOKぃ!!

こちらもよろしくです。
****************************************
◆ Twitterアカウント
@AkibinMusic

◆ Youtubeチャンネル
https://www.youtube.com/channel/UC-JOpwEnJn3gCrUA4NdCYgg

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

Javascriptで値が数値かどうかチェック→スペースかどうかも

Wano株式会社で社内のもろもろを担当しているakibinです。

ヒゲ男ばかり聴いて、少しでも若返ったつもりでいる今日このごろです。でも好きだなーこのちょっと縦ノリっぽい楽曲と声。

今回やってみたこと

Javascriptで値が数値かどうかチェックするのにこちらの記事を参照させてもらいました!(分かりやすかったです!!)

がしかし!

スペースを数字と認識してしまうので、スペースかどうかもチェックするようにしてみました。

こんな感じ

正規表現の\S(空白文字以外の文字)と、!で論理値を反転させてif文で判定。当てはまった(true)場合はtry…catch文を使用して終了する。(JSにはexitが無いので)
※htmlは参照させていただいた記事と変わりないのですが、念の為載せておきます。

check.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>check</title>
  <script src="check.js"></script>
</head>
<body>
  数値を入力して下さい:
  <input type="text" id="input01">
  <input type="button" value="check" onclick="check();">
</body>
</html>
check.js
'use strict';

var check = function() {
    var num = document.getElementById('input01').value;

    try {
        if (!num.match(/\S/g)){
            alert("スペースが入ってますよ!");
            throw new Error("スペースありのため終了します");
        }

        if(!isNaN(num)){
            alert("入力された数は" + num + "です。");
        } else {
              alert("数値以外が入力されています");
        }
    } catch(e) {
        console.log(e.message);
    }
}

これで…

これでOKぃ!!

こちらもよろしくです。
****************************************
◆ Twitterアカウント
@AkibinMusic

◆ Youtubeチャンネル
https://www.youtube.com/channel/UC-JOpwEnJn3gCrUA4NdCYgg

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

JavaScriptでhtmlのTableをいじる

初めに

今回はjQueryをメインでDOM操作しながらTableをあれこれする方法を展開します。

コード

セルを押下できるようにする

セルを押下するとイベントが発火して処理される仕組み(今回はアラート表示)
まずはhtml側にTableをセットする(今回はタイトルなしです)

test.html
<table border="1">
        <tr>
            <td id="a"><a onclick="onClick(this);">Test1</a></td>
            <td id="b"><a onclick="onClick(this);">Test2</a></td>
            <td id="c"><a onclick="onClick(this);">Test3</a></td>
        </tr>
        <tr>
            <td id="d"><a onclick="onClick(this);">Test4</a></td>
            <td id="e"><a onclick="onClick(this);">Test5</a></td>
            <td id="f"><a onclick="onClick(this);">Test6</a></td>
        </tr>
    </table>
main.js
function onClick(link){
    alert("Test");
}

押下したセルの文字を入れ替え

main.js
function onClick(link){
    $(link).html("入れ替え")
}

押下したセルの文字を抽出

main.js
function onClick(link){
    $(link).parent().text()
}

押下したセルの列番号を抽出

main.js
function onClick(link){
    $(link).parent().index()
}

押下したセルのIDを抽出

idを振っている前提です

main.js
function onClick(link){
    $(link).parent().attr('id')
}

終わりに

今回はTableについての展開でした。
すごく簡単ですね!楽しい!

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

200603学習記録:codepenの設定

codepenでリセットCSSを効かす方法など

https://www.i-ryo.com/entry/2019/10/09/070250

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

200603学習記録:atomの設定

html-previewが効かない理由

https://teratail.com/questions/266233

最初にいれておくべきパッケージ

https://anyushu.com/web/atom-packages/

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

iOS,Android input type="date" JavaScriptイベント取得まとめ

はじめに

Javascriptでinput="date"のイベント取得をiOS,Androidで調べたのでまとめ

検証環境

iOS 13.3
ブラウザ Safari

Android 8.0.0
ブラウザ Chrome

iOS

操作 イベント
フォーカス onchange
日付切り替え onchange
消去 onchange
完了 onblur

完了を押下するとフォーカスが外れるため'onblur'が発火するっぽい

Android

操作 イベント
フォーカス -
日付切り替え -
削除 onchange (日付が入力済みの場合)
キャンセル -
設定 onchange

比較

ios Android
フォーカス onchange -
日付切り替え onchange -
消去・削除 onchange onchange
キャンセル - -
完了・設定 onblur onchange

sample

alertだとダイアログを消した際に、blurが発生し続ける見たいだったので、HTML出力

See the Pen sample date by shotaabe (@shotaabe) on CodePen.

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

iOS,Android input="date" JavaScriptイベント取得まとめ

はじめに

Javascriptでinput="date"のイベント取得をiOS,Androidで調べたのでまとめ

検証環境

iOS 13.3
ブラウザ Safari

Android 8.0.0
ブラウザ Chrome

iOS

操作 イベント
フォーカス onchange
日付切り替え onchange
消去 onchange
完了 onblur

完了を押下するとフォーカスが外れるため'onblur'が発火するっぽい

Android

操作 イベント
フォーカス -
日付切り替え -
削除 onchange (日付が入力済みの場合)
キャンセル -
設定 onchange

比較

ios Android
フォーカス onchange -
日付切り替え onchange -
消去・削除 onchange onchange
キャンセル - -
完了・設定 onblur onchange

sample

alertだとダイアログを消した際に、blurが発生し続ける見たいだったので、HTML出力

See the Pen sample date by shotaabe (@shotaabe) on CodePen.

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

inputタグにおけるtype属性について

inputタグとは

テキスト入力やボタンなどの部品を作成する際に用いる
以下のように入力して用いる
<imput type="○○" name="部品の名前" value="初期値">

部品の形式~type属性~

<input type="属性値">と記述する

属性値 内容
text 1行のテキストボックス
password 入力した内容にマスクがかかる(見えなくする)テキストボックス
radio ラジオボタン
checkbox チェックボックス
file ファイル参照ボタン
hidden 非表示のテキストボックス
submit フォームの実行ボタン
image 画像を使たフォームの実行ボタン
reset リセットボタン
buttun 汎用的なボタン

参考

Chrono Drive

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

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

100日チャレンジの333日目

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

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

サイトに3Dメニューページを作ってみる(A-frame + HTML Shader + html2canvas)

この記事でやっていること・できていないこと

  • できたこと
    • A-Frameを使ってサイトのメニューを3D化した。
    • A-Frame内で2次元の普通の画像要素を3次元で使うタイミングでできないことがあったので、HTML Shader + html2canvasを使った。
  • できてないこと

サンプル

image.png

このように3次元空間内にboxを置き、その上にhtmlで作った画像付き要素をのせています。
またクリックをすると、遷移対象のページに飛びます。

https://simasima.work/3d-menu.html

↑ こちらから試すことができます。

A-Frame

https://aframe.io/
ほんの数行のhtmlの記述だけで3D画像と空間を表現でき、とても便利です。
例えば下記サンプルコードですぐに複数の図形と3次元空間を表現できます。

aframe-sample.html
<html>
  <head>
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
  </head>
  <body>
    <a-scene>
      <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
      <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
      <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
      <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
      <a-sky color="#ECECEC"></a-sky>
    </a-scene>
  </body>
</html>

image.png

HTML Shader + html2canvas について

A-Frameの3次元空間内に2次元のDOM要素を加える場合に、どうしてもうまくいかないケースがありました。
本記事では、下記が大変参考になりました。
A-FrameとHTML Shaderで美しい日本語テキストを表示する方法

この記事によると、
HTML Shaderは、その名の通り2次元のDOM要素をマテリアルとして、3次元のA-Frameオブジェクト上に貼り付けることができるコンポーネントで、それは html2canvas というライブラリ上に成り立っているということです。

以降で説明していきますが、そのため上記2つ(HTML Shader + html2canvas)を使えるようにする必要があります。

HTML Shader

html2canvas

まず、HTML Shader と html2canvasを読み込む

HTML Shader

https://github.com/mayognaise/aframe-html-shader
このページによると、npmでのインストールに加えて、ブラウザファイルも用意されているようなので手ごろに使う場合は下記を

内にかけばOKです。
  <script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script>
  <script src="https://unpkg.com/aframe-html-shader@0.2.0/dist/aframe-html-shader.min.js"></script>

html2canvas

私が少し調べた限りでは、ブラウザファイルは用意されていないようなので、
http://html2canvas.hertzen.com/
このページにいき、html2canvas.min.jsを押しその中身をコピーして、html2canvas.min.js というファイル名で保存します。
image.png

今回のフォルダ構成

images
 └── ....
js
 └── html2canvas.min.js
style
 └── style.css
3d-menu.html

ソースコード

3d-menu.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <title>Hello!!!!</title>
  <meta name="description" content="Hello, WebVR! • A-Frame">
  <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>

  <script src="https://unpkg.com/aframe-html-shader@0.2.0/dist/aframe-html-shader.min.js"></script>
  <script src="js/html2canvas.min.js"></script>

  <link rel="stylesheet" href="style/style.css">  
</head>

<body>

    <div id="loader">

        <p>loading...</p>
    </div>
    <div id="target1" class="target">
        <img src="imgs/face.png" alt="A-Frame">
        <div class="cf"><h3>感情分析</h3></div>
        <p class="detail">クリックでページに遷移 </p>
    </div>
    <div id="target2" class="target">
        <img v-if="url" v-bind:src="url" alt="A-Frame">
        <div class="cf"><h3>犬の画像を表示</h3><p>立方体クリックで犬の画像を表示します(動かず)</p></div>
        <!-- <p class="detail">640px × 400px</p> -->
    </div>
    <div id="target3" class="target">
        <img src="imgs/gotop.png" alt="A-Frame">
        <div class="cf"><h3>TOPへ</h3></div>
        <p class="detail">クリックでページに遷移 </p>
    </div>
    <div id="target4" class="target">
        <img src="imgs/orc.png" alt="A-Frame">
        <div class="cf"><h3>OCR分析</h3></div>
        <p class="detail">クリックでページに遷移</p>
    </div>
    <div id="target5" class="target">
        <img src="imgs/dog.jpg" alt="A-Frame">
        <div class="cf"><h3>犬画像ページ</h3></div>
        <p class="detail">クリックでページに遷移</p>
    </div>
    <div id="target6" class="target">
        <img src="imgs/jaga.png" alt="A-Frame">
        <div class="cf"><h3>予備</h3></div>

    </div>


<div>
    <a-scene>
        <a-entity  id="aframeApp" >
            <a-box id="areabox1" position="-10  6 -15" width="16" height="10" rotation="0 30 0" material="shader:html;target: #target1;" @click="handlerClick"></a-box>
            <a-box id="areabox2" position=" 0  6 30" width="16" height="10" rotation="0 15 0" material="shader:html;target: #target2;"></a-box>
            <a-box id="areabox3" position=" 18  6 0" width="16" height="10" rotation="0 75 0" material="shader:html;target: #target3;" @click="handlerClick"></a-box>
            <a-box id="areabox4" position="-10 -6 -15" width="16" height="10" rotation="0 30 0" material="shader:html;target: #target4;" @click="handlerClick"></a-box>
            <a-box id="areabox5" position=" 0 -6 30" width="16" height="10" rotation="0 15 0" material="shader:html;target: #target5;" @click="handlerClick"></a-box>
            <a-box id="areabox6" position=" 18 -6 0" width="16" height="10" rotation="0 75 0" material="shader:html;target: #target6;" @click="handlerClick"></a-box>

            <a-box position="-2 0 5" rotation="0 45 0" color="#4CC3D9" @click="getdog"></a-box>
            <a-plane position=" 18 -6 0" width="16" height="10" @click="getdog"></a-plane>
            <a-sky src="https://images.unsplash.com/photo-1557971370-e7298ee473fb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80" rotation="0 45 0"></a-sky>
        </a-entity>

        <a-entity camera wasd-controls look-controls position="-8 0 8"></a-entity>

        <a-entity>
            <a-camera>
              <a-cursor></a-cursor>
            </a-camera>
        </a-entity>

    </a-scene>
</div>


    <script src="https://unpkg.com/vue@latest/dist/vue.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

    <script>
        // vue.jsの記載

        const app = new Vue({
          el: '#aframeApp',
          data: {
            url:"imgs/logo.png" 
          },
          methods: {
              getdog:async function(){
                    const URL = 'https://dog.ceo/api/breeds/image/random';
                    const response = await axios.get(URL);

                    this.message = response.data;
                    this.url = response.data.message;

                    console.log(this.url);
              }



            ,handlerClick: function (event) {
              console.log('handlerClick');
              console.log(event.target.id);
              const boxid = event.target.id;

              if( boxid == 'areabox1' ){
                location.href = 'https://simasima.work/contents/face-emotion.html';
              } else if( boxid == 'areabox4' ){
                this.skyboxSrc = 'https://simasima.work/contents/ocr-read.html';
              } else if( boxid == 'areabox3' ){
                this.skyboxSrc = 'https://simasima.work/contents/dog.html';
              }else if( boxid == 'areabox5' ){
                this.skyboxSrc = 'https://simasima.work/';
              }


            }
            ,
            handlerMouseEnter: function (event) {
              console.log('handlerMouseEnter');
              console.log(event);
              event.target.setAttribute('color', 'blue');
            }
            ,
            handlerMouseLeave: function (event) {
              console.log('handlerMouseLeave');
              console.log(event);
              event.target.setAttribute('color', 'red');
            }
          }
          ,
          mounted() {
            console.log('mounted');
          }
        })

      </script>

</body>

<script>
    var scene = document.querySelector('a-scene');
    var run = function () {
        document.getElementById("loader").classList.add("hidden");
    }

    if (scene.hasLoaded) {
      run();
    } else {
      scene.addEventListener('loaded', run);
    }
</script>




</html>

スタイルシート

style.css
* {
    margin: 0;
    padding: 0;
}

#loader {
    width: 100%;
    height: 100%;
    position: fixed;
    z-index: 100000000000;
    background-color: #333;
    color: #fff;
}

#loader>p {
    position: absolute;
    top: 50%;
    margin-top: -0.5em;
    width: 100%;
    text-align: center;
    font-size: 200%;
    font-weight: bold;
}

#loader.hidden {
    display: none;
}

.target {
    position: absolute;
    width: 1600px;
    height: 1000px;
    font-size: 500%;
    background-color: #FFF;
    display: hidden;
    /*z-index: 1;*/
}

.target>img {
    float: left;
    display: block;
    width: 32%;
    padding: 4% 0 4% 4%;
}

.target>div {
    margin-left: 36%;
    width: 52%;
    padding: 4%;
}

.target>.detail {
    padding: 3% 0;
    text-align: center;
    width: 92%;
    color: #fff;
    background-color: rgba(1, 1, 1, 0.6);
    margin: 4%;
}

ちょこっと解説・ポイント

今回はこのページを大変参考にさせて頂きました!
http://vr-lab.voyagegroup.com/entry/2016/11/16/122115

その中で、開発に慣れてなくてつまずいたことを記載しておきます。(初心者な内容もあり)

1. エディターのLive server的な機能でみると画像が崩れる時がある

「コメント部分消しただけなのに全体的になぜか崩れたぞ??」
→ これキャッシュが残ってるからでした。スーパーリロードしましょう。

// Mac版
Cmd + Shift + R

// Windows版
Shift + F5

2. 3次元空間ないのカーソルが出てこない

これを加えましょう。

       <a-entity>
            <a-camera>
              <a-cursor></a-cursor>
            </a-camera>
        </a-entity>

3. カーソルを追加したら達が出なくなった

要素は生き延びていたのですが、要素だけ軒並み非表示になってしまいました。。
おそらく奥行きの問題かと考え、をに変更しました。

4. 角度や場所の指定が難しい

ここは触りながら慣れるしかないですね。。
私もかなり苦労しました。

おわりに

A-Frameはすごいです。
3D空間を作ることに関しては、本当に何も考えることなくできました。
いろんなものが身近になってきていますね。

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

サイトの右側にできる余白を消す方法【HTML/CSS】

サイトを作っているときに画面右側にできる謎の余白を消したい

html
  <body>
    <div id="wrapper">この中に全てのソースコードをつっこむ</div>
  </body>
css
  #wrapper {
    width:100%;
    overflow:hidden;
  }

と書くことでサイトの右端にできていた謎の余白を消すことができた。

参考リンク:サイトの右にできる余白の解決方法がわかりません

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

子要素を親要素の中央に設置する方法【CSS】

子要素を親要素の上下左右で中央寄せする方法【CSS】

参考リンク:子要素を親要素内で上下左右中央寄せさせる方法

css
.parent{
  position: relative;
}

.child{
  position:absolute;
  top:50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

こうすることで親要素の中にある子要素を親要素の中央に設置することができた。

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