saoriri備忘録

tech とか コードについてとか色々

illustratorでSVGを保存するとid名が文字化けしてしまう

概要

illustratorで作成した画像をsvgで保存する際、
レイヤー 名で設定した文字中のアンダーバーが ”X5F” と文字化けしてしまい困りました。
対応策は、先に結論を言うと、illustratorで単純にsvg として保存するのではなく、ファイルタブから書き出しを選択しオプションを設定して書き出す、という手法をとることで解消されました。

経緯

illustratorは、デザイナーさんからいただいたデザインを確認する為に開くぐらいの程度しか触ったことありませんでしたが、
仕事でデザイナーさんにこういったsvgを作ってくださいというような指示用サンプルが必要となり、作成する際にid名の文字化け問題に直面した次第です。
なので、本職のデザイナーさんにとったら「そんなの常識だよ」と思われるかもしれませんが、備忘録として残します。


手順

① svg ファイルをjavascript でグリグリいじりたいので、いじりたいレイヤーごとにレイヤー名を振り分けます。
illustratorではsvgとして書き出す時に、レイヤー名で設定した名前が、svgのid名としてセットされます。

illustratorのレイヤー画面


② 《NGパターン》
illustratorでのsvg保存時、ファイルタブ→別名で保存→ファイル形式でsvgを選択、で保存し、svgファイルをエディタで開くと、id名が下の画像のように文字化けしてしまいます。

svgのid名文字化け


③ 《OKパターン》
なので、ファイルタブ→書き出し→書き出し形式を選択し、下の画像のようにオプションを選択してsvgファイルを書き出しすると、問題なくid名が設定されます。

illustratorファイル保存時オプション

最後に

なかなか "X5F アンダーバー 文字化け" などで調べても原因が出てこなかったので、ブログに残しました。
誰かの役に立ちますように。

再帰関数の理解を深める!

再帰関数への苦手意識

私、前々から再帰関数への苦手意識がありました。。。
(業務でもあまり使わないしなーと、ついつい理解を後回しにしていました。もごもご)
しかし競技プログラミングなんか見てみると頻出頻度が高いので、この際理解を深めようと思いました。

やりたい内容

▶︎0からnまで、以下のルールに則った総和であるresultを返す。
奇数の場合は、前の値を*2する。
偶数の場合は、前の値を+1する。
n=0の場合は、1を返す。


例)n:0〜6 ⇨ result:1, 2, 3, 6, 7, 14, 15
n=0の時result=1、n=1の時1*2でresult=2、
n=2の時2+1でresult=3、n=3の時3*2でresult=6、
n=4の時6+1でresult=7となる。

再帰関数を用いたパターン①と、理解を深める為にfor文で単純にループを回すパターン②と2つのパターンを書いてみました。

// ①再帰
let recursive = (n) => {
    if(n==0) return 1;
    return (n%2==1) ? recursive(n-1)*2 : recursive(n-1)+1; 
}

(() => {
    const n = 5;
    console.log(recursive(n)); // 14
})();
// ②再帰使わない
let recursive = (n) => {
    let result = 1;
    for (let i=0; i<=n; i++) {
        if (i==0) continue; 
        if (i%2==1) result *= 2;
        if (i%2==0) result += 1;
    }
     return result; 
}

(() => {
    const n = 5;
    console.log(recursive(n)); // 14
})();

終わりに

これからも引き続き再帰の概念を学んで行きます。。。
今回勉強する上でイメージがとても分かりやすかったサイトを載せます。感謝。

再帰関数を学ぶと、どんな世界が広がるか - Qiita

【Javascript】文字列から一文字ずつ比較して全て含まれている文字列のみ表示する

概要

どういう事をしたいかと言うと、
ターゲットの文字列"dog" として、doge は、"d", "o", "g" が含まれているからOK!
god"d", "o", "g" が含まれているからOK!
food"o", "g"は含まれているが"d"が含まれていないのでNG!
と言うルールです。

それではいざ!

ソース

const targetA = 'dog'
const wordBArray = ['good', 'god', 'food', 'dog']

const splitedA = targetA.split("") // ['d', 'o', 'g']
const result = wordBArray.filter((f, i, array) => {
    return splitedA.every(a => {
        return f.split("").some(b => a == b )    
    })
})
    console.log(result) // ['good', 'god', 'dog']
}

angular material の mat-button-toggle を使ってみる。

内容

angular material に装備されているmat-button-toggle を使用して、
トグルボタンを設定してみる。
調べてみたのですが、情報が比較的少なかったのでメモ。

// angularmaterial の toggleボタンモジュールをimportする
import {
   MatButtonToggleModule
} from '@angular/material';

@NgModule({
imports: [
    MatButtonToggleModule,
],  // 省略
})
<mat-button-toggle-group class="selectAll" #group=matButtonToggleGroup name="fontStyle" aria-label="Font Style">
    <mat-button-toggle value="select" (click)="imageSelectAll(group.value)">全選択</mat-button-toggle>
    <mat-button-toggle value="deselect" (click)="imageSelectAll(group.value)">解除</mat-button-toggle>
</mat-button-toggle-group>
// toggleボタンが押された時
imageSelectAll(value: string): void {
    const b = value === 'select';
    this.imageSelects.forEach( i => i.checked = b );
}

mat-button-toggle-group#group を設定。
そうすると、mat-button-togglevalueが有効になり、
clickなどアクションした時に、group.valueとして値を持っていく事ができます。


スタイル変更で詰まった...

angular material のデフォルトデザインから自分好みにスタイルを変えようと思いましたが、
なんだかうまいことスタイルがあたってくれない。泣
.mat-button-toggle-button と直接css指定してもダメ。泣

コンポーネントの階層が違うことが原因でした。
解決策としてng:deepを使用する事で解決。

.mat-button-toggle-group {
    margin-right: 30px;

    & ::ng-deep {
        .mat-button-toggle-label-content {
            line-height: 32px;
        }
        .mat-button-toggle-button {
            padding: 3px;
        }
        .mat-button-toggle-checked {
            background-color: #CCCCCC;
            color: white;
        }
    }
}

参考サイト

Angular Material

【javascript】配列から配列の特定要素を削除して別の配列として取り出す

概要

配列Aから配列Bの要素と合致するものを削除して、配列Cを作る処理です。
配列対配列の操作です。

javascript の配列操作の関数はとても便利なのですが、
メソッドチェーンの組み合わせで迷う事がしょっちゅうなので、覚え書きです。

filterとeveryを組み合わせます。


ソース

const arrayA = ['aaa', 'bbb', 'ccc', 'ddd', 'eee'];
const arrayB = ['bbb', 'ddd'];

const arrayC = arrayA.filter(a => 
    return arrayB.every(b => 
        b !== a
    )
);

console.log(arrayC);     // ['aaa', 'ccc', 'eee']