[Scratch3.0 拡張機能] 文字からユニコード番号に変換するちょっとしたエクステンションを作る
※ 当ページには【広告/PR】を含む場合があります。
2020/12/16
何かから何かを変換するブロックタイプ ~ レポーター
+ コマンドタイプ:
何かの処理を実行するブロック
+ レポータータイプ:
文字列や数値を返すブロック
+ ブーリアンタイプ:
判定を行うブロック
+ ハットタイプ:
イベントを監視・処理をするブロック
文字のユニコード番号をコスチューム画像の識別に利用したい
Scratch3エクステンションの作成
エクステンションのブロック表紙絵とアイコン画像
str2unicode.png
str2unicode-small.png
scratch-gui/src/lib/libraries/extensions/str2unicode
index.jsxの中身を修正
scratch-gui/src/lib/libraries/extensions
index.jsx
str2unicode
import React from 'react';
import {FormattedMessage} from 'react-intl';
//...中略
//👇先程作った画像までのリソースパスを定義
import str2unicodeURL from './str2unicode/str2unicode.png';
import str2unicodeIconURL from './str2unicode/str2unicode-small.png';
export default [
///...中略
//👇拡張機能を追加登録
{
name: '文字からユニコードへ変換',
extensionId: 'str2unicode',
iconURL: str2unicodeURL,
insetIconURL: str2unicodeIconURL,
description: (
<FormattedMessage
defaultMessage="文字からユニコードを調べます"
description="Description for the 'Str2Unicode' extension"
id="gui.extension.str2unicode.description"
/>
),
featured: true
}
];
拡張機能の中身を実装
scratch-vm/src/extensions
scratch3_str2unicode
const ArgumentType = require('../../extension-support/argument-type');
const BlockType = require('../../extension-support/block-type');
const Cast = require('../../util/cast');
const log = require('../../util/log');
// 👇先程作成したアイコン画像
const commonSvgIcon = 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzOC4zMDIgMzguNDc1IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5Mi44OCAtMTcyLjU0KSI+CiAgPGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2UtZGFzaGFycmF5PSIiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuNSIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOm5vcm1hbCIgZGF0YS1wYXBlci1kYXRhPSd7ImlzUGFpbnRpbmdMYXllciI6dHJ1ZX0nPgogICA8cGF0aCBkPSJtMTkzLjEzIDIxMC43NnYtMzcuOTc1aDM3LjgwMnYzNy45NzV6Ii8+CiAgPC9nPgogPC9nPgogPHBhdGggZD0ibTE5LjgyOCAxNi41NzItNi40ODgyLTAuNDI2MjYtNC41ODkyIDQuNjA2Mi0xLjU5OTYtNi4zMDIzLTUuNzk4OS0yLjk0MTIgNS40OTk2LTMuNDY4OCAxLjAwNTMtNi40MjQgNC45OTg1IDQuMTU4NSA2LjQyMDItMS4wMjkxLTIuNDEwNCA2LjAzODl6IiBzdHlsZT0iZmlsbDojZDQ1NTAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6MS40O3N0cm9rZTojMDAwMDAwIi8+CiA8cGF0aCBkPSJtMjkuMjYgMzYuOTcxYy0xLjgxNzYtMS43NDUzLTMuNjM1Mi0zLjQ5MDUtNS40NTI3LTUuMjM1OC0yLjUwMDEgMC4yMjYzNC01LjAwMDIgMC40NTI2OC03LjUwMDQgMC42NzkwMiAxLjA4NTUtMi4yNzQ5IDIuMTcxMS00LjU0OTggMy4yNTY2LTYuODI0Ny0wLjk5MDkzLTIuMzIxOS0xLjk4MTktNC42NDM4LTIuOTcyOC02Ljk2NTcgMi40ODg1IDAuMzM5MzEgNC45NzcgMC42Nzg2MiA3LjQ2NTQgMS4wMTc5IDEuODg3Ny0xLjY2MTQgMy43NzU0LTMuMzIyNyA1LjY2MzEtNC45ODQxIDAuNDUyNDMgMi40ODQ2IDAuOTA0ODYgNC45NjkyIDEuMzU3MyA3LjQ1MzggMi4xNTc2IDEuMjk1MSA0LjMxNTIgMi41OTAzIDYuNDcyOCAzLjg4NTQtMi4yMDg5IDEuMTk2My00LjQxNzcgMi4zOTI1LTYuNjI2NiAzLjU4ODgtMC41NTQyMyAyLjQ2MTgtMS4xMDg1IDQuOTIzNi0xLjY2MjcgNy4zODU0eiIgc3R5bGU9ImZpbGw6I2IyNTVhMTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjEuNDtzdHJva2U6IzAwMDAwMCIvPgogPGcgdHJhbnNmb3JtPSJyb3RhdGUoLTQwLjA2MikiIHN0eWxlPSJmaWxsOiMwMDAwMDAiIGFyaWEtbGFiZWw9IuaWh+WtlyI+CiAgPHBhdGggZD0ibTkuNTMyOCAyMi43ODdoLTEuNDA1OGMtMC4wMjcwNzQtMC45MDIxNiAxLjE5NzItMC40Mjc3NyAxLjgxMzUtMC41MjgxOGgxLjMzNTh2LTEuNDU3NWMxLjIzMjYtMC4yMjIzNS0wLjAzMDUyIDIuMDYzNSAxLjQ1NjcgMS40NTc1aDIuMzcxNmMwLjA4Mzk5IDEuMTMxNy0xLjgxMTItMC4wOTUxOC0xLjczMiAxLjE2NDIgMC4wMDQ4IDAuOTM2MS0xLjI2NjkgMS43NzM3LTEuMDIxMiAyLjUxMDkgMC42NzI4OCAwLjY2NDM1IDIuMjYwNCAwLjgzMjIxIDIuNjE2MyAxLjMyMTYtMC4zNTE1MiAwLjkyNTA3LTEuMjg2IDAuMDEzMS0xLjg5OS0wLjE2Mzk1LTAuNzgzNzUtMC4zMTM5NS0xLjQwNS0xLjM3NzktMi4wOTgyLTAuMzc1NjMtMC43NDMzMSAwLjI3NzgzLTIuMDIwOSAxLjYwMjUtMi42NDg1IDAuODE0NjUtMC41MTE1NC0wLjU5NzU2IDEuMTQ5OS0wLjQxNTggMS40NTgyLTAuODI1MjIgMC43MDk3Ny0wLjM1NjUxIDIuMDI1OS0wLjg1NDMzIDAuOTExNDItMS41ODk1LTAuNTE0ODktMC43MDM0MS0wLjg4OTgxLTEuNTAxOS0xLjE1ODctMi4zMjg5em0wLjYxMTU4IDBjMC4zMjcxMyAwLjgzNDI2IDAuODgxMjQgMi4zMjQxIDEuNjMyNyAyLjQzNzcgMC40MDkwOC0wLjYwNjI4IDEuMzk0LTIuMDI3NCAwLjkwOTk5LTIuNDM3N2gtMi41NDI3eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtzdHJva2Utd2lkdGg6LjM4MTI0Ii8+CiAgPHBhdGggZD0ibTIwLjAyOSAyMS43MzloMi45OTgzdjEuNjQwMWMtMC45ODA0NCAwLjM0OTE3LTAuMjE0NTMtMS42MzU2LTEuMzk3LTEuMTI3NC0xLjUyLTJlLTMgLTMuMDM5OSA1LjM2ZS00IC00LjU1OTktNS4zNGUtNHYxLjEyNzhjLTAuODEzNjIgMC4yODM2My0xLjAwMzMtMS45MzczLTAuMDk4MDQtMS42NDAxaDIuNDM3MXYtMS4xMTU5YzAuNzA0MzItMC4yNzM5MyAwLjY3MTE5IDAuNzAyMjMgMC42MTk1MiAxLjExNnptMC4wNTU2IDIuODQzNGMwLjIwMzM5IDAuODAzNjUgMS4zMTQxIDAuMjgyNCAxLjk3MDMgMC40MDkwNGgxLjI3NDNjMC4wMjcwNyAwLjkwMjE2LTEuMTk3MiAwLjQyNzc3LTEuODEzNSAwLjUyODE4aC0xLjM4NzRjLTAuMTQ1MzQgMC44MjA4NCAwLjQ1MTIzIDIuMTYxOC0wLjY4MzU0IDIuNDczNC0wLjkyNzc4IDAuMjg0MzMtMS41Njc5LTAuNzc4MzYtMC4zMDg4OC0wLjY1ODkxIDAuNzUxODQtMC4yNDI1NSAwLjI2NDc0LTEuMDQyMiAwLjM4MDg1LTEuNjA5IDAuMDUyOTktMC40MTMwMi0wLjYwNDU0LTAuMTE1NTEtMC44NzQ2Ni0wLjIwNTQyaC0yLjQ2MTJjLTAuMDI3MDctMC45MDIxNiAxLjE5NzItMC40Mjc3NyAxLjgxMzUtMC41MjgxOGgxLjQ4NjdjLTAuNTk3OTgtMC44NjI4NSAyLjIwMzMtMS4zNjA3IDAuNTgyMjUtMS40MTQ0LTAuODEwNTYtMC4xNTM2Ni0yLjEyODQgMC4yOTIzMS0yLjYwNzEtMC4yMjk5MSAwLjM3OTY4LTAuNjA1MzkgMS4yNzIyLTAuMjE0NTIgMS44OTktMC4zMDk1OWgyLjQ0NWMwLjI0MzA4IDAuOTk1Ny0xLjE5MjkgMS4wNDM0LTEuNzE1NiAxLjU0NDh6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO3N0cm9rZS13aWR0aDouMzgxMjQiLz4KIDwvZz4KIDxnIHRyYW5zZm9ybT0icm90YXRlKDUxLjYwNikiIHN0eWxlPSJmaWxsOiMwMDAwMDAiIGFyaWEtbGFiZWw9IjB4ZGRkZCI+CiAgPHBhdGggZD0ibTE3Ljk0NSA3Ljg1NjJjLTEuMTc5MyAwLjM1NDc1LTAuOTMzODIgMS44NC0wLjkxMDM1IDIuNzc3OSAwLjUzMTggMS40OTc0IDIuMjYzNiAwLjM2NDMyIDEuODU4OC0wLjkwMjk5LTAuMDA4NS0wLjY2ODgyLTAuMTAwNjgtMS43ODM2LTAuOTQ4NDctMS44NzQ5em0wLTAuNDcwOTFjMS40NzMgMC4wNzk1OTQgMS43MDA3IDEuOTI4OSAxLjQ5NTQgMy4wNzc5LTAuMDc2NSAxLjI5MDktMS44ODc2IDIuMTE0MS0yLjYzMTMgMC44NTE0My0wLjYxMTI5LTEuMTAzOS0wLjU4MTMxLTIuNzIyNCAwLjMxMzYyLTMuNjY2NiAwLjIyNzMzLTAuMTg5OTIgMC41Mjg1LTAuMjc2NiAwLjgyMjIyLTAuMjYyNjR6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO3N0cm9rZS13aWR0aDouMzIyOTEiLz4KICA8cGF0aCBkPSJtMjMuMTc1IDguNTYyNmMtMC4zOTczMyAwLjUzNDY4LTAuNzk0NjYgMS4wNjk0LTEuMTkyIDEuNjA0IDAuNDE3OTMgMC41NjQxMSAwLjgzNTg2IDEuMTI4MiAxLjI1MzggMS42OTIzLTAuOTIxNjQgMC41NTA3NC0xLjI3MDEtMS45MzQ2LTIuMDQ4Ni0wLjY4Ny0wLjE3MzM0IDAuNzEwNzUtMS4zOTA0IDAuOTQ0NzQtMC42NDYyLTAuMDM2MTEgMS4wMTA5LTAuNjY5MTkgMC41NTEtMS41MTc3LTAuMTI1MDktMi4yMTQ0LTAuNjA3MzYtMC45NzI2NyAwLjk5MTMgMC4xNTE2NiAxLjE4ODkgMC41ODMwMSAwLjY0MzA0IDAuMDY4MDQ0IDAuNjM4MTQtMS4zMjggMS41NjkyLTAuOTQxOXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWw7c3Ryb2tlLXdpZHRoOi4zMjI5MSIvPgogIDxwYXRoIGQ9Im0yNi4xNzEgOS4wNjI5di0xLjc4MzZjMS4wNDU0IDAuMjI0ODEgMC4zODE4NiAxLjY2NyAwLjU0MTU0IDIuNDk4OXYyLjA4MDdjLTAuOTcwMjktMC40MzQ3Ny0yLjI1ODQgMC42NzMzMy0yLjgxMi0wLjc5MjU5LTAuNTgxOTktMS4wNjQ4IDAuMjA3MjMtMi44NTkxIDEuNTY2Ni0yLjU1MjcgMC4yOTY0NSAwLjA3NzA3NyAwLjU1NTc5IDAuMjgxNzIgMC43MDM5MiAwLjU0OTI4em0tMS44NDU0IDEuMTUwOGMtMC4zODAzIDEuNjgwNCAyLjUzMjggMS40MTMyIDEuOTIwMi0wLjI1NDktMC4yODE1NC0xLjM0MTctMi4xMjc0LTEuMjM2Ni0xLjkyMDIgMC4yNTQ5eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtzdHJva2Utd2lkdGg6LjMyMjkxIi8+CiAgPHBhdGggZD0ibTI5Ljk5NyA5LjA2Mjl2LTEuNzgzNmMxLjA0NTQgMC4yMjQ4MSAwLjM4MTg2IDEuNjY3IDAuNTQxNTQgMi40OTg5djIuMDgwN2MtMC45NzAyOS0wLjQzNDc3LTIuMjU4NCAwLjY3MzMzLTIuODEyLTAuNzkyNTktMC41ODE5OS0xLjA2NDggMC4yMDcyMy0yLjg1OTEgMS41NjY2LTIuNTUyNyAwLjI5NjQ1IDAuMDc3MDc3IDAuNTU1NzkgMC4yODE3MiAwLjcwMzkyIDAuNTQ5Mjh6bS0xLjg0NTQgMS4xNTA4Yy0wLjM4MDMgMS42ODA0IDIuNTMyOCAxLjQxMzIgMS45MjAyLTAuMjU0OS0wLjMzOTA0LTEuMzM5OS0yLjA3MzYtMS4yNzQ4LTEuOTIwMiAwLjI1NDl6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO3N0cm9rZS13aWR0aDouMzIyOTEiLz4KICA8cGF0aCBkPSJtMzMuODIzIDkuMDYyOXYtMS43ODM2YzEuMDQ1NCAwLjIyNDgxIDAuMzgxODYgMS42NjcgMC41NDE1NCAyLjQ5ODl2Mi4wODA3Yy0wLjk3MDI5LTAuNDM0NzctMi4yNTg0IDAuNjczMzMtMi44MTItMC43OTI1OS0wLjU4MjA0LTEuMDY0OCAwLjIwNzM1LTIuODU5MyAxLjU2NjctMi41NTI2IDAuMjk2NDggMC4wNzY5NDEgMC41NTU1MyAwLjI4MTc4IDAuNzAzNzIgMC41NDkyem0tMS44NDU0IDEuMTUwOGMtMC4zODAzIDEuNjgwNCAyLjUzMjggMS40MTMyIDEuOTIwMi0wLjI1NDktMC4zMzkwNC0xLjMzOTktMi4wNzM2LTEuMjc0OC0xLjkyMDIgMC4yNTQ5eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtzdHJva2Utd2lkdGg6LjMyMjkxIi8+CiAgPHBhdGggZD0ibTM3LjY1IDkuMDYyOXYtMS43ODM2YzEuMDQ1NCAwLjIyNDgxIDAuMzgxODYgMS42NjcgMC41NDE1NCAyLjQ5ODl2Mi4wODA3Yy0wLjk3MDI5LTAuNDM0NzctMi4yNTg0IDAuNjczMzMtMi44MTItMC43OTI1OS0wLjU4MTk5LTEuMDY0OCAwLjIwNzIzLTIuODU5MSAxLjU2NjYtMi41NTI3IDAuMjk2NDUgMC4wNzcwNzcgMC41NTU3OSAwLjI4MTcyIDAuNzAzOTIgMC41NDkyOHptLTEuODQ1NCAxLjE1MDhjLTAuMzgwMyAxLjY4MDQgMi41MzI4IDEuNDEzMiAxLjkyMDItMC4yNTQ5LTAuMzM5MDQtMS4zMzk5LTIuMDczNi0xLjI3NDgtMS45MjAyIDAuMjU0OXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWw7c3Ryb2tlLXdpZHRoOi4zMjI5MSIvPgogPC9nPgo8L3N2Zz4K';
const blockIconURI = commonSvgIcon;
const menuIconURI = commonSvgIcon;
class Scratch3Str2Unicode {
constructor (runtime) {
this.runtime = runtime;
}
getInfo () {
return {
id: 'str2unicode',
name: 'String To Unicode#',
menuIconURI: menuIconURI,
blockIconURI: blockIconURI,
blocks: [
{
opcode: 'writeLog',
blockType: BlockType.COMMAND,
text: 'log [TEXT]',
arguments: {
TEXT: {
type: ArgumentType.STRING,
defaultValue: "hello"
}
}
},
{
opcode: 'getBrowser',
text: 'browser',
blockType: BlockType.REPORTER
}
],
menus: {
}
};
}
writeLog (args) {
const text = Cast.toString(args.TEXT);
log.log(text);
}
getBrowser () {
return navigator.userAgent;
}
}
module.exports = Scratch3Str2Unicode;
scratch-vmの拡張機能リストに追加
scratch-vm/src/extension-support/extension-manager.js
const dispatch = require('../dispatch/central-dispatch');
const log = require('../util/log');
const maybeFormatMessage = require('../util/maybe-format-message');
const BlockType = require('./block-type');
// These extensions are currently built into the VM repository but should not be loaded at startup.
// TODO: move these out into a separate repository?
// TODO: change extension spec so that library info, including extension ID, can be collected through static methods
const builtinExtensions = {
//...中略
//👇新規エクステンションのindex.jsのパスで登録
str2unicode: () => require('../extensions/scratch3_str2unicode')
};
//...以下略
エクステンションの動作確認
$ npm start
#OR
$ yarn start
http://localhost:8601
codePointAtメソッド
// "あ"のコードポイントを取得
console.log("あ".codePointAt(0)); // => 12354
// "あ"のコードポイントを取得
console.log("あ".codePointAt(0)).toString(16); // => 3042
文字からコードポイントを返すスクラッチブロック
scratch-vm/src/extensions/scratch3_str2unicode/index.js
const ArgumentType = require('../../extension-support/argument-type');
///...略
class Scratch3Str2Unicode {
///...略
getInfo () {
return {
id: 'str2unicode',
///...略
blocks: [
///...略
//👇①レポータータイプの(引数あり)関数を定義
{
opcode: 'getCodePoint',
text: '文字>コードポイント [STR]',
blockType: BlockType.REPORTER,
arguments: {
STR: {
type: ArgumentType.STRING,
defaultValue: 'あ'
}
}
}
],
///...略
};
}
//👇②文字をコードポイントに変換するレポーター
getCodePoint (args) {
//👇STRで定義していた引数を受け取る
const text = Cast.toString(args.STR);
//👇文字からポイントコードポイントへ変換して返す
return text.codePointAt(0).toString(16);
}
}
///...以下略
+ COMMAND:
関数を実行するブロック。
引数を定義して利用することも可能
+ REPORTER:
特定の文字列や数値などを返すブロック。
引数を与えて利用することもできる
+ BOOLEAN:
判定に特化したブロック。
true/falseのどちらかを返す。
引数を与えて真偽を判断して返すことも可能。
+ HAT:
エクステンションのコード内部の変数(true/false)を監視して、
trueのときにだけ処理を実行するブロック。
イベントのトリガーとして利用できる
まとめ
参考サイト
記事を書いた人
ナンデモ系エンジニア
これからの"地方格差"なきプログラミング教育とは何かを考えながら、 地方密着型プログラミング学習関連テーマの記事を不定期で独自にブログ発信しています。
カテゴリー