クリッピング マスキング について(その5) – クリッピングパスのグループ化

Posted コメントするカテゴリー: javascript

クリッピング マスキング について(その5) – クリッピングパスのグループ化

クリッピングパスその5は、クリッピングされる対象(本サンプルでは画像)のDOM要素を、
gタグで囲い、グルーピングを行ったうえでクリッピングする例を試してみます。

一つのクリッピングする側の要素を、gタグで囲い、gタグで囲った要素をひとまとめにして制御することが可能です。

今回のサンプルでは、楕円(ellipse)を一つ用意し、

<ellipse
    id="ellipse_group"
    cx="200"
    cy="100"
    rx="100"
    ry="150"
    fill-opacity="0.2"
/>

それをgタグで囲った中で4つのクリッピング(する側)の要素として記述し、

<g clip-path="url(#test_clip_dom1)">
    <use href="#ellipse_group" x="0" y="0" fill="#808080" />
    <use href="#ellipse_group" x="0" y="0" fill="#4169e1" transform="rotate(30,120,120)" />
    <use href="#ellipse_group" x="0" y="0" fill="#3cb371" transform="rotate(60,120,120)" />
    <use href="#ellipse_group" x="0" y="0" fill="#ff0011" transform="rotate(90,120,120)" />
</g>

楕円(ellipse)のパラメータを動的にスライダで変更、確認できる画面を用意しました。

下記、サンプルの全体です。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
    font-size : 0.9em;
    padding-bottom: 10px;
}
.range {
    width: 500px;
}
.code_view {
    font-size : 0.8em;
    padding: 5px;
    background-color: #000000;
    color: #ffffff;
}
#code_view1, #code_view2, #code_view3, #code_view4  {
    color: #ff0000;
}
</style>

</head>
<body>

<svg width="500" height="320" viewBox="0 0 500 320">
    <defs>
        <ellipse
            id="ellipse_group"
            cx="280"
            cy="200"
            rx="70"
            ry="70"
            fill-opacity="0.2"
        />
        <clipPath id="test_clip_dom1">
            <circle cx="160" cy="160" r="150">
        </clipPath>
    </defs>
    <g clip-path="url(#test_clip_dom1)">
        <use href="#ellipse_group" x="0" y="0" fill="#808080" />
        <use href="#ellipse_group" x="0" y="0" fill="#4169e1" transform="rotate(30,120,120)" />
        <use href="#ellipse_group" x="0" y="0" fill="#3cb371" transform="rotate(60,120,120)" />
        <use href="#ellipse_group" x="0" y="0" fill="#ff0011" transform="rotate(90,120,120)" />
    </g>

</svg>

<div>
    <div class="params_box">
        <div>
        <input type="range" class="range" id="range1" value="40" max="500">
        param1 : <span class="params" id="range1_value"></span>
        </div>

        <div>
        <input type="range" class="range" id="range2" value="140" max="500">
        param2 : <span class="params" id="range2_value"></span></span>
        </div>

        <div>
        <input type="range" class="range" id="range3" value="100" max="500">
        param3 : <span class="params" id="range3_value"></span></span>
        </div>

        <div>
        <input type="range" class="range" id="range4" value="100" max="500">
        param4 : <span class="params" id="range4_value"></span></span>
        </div>

    </div>
</div>

<div class="code_view">
&lt;ellipse<br />
  id="ellipse_group"<br />
  cx="<span id="code_view1"></span>"<br />
  cy="<span id="code_view2"></span>"<br />
  rx="<span id="code_view3"></span>"<br />
  ry="<span id="code_view4"></span>"<br />
  fill-opacity="0.2"<br />
/&gt;<br />
</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);

// スライダーを動かした時の処理
function change_range_slider()
{
    console.log("range1_dom.value -> " + range1_dom.value);
    console.log("range2_dom.value -> " + range2_dom.value);
    console.log("range3_dom.value -> " + range3_dom.value);
    console.log("range4_dom.value -> " + range4_dom.value);

    // クリップする側の要素を取得する
    let test_clip_dom1 = document.getElementById('ellipse_group');
    console.log("test_clip_dom1 -> " + test_clip_dom1);

    // SVG要素の x y font の値を設定する
    test_clip_dom1.setAttribute('cx' , range1_dom.value);
    test_clip_dom1.setAttribute('cy' , range2_dom.value);
    test_clip_dom1.setAttribute('rx'  , range3_dom.value);
    test_clip_dom1.setAttribute('ry'  , range4_dom.value);

    // パラメータ値を出力
    let range1_value_dom = document.getElementById('range1_value');
    let range2_value_dom = document.getElementById('range2_value');
    let range3_value_dom = document.getElementById('range3_value');
    let range4_value_dom = document.getElementById('range4_value');

    range1_value_dom.innerHTML = range1_dom.value;
    range2_value_dom.innerHTML = range2_dom.value;
    range3_value_dom.innerHTML = range3_dom.value;
    range4_value_dom.innerHTML = range4_dom.value;

    // DOM要素 「id="test_clip_dom1" 」の 各パラメータを動的に出力する
    let code_view1_dom = document.getElementById('code_view1');
    let code_view2_dom = document.getElementById('code_view2');
    let code_view3_dom = document.getElementById('code_view3');
    let code_view4_dom = document.getElementById('code_view4');
    code_view1_dom.innerHTML = range1_dom.value;
    code_view2_dom.innerHTML = range2_dom.value;
    code_view3_dom.innerHTML = range3_dom.value;
    code_view4_dom.innerHTML = range4_dom.value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、半径150ピクセル、中心位置 x:160、y:160の円に対して、
gタグで囲った中で4つのクリッピング要素をもとにクリッピングされていることがわかります。

また、スライダを動的に変更すると、クリッピングする要素がグループとして作用していることがわかります。

下記のキャプチャ例は、スライダーを調整した例です。

例1

例2

例3

例4

クリッピング マスキング について(その4) – 文字列でのクリッピングパス

Posted コメントするカテゴリー: javascript

クリッピング マスキング について(その4) – 文字列でのクリッピングパス

クリッピングパスその4はクリッピングされる対象(本サンプルでは画像)のDOM要素を、
文字列でクリッピングするサンプルを試してみます。

クリッピングされる対象と、クリッピングする対象の関係はこれまでのサンプルと同様で、
クリッピングする要素が text 要素で指定されているという違いのみになります。

下記のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
    font-size : 0.8em;
    padding-bottom: 10px;
}
.range {
    width: 400px;
}
.code_view {
    font-size : 0.8em;
    padding: 5px;
    background-color: #000000;
    color: #ffffff;
}
#code_view1, #code_view2, #code_view3  {
    color: #ff0000;
}
</style>

</head>
<body>

<svg width="500" height="250" viewBox="0 0 500 250">

    <defs>
        <clipPath id="test_clip_dom1">
            <text
                id="test_clip_path1"
                x="30"
                y="70"
                font-size="50"
                font-weight="bold"
            >enaga</text>
        </clipPath>
    </defs>
    
    <image href="./sima.jpg" clip-path="url(#test_clip_dom1)" width="400" height="226"/>
    
</svg>

<div>
    <div class="params_box">
        <span>param1 : </span><span class="params" id="range1_value"></span>
        <div><input type="range" class="range" id="range1" value="40" max="500"></div>
    </div>
    <div class="params_box">
        <span>param2 : <span class="params" id="range2_value"></span></span>
        <div><input type="range" class="range" id="range2" value="140" max="500"></div>
    </div>
    <div class="params_box">
        <span>param3 : <span class="params" id="range3_value"></span></span>
        <div><input type="range" class="range" id="range3" value="100" max="500"></div>
    </div>
</div>

<div class="code_view">
&lt;clipPath id="test_clip_dom1"&gt;<br />
  &lt;text<br />
    id="test_clip_path1"<br />
    x = "<span id="code_view1"></span>"<br />
    y = "<span id="code_view2"></span>"<br />
    font-size ="<span id="code_view3"></span>"<br />
  /&gt;<br />
&lt;/clipPath&gt;<br />
</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);

// スライダーを動かした時の処理
function change_range_slider()
{
    console.log("range1_dom.value -> " + range1_dom.value);
    console.log("range2_dom.value -> " + range2_dom.value);
    console.log("range3_dom.value -> " + range3_dom.value);

    // クリップする側の要素を取得する
    let test_clip_path1 = document.getElementById('test_clip_path1');
    console.log("test_clip_path1 -> " + test_clip_path1);

    // SVG要素の x y font の値を設定する
    test_clip_path1.setAttribute('x'        , range1_dom.value);
    test_clip_path1.setAttribute('y'        , range2_dom.value);
    test_clip_path1.setAttribute('font-size', range3_dom.value);

    // パラメータ値を出力
    let range1_value_dom = document.getElementById('range1_value');
    let range2_value_dom = document.getElementById('range2_value');
    let range3_value_dom = document.getElementById('range3_value');

    range1_value_dom.innerHTML = range1_dom.value;
    range2_value_dom.innerHTML = range2_dom.value;
    range3_value_dom.innerHTML = range3_dom.value;

    // DOM要素 「id="test_clip_path1" 」の 各パラメータを動的に出力する
    let code_view1_dom = document.getElementById('code_view1');
    let code_view2_dom = document.getElementById('code_view2');
    let code_view3_dom = document.getElementById('code_view3');
    code_view1_dom.innerHTML = range1_dom.value;
    code_view2_dom.innerHTML = range2_dom.value;
    code_view3_dom.innerHTML = range3_dom.value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、テキスト要素の位置、サイズにより、元画像がクリッピングされることがわかります。

下記のキャプチャ例は、スライダーを調整した一例です。

クリッピング マスキング について(その3) – 複数のクリッピングパス要素について

Posted コメントするカテゴリー: javascript

クリッピング マスキング について(その3) – 複数のクリッピングパス要素について

クリッピングについて、さらに調べてみます。

前回投稿したクリッピングの処理について、クリッピングするパスが複数あるケースを試してみます。

用意したサンプルでは、前回のスライダで動的に変更可能なパスと、ellipse(楕円)、polygon(多角形)の3つを用意しました。

ellipse(楕円)は単体で描画すると、下記のような楕円です。

<ellipse
    cx="90"
    cy="30"
    rx="80"
    ry="30"
    stroke="#000000"
    stroke-width="1"
    fill="none"
/>

また、polygon(多角形)を単体で描画すると、下記のような多角形になります。

<polygon
    points="10 15 25 120 50 180 75 95 98 250 105 140 130 175 135 210 150 135"
    stroke="#000000"
    stroke-width="1"
    fill="none"
/>

この二つのパスは、当ブログの過去に投稿した際のサンプルを流用していますが、
記述するパスは特に指定はありません。

この3つのパスを使ってクリッピングする下記のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
    font-size : 0.8em;
    padding-bottom: 10px;
}
.range {
    width: 400px;
}
.code_view {
    font-size : 0.8em;
    padding: 5px;
    background-color: #000000;
    color: #ffffff;
}
#code_view1 {
    color: #ff0000;
}
</style>

</head>
<body>

<svg width="500" height="270" viewBox="0 0 500 270">

    <defs>
        <clipPath id="test_clip_dom1">
            <path
                id="test_clip_path1"
                d='M16 238 L236 246 L242 22 Z'
                rx="150"
                ry="100"
                cx="200"
                cy="120"
                stroke="#999999"
                stroke-width="1"
                fill="#cccccc"
            />

            <ellipse
                cx="90"
                cy="30"
                rx="80"
                ry="30"
                stroke="#000000"
                stroke-width="1"
                fill="none"
            />

            <polygon
                points="10 15 25 120 50 180 75 95 98 250 105 140 130 175 135 210 150 135"
                stroke="#000000"
                stroke-width="1"
                fill="none"
            />

        </clipPath>
    </defs>
    
    <image href="./sima.jpg" clip-path="url(#test_clip_dom1)" width="400" height="226"/>
    
</svg>

<div>

    <div class="params_box">
        <span>param1 : </span><span class="params" id="range1_value"></span>
        <div><input type="range" class="range" id="range1" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>param2 : <span class="params" id="range2_value"></span></span>
        <div><input type="range" class="range" id="range2" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>param3 : <span class="params" id="range3_value"></span></span>
        <div><input type="range" class="range" id="range3" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>param4 : <span class="params" id="range4_value"></span></span>
        <div><input type="range" class="range" id="range4" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>param5 : <span class="params" id="range5_value"></span></span>
        <div><input type="range" class="range" id="range5" value="300" max="500"></div>
    </div>

    <div class="params_box">
        <span>param6 : <span class="params" id="range6_value"></span></span>
        <div><input type="range" class="range" id="range6" value="200" max="500"></div>
    </div>

</div>

<div class="code_view">
&lt;clipPath id="test_clip_dom1"&gt;<br />
  &lt;path<br />
    id="test_clip_path1"<br />
    d = "<span id="code_view1"></span>"<br />
    rx="150"<br />
    ry="100"<br />
    cx="200"<br />
    cy="120"<br />
    stroke="#999999"<br />
    stroke-width="1"<br />
    fill="#cccccc"<br />
  /&gt;<br />
&lt;/clipPath&gt;<br />
</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');
let range5_dom = document.getElementById('range5');
let range6_dom = document.getElementById('range6');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);
range5_dom.addEventListener('input', change_range_slider);
range6_dom.addEventListener('input', change_range_slider);

// スライダーを動かした時の処理
function change_range_slider()
{
    console.log("range1_dom.value -> " + range1_dom.value);
    console.log("range2_dom.value -> " + range2_dom.value);
    console.log("range3_dom.value -> " + range3_dom.value);
    console.log("range4_dom.value -> " + range4_dom.value);
    console.log("range5_dom.value -> " + range5_dom.value);
    console.log("range6_dom.value -> " + range6_dom.value);

    // クリップする側の要素を取得する
    let test_clip_path1 = document.getElementById('test_clip_path1');
    console.log("test_clip_path1 -> " + test_clip_path1);

    let d_value = '';
    
    // DOM要素 「id="test_clip_path1" 」の d のパラメータ
    d_value = 'M' + range1_dom.value + ' ' + range2_dom.value
            + ' L' + range3_dom.value + ' ' + range4_dom.value
            + ' L' + range5_dom.value + ' ' + range6_dom.value
            + ' Z';

    // SVG要素の d の値を設定する
    test_clip_path1.setAttribute('d', d_value);

    // パラメータ値を出力
    let range1_value_dom = document.getElementById('range1_value');
    let range2_value_dom = document.getElementById('range2_value');
    let range3_value_dom = document.getElementById('range3_value');
    let range4_value_dom = document.getElementById('range4_value');
    let range5_value_dom = document.getElementById('range5_value');
    let range6_value_dom = document.getElementById('range6_value');

    range1_value_dom.innerHTML = range1_dom.value;
    range2_value_dom.innerHTML = range2_dom.value;
    range3_value_dom.innerHTML = range3_dom.value;
    range4_value_dom.innerHTML = range4_dom.value;
    range5_value_dom.innerHTML = range5_dom.value;
    range6_value_dom.innerHTML = range6_dom.value;

    // DOM要素 「id="test_clip_path1" 」の d のパラメータを動的に出力する
    let code_view1_dom = document.getElementById('code_view1');
    code_view1_dom.innerHTML = d_value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、3つのパス要素が出力され、元画像の表示をクリッピングしていることがわかります。

このように1つのパスでは表現が難しいクリッピングを、複数のパスで実現することができます。

クリッピング マスキング について(その2) – クリッピングパスに画像を使用した場合

Posted コメントするカテゴリー: javascript

クリッピング マスキング について(その2) – クリッピングパスに画像を使用した場合

クリッピングについて、さらに調べてみます。

クリッピングは「元(クリップされる側)のDOM要素を、クリップする側の要素で、切り抜く」ような動きをすると言えます。
前回のサンプルでは、元のDOM要素も、クリップする側の要素も図形の要素を用いていたので、切り抜く側、切り抜かれる側の区別が把握しずらかったです。

今回は、クリップされる側(元のDOM要素)に画像を使って、動きを見てみます。

元の画像は、下記のようなjpg画像(サイズは、横400px 縦266px)を用意しました。

次に、その画像をクリッピングする下記のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
    font-size : 0.8em;
    padding-bottom: 10px;
}
.range {
    width: 400px;
}
.code_view {
    font-size : 0.8em;
    padding: 5px;
    background-color: #000000;
    color: #ffffff;
}
#code_view1 {
    color: #ff0000;
}
</style>

</head>
<body>

<svg width="500" height="270" viewBox="0 0 500 270">

    <defs>
        <clipPath id="test_clip_dom1">
            <path
                id="test_clip_path1"
                d='M16 238 L236 246 L242 22 Z'
                rx="150"
                ry="100"
                cx="200"
                cy="120"
                stroke="#999999"
                stroke-width="1"
                fill="#cccccc"
            />
        </clipPath>
    </defs>
    
    <image href="./sima.jpg" clip-path="url(#test_clip_dom1)" width="400" height="226"/>
    
</svg>

<div>

    <div class="params_box">
        <span>param1 : </span><span class="params" id="range1_value"></span>
        <div><input type="range" class="range" id="range1" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>param2 : <span class="params" id="range2_value"></span></span>
        <div><input type="range" class="range" id="range2" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>param3 : <span class="params" id="range3_value"></span></span>
        <div><input type="range" class="range" id="range3" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>param4 : <span class="params" id="range4_value"></span></span>
        <div><input type="range" class="range" id="range4" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>param5 : <span class="params" id="range5_value"></span></span>
        <div><input type="range" class="range" id="range5" value="300" max="500"></div>
    </div>

    <div class="params_box">
        <span>param6 : <span class="params" id="range6_value"></span></span>
        <div><input type="range" class="range" id="range6" value="200" max="500"></div>
    </div>

</div>

<div class="code_view">
&lt;clipPath id="test_clip_dom1"&gt;<br />
  &lt;path<br />
    id="test_clip_path1"<br />
    d = "<span id="code_view1"></span>"<br />
    rx="150"<br />
    ry="100"<br />
    cx="200"<br />
    cy="120"<br />
    stroke="#999999"<br />
    stroke-width="1"<br />
    fill="#cccccc"<br />
  /&gt;<br />
&lt;/clipPath&gt;<br />
</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');
let range5_dom = document.getElementById('range5');
let range6_dom = document.getElementById('range6');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);
range5_dom.addEventListener('input', change_range_slider);
range6_dom.addEventListener('input', change_range_slider);

// スライダーを動かした時の処理
function change_range_slider()
{
    console.log("range1_dom.value -> " + range1_dom.value);
    console.log("range2_dom.value -> " + range2_dom.value);
    console.log("range3_dom.value -> " + range3_dom.value);
    console.log("range4_dom.value -> " + range4_dom.value);
    console.log("range5_dom.value -> " + range5_dom.value);
    console.log("range6_dom.value -> " + range6_dom.value);

    // クリップする側の要素を取得する
    let test_clip_path1 = document.getElementById('test_clip_path1');
    console.log("test_clip_path1 -> " + test_clip_path1);

    let d_value = '';
    
    // DOM要素 「id="test_clip_path1" 」の d のパラメータ
    d_value = 'M' + range1_dom.value + ' ' + range2_dom.value
            + ' L' + range3_dom.value + ' ' + range4_dom.value
            + ' L' + range5_dom.value + ' ' + range6_dom.value
            + ' Z';

    // SVG要素の d の値を設定する
    test_clip_path1.setAttribute('d', d_value);

    // パラメータ値を出力
    let range1_value_dom = document.getElementById('range1_value');
    let range2_value_dom = document.getElementById('range2_value');
    let range3_value_dom = document.getElementById('range3_value');
    let range4_value_dom = document.getElementById('range4_value');
    let range5_value_dom = document.getElementById('range5_value');
    let range6_value_dom = document.getElementById('range6_value');

    range1_value_dom.innerHTML = range1_dom.value;
    range2_value_dom.innerHTML = range2_dom.value;
    range3_value_dom.innerHTML = range3_dom.value;
    range4_value_dom.innerHTML = range4_dom.value;
    range5_value_dom.innerHTML = range5_dom.value;
    range6_value_dom.innerHTML = range6_dom.value;

    // DOM要素 「id="test_clip_path1" 」の d のパラメータを動的に出力する
    let code_view1_dom = document.getElementById('code_view1');
    code_view1_dom.innerHTML = d_value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、

<clipPath id="test_clip_dom1">
    <path
        id="test_clip_path1"
        d='M16 238 L236 246 L242 22 Z'
        rx="150"
        ry="100"
        cx="200"
        cy="120"
        stroke="#999999"
        stroke-width="1"
        fill="#cccccc"
    />
</clipPath>

のクリップ要素の初期値

d='M16 238 L236 246 L242 22 Z'

が有効になり、三角形のパス要素の中に、
元画像の一部分が見えている状態になります。

また、画面内の6つのパラメータは

d='M16 238 L236 246 L242 22 Z'

のパラメータ内部の値を変更するように作用します。

例えば、パラメータの1から6を

M116 103 L303 10 L251 212 Z

になるように変更すると、画面上では以下の表示になります。

サンプルのHTMLで、パラメータを変更してみると、
クリッピングのパスが元画像にどのように影響しているのかが感覚的につかめますので、
試してみることをお勧めいたします。

クリッピング マスキング について – クリッピングパス

Posted コメントするカテゴリー: javascript

クリッピング マスキング について – クリッピングパス

クリッピングとマスキングについて試してみます。
それぞれの意味は、簡単にいうと

・クリッピング
  内側のものは全て見える
  外側のものは覆い隠す

・マスキング
  グラフィックや他のコンテナ要素を含むコンテナ要素
  前景のオブジェクト(グラフィックや要素)を背景に組成するグラフィック

文字だけを読んで理解するのは直感的ではないので、動作するサンプルで把握してみます。

まず、クリッピングについて試してみます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
    padding-top: 10px;
    padding-bottom: 2px;
}
.range {
    width: 400px;
}
</style>

</head>
<body>

<svg width="500" height="400" viewBox="0 0 500 400">

    <defs>
        <clipPath id = "test_clip_dom1">
            <ellipse
                rx="150"
                ry="100"
                cx="200"
                cy="120"
                stroke="#999999"
                stroke-width="1"
                fill="#cccccc"
            />
        </clipPath>
    </defs>
    
    <rect
        id="rect_dom"
        x="10"
        y="10"
        cx="10"
        cy="10"
        width="300"
        height="150"
        fill="#999999"
        clip-path="url(#test_clip_dom1)"
    />
    
</svg>

<div>

    <div class="params_box">
        <span>rect x : </span><span class="params" id="range1_value"></span>
        <div><input type="range" class="range" id="range1" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>rect y : <span class="params" id="range2_value"></span></span>
        <div><input type="range" class="range" id="range2" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>rect cx : <span class="params" id="range3_value"></span></span>
        <div><input type="range" class="range" id="range3" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>rect cy : <span class="params" id="range4_value"></span></span>
        <div><input type="range" class="range" id="range4" value="10" max="500"></div>
    </div>

    <div class="params_box">
        <span>rect width : <span class="params" id="range5_value"></span></span>
        <div><input type="range" class="range" id="range5" value="300" max="500"></div>
    </div>

    <div class="params_box">
        <span>rect height : <span class="params" id="range6_value"></span></span>
        <div><input type="range" class="range" id="range6" value="200" max="500"></div>
    </div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');
let range5_dom = document.getElementById('range5');
let range6_dom = document.getElementById('range6');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);
range5_dom.addEventListener('input', change_range_slider);
range6_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
    console.log("range1_dom.value -> " + range1_dom.value);
    console.log("range2_dom.value -> " + range2_dom.value);
    console.log("range3_dom.value -> " + range3_dom.value);
    console.log("range4_dom.value -> " + range4_dom.value);
    console.log("range5_dom.value -> " + range5_dom.value);
    console.log("range6_dom.value -> " + range6_dom.value);

    // SVG画像のDOMを取得する
    let rect_dom = document.getElementById('rect_dom');
    console.log("rect_dom -> " + rect_dom);

    // SVG要素を変更する
    rect_dom.setAttribute('x'     , range1_dom.value);
    rect_dom.setAttribute('y'     , range2_dom.value);
    rect_dom.setAttribute('cx'    , range3_dom.value);
    rect_dom.setAttribute('cy'    , range4_dom.value);
    rect_dom.setAttribute('width' , range5_dom.value);
    rect_dom.setAttribute('height', range6_dom.value);
    
    // 画面出力
    let range1_value_dom = document.getElementById('range1_value');
    let range2_value_dom = document.getElementById('range2_value');
    let range3_value_dom = document.getElementById('range3_value');
    let range4_value_dom = document.getElementById('range4_value');
    let range5_value_dom = document.getElementById('range5_value');
    let range6_value_dom = document.getElementById('range6_value');

    range1_value_dom.innerHTML = range1_dom.value;
    range2_value_dom.innerHTML = range2_dom.value;
    range3_value_dom.innerHTML = range3_dom.value;
    range4_value_dom.innerHTML = range4_dom.value;
    range5_value_dom.innerHTML = range5_dom.value;
    range6_value_dom.innerHTML = range6_dom.value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、楕円のSVG画像「ellipse」が表示されます。

6つのスライダーは「rect」に対して、パラメータを変更するようになっていて、
スライダーを動かすと楕円がどのようにクリッピングされるかがわかります。

下記のキャプチャはその一例です。

また、クリッピングに使用する「rect」も画面アクセス時には出力されていますが、
「rect」のほうは視覚的に見ることができません。

冒頭でクリッピングの動作について触れましたが、クリッピングは以下の動きをします。

・クリッピング
  内側のものは全て見える
  外側のものは覆い隠す

ここでいう「内側のもの」は「rectで描画されている四角形の内側」という解釈ができます。
また、「外側のものは覆い隠す」については、「rectで描画される四角形の外側」という解釈もできます。

元々の楕円の「ellipse」は常に一定の大きさで描画され、rectでクリッピングされたものが出力されることがわかります。

下記は、スライダー動かし、クリッピングする位置を変更した一例です。

座標変換 transform について – matrix について

Posted コメントするカテゴリー: javascript

座標変換 transform について – matrix について

transform属性の matrix を試してみます。

MDNドキュメントを確認すると、

matrixは、これまでに試してきた「移動」「回転」「縮小」「傾斜」の動作を、2行3列の行列形式で表して定義することができます。

また、2行3列の形ではない変換関数という考え方があり、6つの引数(変換行列)を指定して次のように定義します。

matrix(a, b, c, d, tx, ty)

この変換関数の形で指定した各引数は、以下の3行3列の行列を指定をしたものと同じです。
(上記の説明では2行3列と記載しましたが、変換行列を適用すると3行3列と同様になります)

ここでは、変換関数を使って、SVG画像が画面上でどのように変化するかを把握する、簡単なサンプルを書いて試してみます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
    padding-top: 10px;
    padding-bottom: 2px;
}
.range {
    width: 400px;
}
.code_view {
    padding: 5px;
    width :400px;
    background-color: #000000;
    color: #ffffff;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="100 100 400 400">
    <path
        id           = "test_tran_dom1"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "matrix(1,0, 0,1, 200,200)"
    />
</svg>

<div class="code_view">
    matrix(
        <span id="code_view1"></span>
        <span id="code_view2"></span>
        <span id="code_view3"></span>
        <span id="code_view4"></span>
        <span id="code_view5"></span>
        <span id="code_view6"></span>
    )
</div>

<div>
    <div class="params_box">
        <span>パラメータa : </span><span class="params" id="range1_value"></span>
        <div><input type="range" class="range" id="range1" value="100" max="360"></div>
    </div>

    <div class="params_box">
        <span>パラメータb : <span class="params" id="range2_value"></span></span>
        <div><input type="range" class="range" id="range2" value="0" max="360"></div>
    </div>

    <div class="params_box">
        <span>パラメータc : <span class="params" id="range3_value"></span></span>
        <div><input type="range" class="range" id="range3" value="0" max="360"></div>
    </div>

    <div class="params_box">
        <span>パラメータd : <span class="params" id="range4_value"></span></span>
        <div><input type="range" class="range" id="range4" value="100" max="360"></div>
    </div>

    <div class="params_box">
        <span>パラメータtx : <span class="params" id="range5_value"></span></span>
        <div><input type="range" class="range" id="range5" value="200" max="400"></div>
    </div>

    <div class="params_box">
        <span>パラメータty : <span class="params" id="range6_value"></span></span>
        <div><input type="range" class="range" id="range6" value="200" max="400"></div>
    </div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');
let range5_dom = document.getElementById('range5');
let range6_dom = document.getElementById('range6');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);
range5_dom.addEventListener('input', change_range_slider);
range6_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
    console.log("range1_dom.value -> " + range1_dom.value);
    console.log("range2_dom.value -> " + range2_dom.value);
    console.log("range3_dom.value -> " + range3_dom.value);
    console.log("range4_dom.value -> " + range4_dom.value);
    console.log("range5_dom.value -> " + range5_dom.value);
    console.log("range6_dom.value -> " + range6_dom.value);

    // SVG画像のDOMを取得する
    let test_tran_dom1 = document.getElementById('test_tran_dom1');
    console.log("test_tran_dom1 -> " + test_tran_dom1);

    // パラメータの値をリスト(配列)形式にして値を決定する
    let param1_value = (range1_dom.value / 100);
    let param2_value = (range2_dom.value / 100);
    let param3_value = (range3_dom.value / 100);
    let param4_value = (range4_dom.value / 100);
    let param5_value = range5_dom.value;
    let param6_value = range6_dom.value;

    // 各パラメータを引数の形式にまとめる
    let set_param_value = param1_value + ","
                        + param2_value + ","
                        + param3_value + ","
                        + param4_value + ","
                        + param5_value + ","
                        + param6_value;

    // SVG要素の matrix を変更する
    test_tran_dom1.setAttribute('transform', 'matrix(' + set_param_value + ')');
    
    // 画面出力
    let range1_value_dom = document.getElementById('range1_value');
    let range2_value_dom = document.getElementById('range2_value');
    let range3_value_dom = document.getElementById('range3_value');
    let range4_value_dom = document.getElementById('range4_value');
    let range5_value_dom = document.getElementById('range5_value');
    let range6_value_dom = document.getElementById('range6_value');
    range1_value_dom.innerHTML = param1_value;
    range2_value_dom.innerHTML = param2_value;
    range3_value_dom.innerHTML = param3_value;
    range4_value_dom.innerHTML = param4_value;
    range5_value_dom.innerHTML = param5_value;
    range6_value_dom.innerHTML = param6_value;

    let code_view1_dom = document.getElementById('code_view1');
    let code_view2_dom = document.getElementById('code_view2');
    let code_view3_dom = document.getElementById('code_view3');
    let code_view4_dom = document.getElementById('code_view4');
    let code_view5_dom = document.getElementById('code_view5');
    let code_view6_dom = document.getElementById('code_view6');
    code_view1_dom.innerHTML = param1_value + ',';
    code_view2_dom.innerHTML = param2_value + ',';
    code_view3_dom.innerHTML = param3_value + ',';
    code_view4_dom.innerHTML = param4_value + ',';
    code_view5_dom.innerHTML = param5_value + ',';
    code_view6_dom.innerHTML = param6_value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、これまでと同様のサンプルSVG画像が表示されます。

パラメータは a b c d tx ty の6つですが、各値は同じように処理している訳ではなく、

パラメータ 「 a b c d 」 は 100で割って、100分率の値を使用しています。
また、「 tx ty 」 については、座標(SVG画像の位置を決める)を扱うので、スライダーの値をそのまま使用しています。

各パラメータを一つづつ動かしてみると、
a と c は水平方向(x軸方向)に作用し、 b と d は垂直方向(y軸方向)に作用することがわかります。
また、 tx と ty については、SVG画像全体の位置情報(座標)に作業していることがわかります。

座標変換 transform について – skewX skewY について

Posted コメントするカテゴリー: javascript

座標変換 transform について – skewX skewY について

transform属性の skewX を試してみます。
以下のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-bottom: 20px;
}
.range {
	width: 400px;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="0 0 400 400">
    <path
        id           = "test_tran_dom1"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "translate(150, 150)"
    />
</svg>

<div>
	<div class="params_box">
		<span>パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="360"></div>
		<span>skewX : </span>
		<span class="params" id="range1_value"></span>
	</div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);

	// DOMを取得する
	let test_tran_dom1 = document.getElementById('test_tran_dom1');
	console.log("test_tran_dom1 -> " + test_tran_dom1);

	// パラメータの値をリスト(配列)形式にして値を決定する
	let param1_value = range1_dom.value;

	let set_param_value = param1_value;
	console.log("set_param_value -> " + set_param_value);

	// SVG要素の skewX を変更する
	test_tran_dom1.setAttribute('transform', 'translate(150, 150), skewX(' + set_param_value + ')');
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	range1_value_dom.innerHTML = set_param_value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、これまでと同様のサンプルSVG画像が表示されます。

スライダーを操作すると、x軸方向に skewX の値が変化し、画像が動的に変わり、画像に対しての効果がわかります。

ちなみに skewX の値を指定している箇所で、下記のように

	// SVG要素の skewX を変更する
	test_tran_dom1.setAttribute('transform', 'translate(150, 150), skewX(' + set_param_value + ')');

同時に「translate(150, 150)」も設定していますが、これはスライダー変更時にSVG画像位置を固定して変化がわかりやすくする為に書いています。
実際の使用シーンでは、座標指定は画面の表示箇所の都合に合わせて指定するとよいと思います。

skewY について

さきほどのサンプルをもとに、transform属性の skewY を試してみます。
以下のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-bottom: 20px;
}
.range {
	width: 400px;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="0 0 400 400">
    <path
        id           = "test_tran_dom1"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "translate(150, 150)"
    />
</svg>

<div>
	<div class="params_box">
		<span>パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="360"></div>
		<span>skewY : </span>
		<span class="params" id="range1_value"></span>
	</div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);

	// DOMを取得する
	let test_tran_dom1 = document.getElementById('test_tran_dom1');
	console.log("test_tran_dom1 -> " + test_tran_dom1);

	// パラメータの値をリスト(配列)形式にして値を決定する
	let param1_value = range1_dom.value;

	let set_param_value = param1_value;
	console.log("set_param_value -> " + set_param_value);

	// SVG要素の skewY を変更する
	test_tran_dom1.setAttribute('transform', 'translate(150, 150), skewY(' + set_param_value + ')');
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	range1_value_dom.innerHTML = set_param_value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、これまでと同様のサンプルSVG画像が表示されます。

スライダーを操作すると、y軸方向に skewY の値が変化し、画像への効果がわかります。

skewX skewY について

さらに、さきほどのサンプルをもとに、transform属性の skewX skewY の併用を試してみます。
以下のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-bottom: 20px;
}
.range {
	width: 400px;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="0 0 400 400">
    <path
        id           = "test_tran_dom1"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "translate(150, 150)"
    />
</svg>

<div>
	<div class="params_box">
		<span>パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="360"></div>
		<span>skewX : </span>
		<span class="params" id="range1_value"></span>
	</div>
	<div class="params_box">
		<span>パラメータ2</span>
		<div><input type="range" class="range" id="range2" value="20" max="360"></div>
		<span>skewY : </span>
		<span class="params" id="range2_value"></span>
	</div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);
	console.log("range2_dom.value -> " + range2_dom.value);

	// DOMを取得する
	let test_tran_dom1 = document.getElementById('test_tran_dom1');
	console.log("test_tran_dom1 -> " + test_tran_dom1);

	// SVG要素の skewX skewY を変更する
	test_tran_dom1.setAttribute('transform', 'translate(150, 150), skewX(' + range1_dom.value + '), skewY(' + range2_dom.value + ')');
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	let range2_value_dom = document.getElementById('range2_value');
	range1_value_dom.innerHTML = range1_dom.value;
	range2_value_dom.innerHTML = range2_dom.value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test3.html)

画面にアクセスすると、これまでと同様のサンプルSVG画像が表示されます。

スライダーは2つあり、x方向とy方向の値を変更することができます。
それぞれのスライダーを操作すると、x軸方向に skewX、y軸方向に skewY、の値がそれぞれ変化し、画像への効果がわかります。

skewXを任意の値で変化させた後、skewYを任意の値で変化した場合、両方の効果がSVG画像に適用されることがわかります。

座標変換 transform について – scale について

Posted コメントするカテゴリー: javascript

座標変換 transform について – scale について

transform属性の scale を試してみます。
以下のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-bottom: 20px;
}
.range {
	width: 400px;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="0 0 400 400">
    <path
        id           = "test_tran_dom1"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "translate(10, 10)"
    />
</svg>

<div>
	<div class="params_box">
		<span>パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="300"></div>
		<span>scale(x方向) :</span>
		<span class="params" id="range1_value"></span>
	</div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);

	// DOMを取得する
	let test_tran_dom1 = document.getElementById('test_tran_dom1');

	console.log("test_tran_dom1 -> " + test_tran_dom1);

	// パラメータの値をリスト(配列)形式にして値を決定する
	let param1_value = range1_dom.value;

	let set_param_value = (param1_value / 10);

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x方向 を変更する
	test_tran_dom1.setAttribute('transform', 'scale(' + set_param_value + ')');
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');

	range1_value_dom.innerHTML = set_param_value + '倍';

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、1つのDOMが出力されます。

パラメータを操作することで、svg画像に指定した x方向の拡大率 の値が変化します。

また、この例では拡大率の変化が把握しやすいように、スライダーの値を10分の1にして適用させています。

座標変換 transform について – scale x方向 y方向 について

先程のサンプルを変更して、y方向にもパラメータを追加してみます。

x方向 y方向 それぞれに scale を適用する場合は、下記の書き方になります。

scale(x, y)

簡単サンプルを書きました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-bottom: 20px;
}
.range {
	width: 400px;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="0 0 400 400">
    <path
        id           = "test_tran_dom1"
        x            = "20"
        y            = "20"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "translate(10, 10)"
    />
</svg>

<div>

	<div class="params_box">
		<span>パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="300"></div>
		<span>scale (x軸方向) :</span>
		<span class="params" id="range1_value"></span>
	</div>

	<div class="params_box">
		<span>パラメータ2</span>
		<div><input type="range" class="range" id="range2" value="20" max="300"></div>
		<span>scale (y軸方向) :</span>
		<span class="params" id="range2_value"></span>
	</div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);
	console.log("range2_dom.value -> " + range2_dom.value);

	// DOMを取得する
	let test_tran_dom1 = document.getElementById('test_tran_dom1');

	console.log("test_tran_dom1 -> " + test_tran_dom1);

	// パラメータの値をリスト(配列)形式にして値を決定する
	let param1_value = (range1_dom.value / 10);
	let param2_value = (range2_dom.value / 10);

	let set_param_value = param1_value + ","
	                    + param2_value;

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x方向 y方向 を変更する
	test_tran_dom1.setAttribute('transform', 'scale(' + set_param_value + ')');
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	let range2_value_dom = document.getElementById('range2_value');

	range1_value_dom.innerHTML = param1_value + '倍';
	range2_value_dom.innerHTML = param2_value + '倍';

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、一つのSVG画像と、パラメータが2つ表示されます。

x方向のパラメータと、y方向のパラメータを動かすと、それぞれの軸方向に対して、SVG画像が伸縮します。

パラメータが独立しているので、縦横比はバラバラな値が適用されます。
縦横比を維持した形で伸縮する場合は、ロジックを書かなくても y 方向のパラメータを省略するだけで実現可能です。

また、このサンプルも前回同様にスライダーの値を10分の1しています。

座標変換 transform について – rotate について

Posted コメントするカテゴリー: javascript

座標変換 transform について – rotate について

transform属性の rotate を試してみます。
以下のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-bottom: 20px;
}
.range {
	width: 400px;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="0 0 400 400">
    <path
        id           = "test_tran_dom1"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "translate(10, 10)"
    />
</svg>

<div>
	<div class="params_box">
		<span>パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="300"></div>
		<span>rotate :</span>
		<span class="params" id="range1_value"></span>
	</div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);

	// DOMを取得する
	let test_tran_dom1 = document.getElementById('test_tran_dom1');

	console.log("test_tran_dom1 -> " + test_tran_dom1);

	// パラメータの値をリスト(配列)形式にして値を決定する
	let param1_value = range1_dom.value;

	let set_param_value = param1_value;

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x属性 を変更する
	test_tran_dom1.setAttribute('transform', 'rotate(' + set_param_value + ')');
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');

	range1_value_dom.innerHTML = range1_dom.value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、1つのDOMが出力されます。
パラメータを操作することで、svg画像に指定した rotate の値の変化を見ることができます。

また、このサンプルのrotateは引数が1つだけです。
rotateの引数が1つだけの場合は、SVG画像を描画している要素の「x軸:0 y軸:0」を起点として画像を回転します。

rotate の引数について

rotateの引数を調整することで、回転する起点を変えることができます。

具体的には

rotate(角度, [x方向の起点, y方向の起点])

という形で、引数を割り当てることができます。

例えば

rotate(45, 50, 100)

と指定した場合は、SVG画像を45度回転し、そのSVG画像をx:50、y:100の座標を軸に回転します。

以下、簡単なサンプルを書きました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-bottom: 20px;
}
.range {
	width: 400px;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="0 0 400 400">
    <path
        id           = "test_tran_dom1"
        x            = "20"
        y            = "20"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "translate(10, 10)"
    />
</svg>

<div>

	<div class="params_box">
		<span>パラメータ0</span>
		<div><input type="range" class="range" id="range0" value="20" max="360"></div>
		<span>回転方向 :</span>
		<span class="params" id="range0_value"></span>
	</div>

	<div class="params_box">
		<span>パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="300"></div>
		<span>x軸方向 :</span>
		<span class="params" id="range1_value"></span>
	</div>

	<div class="params_box">
		<span>パラメータ2</span>
		<div><input type="range" class="range" id="range2" value="20" max="300"></div>
		<span>y軸方向 :</span>
		<span class="params" id="range2_value"></span>
	</div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range0_dom = document.getElementById('range0');
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range0_dom.addEventListener('input', change_range_slider);
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range0_dom.value -> " + range0_dom.value);
	console.log("range1_dom.value -> " + range1_dom.value);
	console.log("range2_dom.value -> " + range2_dom.value);

	// DOMを取得する
	let test_tran_dom1 = document.getElementById('test_tran_dom1');

	console.log("test_tran_dom1 -> " + test_tran_dom1);

	// パラメータの値をリスト(配列)形式にして値を決定する
	let param0_value = range0_dom.value;
	let param1_value = range1_dom.value;
	let param2_value = range2_dom.value;

	let set_param_value = param0_value + ","
	                    + param1_value + ","
	                    + param2_value;

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x属性 を変更する
	test_tran_dom1.setAttribute('transform', 'rotate(' + set_param_value + ')');
	
	// 画面出力
	let range0_value_dom = document.getElementById('range0_value');
	let range1_value_dom = document.getElementById('range1_value');
	let range2_value_dom = document.getElementById('range2_value');

	range0_value_dom.innerHTML = range0_dom.value;
	range1_value_dom.innerHTML = range1_dom.value;
	range2_value_dom.innerHTML = range2_dom.value;

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、SVG画像と、パラメータが3つ表示されます。

パラメータ0は回転角度、パラメータ1はx座標、パラメータ2はy座標、をそれぞれ変更できます。

例えば、パラメータ1を40、パラメータ2を60にして、パラメータ0の回転角度を変更すると、
rotateは下記のようにセットされ、SVG画像は、x:40 y:60の座標を起点として回転するようになります。

rotate(任意の角度, 40, 60)

パラメータ0~2 をそれぞれ変更すると、引数がどのように影響するか把握しやすくなります。

座標変換 transform について – translate について

Posted コメントするカテゴリー: javascript

座標変換 transform について – translate について

transform属性の translate を試してみます。
以下のサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-bottom: 20px;
}
.range {
	width: 400px;
}
</style>

</head>
<body>

<svg width="400" height="400" viewBox="0 0 400 400">
    <path
        id           = "test_tran_dom1"
        d            = "M 20 20 A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
        transform    = "translate(10, 10)"
    />
</svg>

<div>
	<div class="params_box">
		<span>パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="300"></div>
		<span>x軸方向 :</span>
		<span class="params" id="range1_value"></span>
	</div>

	<div class="params_box">
		<span>パラメータ2</span>
		<div><input type="range" class="range" id="range2" value="20" max="300"></div>
		<span>y軸方向 :</span>
		<span class="params" id="range2_value"></span>
	</div>

</div>

<script>
// スライダの要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);
	console.log("range2_dom.value -> " + range2_dom.value);

	// DOMを取得する
	let test_tran_dom1 = document.getElementById('test_tran_dom1');

	console.log("test_tran_dom1 -> " + test_tran_dom1);

	// パラメータの値をリスト(配列)形式にして値を決定する
	let param1_value = range1_dom.value;
	let param2_value = range2_dom.value;

	let set_param_value = param1_value + ","
	                    + param2_value + " ";

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x属性 を変更する
	test_tran_dom1.setAttribute('transform', 'translate(' + set_param_value + ')');
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	let range2_value_dom = document.getElementById('range2_value');

	range1_value_dom.innerHTML = range1_dom.value + '<br />';
	range2_value_dom.innerHTML = range2_dom.value + '<br />';

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、1つのDOMが出力されます。

また、パラメータが2つあり、それぞれを操作することで、svg画像に指定した translate の値の変化を見ることができます。

座標変換 transform について

Posted コメントするカテゴリー: javascript

座標変換 transform について

transformについて調べてみます。

transformは属性です。
要素を移動、回転、伸縮、傾斜、といった指定で変形します。

属性に対しての指定方法は下記になります。

translate
x方向、y方向に要素を移動する

rotate
指定角度の回転をする

scale
要素を拡大、縮小する

skewX skewY
x方向、y方向に指定した角度分を傾斜する

matrix
2行3列の行列を、変換する関数です。
6個の値を変換行列の形式で変形します。

一つ一つサンプルを書いて確認していきます。

SVGについて – テキストについて(9)

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて(9)

textPath要素について調べてみます。
textPath要素は、textタグのxlink:href属性で、パス情報の定義とidを指定して結び付けます。

以下、サンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-top: 10px;
}

.range {
	width: 300px;
}
</style>

</head>
<body>

<svg width="500" height="250" viewBox="0 0 500 250">

	<path id="test_text1" d="M 20,20 C 40,40 80,40 100,20" stroke="#999999"  fill="transparent"/>
	<text>
		<textPath xlink:href="#test_text1">
			テキストのテストです1
			テキストのテストです2
			テキストのテストです3
			テキストのテストです4
		</textPath>
	</text>

</svg>

<div>
	<div class="params_box">
		<span class="param_title">パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range1_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ2</span>
		<div><input type="range" class="range" id="range2" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range2_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ3</span>
		<div><input type="range" class="range" id="range3" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range3_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ4</span>
		<div><input type="range" class="range" id="range4" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range4_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ5</span>
		<div><input type="range" class="range" id="range5" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range5_value"></span>
	<div>

	<div class="params_box">
		<span class="param_title">パラメータ6</span>
		<div><input type="range" class="range" id="range6" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range6_value"></span>
	<div>

</div>

<script>
// スライダ range1~6 の要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');
let range5_dom = document.getElementById('range5');
let range6_dom = document.getElementById('range6');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);
range5_dom.addEventListener('input', change_range_slider);
range6_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);
	console.log("range2_dom.value -> " + range2_dom.value);
	console.log("range3_dom.value -> " + range3_dom.value);
	console.log("range4_dom.value -> " + range4_dom.value);
	console.log("range5_dom.value -> " + range5_dom.value);
	console.log("range6_dom.value -> " + range6_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');

	console.log("test_text1_dom -> " + test_text1_dom);

	// パラメータ1~6まで値をリスト(配列)形式にして値を決定する
	// ただし、値は a,a' b,b' c,c' のようにカンマ区切りで2つセットで決定する
	let param1_value = range1_dom.value;
	let param2_value = range2_dom.value;
	let param3_value = range3_dom.value;
	let param4_value = range4_dom.value;
	let param5_value = range5_dom.value;
	let param6_value = range6_dom.value;

	let set_param_value = param1_value + ","
	                    + param2_value + " "
	                    + param3_value + ","
	                    + param4_value + " "
	                    + param5_value + ","
	                    + param6_value;

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x属性 を変更する
	test_text1_dom.setAttribute('d', 'M 20,20 C ' + set_param_value);
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	let range2_value_dom = document.getElementById('range2_value');
	let range3_value_dom = document.getElementById('range3_value');
	let range4_value_dom = document.getElementById('range4_value');
	let range5_value_dom = document.getElementById('range5_value');
	let range6_value_dom = document.getElementById('range6_value');

	range1_value_dom.innerHTML = range1_dom.value + '<br />';
	range2_value_dom.innerHTML = range2_dom.value + '<br />';
	range3_value_dom.innerHTML = range3_dom.value + '<br />';
	range4_value_dom.innerHTML = range4_dom.value + '<br />';
	range5_value_dom.innerHTML = range5_dom.value + '<br />';
	range6_value_dom.innerHTML = range6_dom.value + '<br />';

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト1テキストのテスト2テキストのテスト3テキストのテスト4」という文字列が出力されますが、パスの定義である

<path id="test_text1" d="M 20,20 C 40,40 80,40 100,20" stroke="#999999"  fill="transparent"/>

に沿った形でテキスト出力されています。

初期値では文字列が「テキストの」までで途切れていますが、画面下のパラメータ1~6を調整することで、
パスの「C」の値を3箇所、動的に変更できます。

パラメータ1から6を変更することで、パスの座標が変化し、パス情報に沿って文字列が出力されることがわかります。

以下、パラメータの設定の一例をキャプチャしたものです。

SVGについて – テキストについて(8)

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて(8)

tspan要素について調べてみます。

tspan要素は、長い文字列の中の一部分の文字列に対してマークアップするシーンで使用します。

text要素の子要素として定義します。
また、tspan要素の中にtspan要素を書いてネストにすることもできます。

以下、サンプルを用意しました。

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

<svg width="500" height="200" viewBox="0 0 500 200">

	<text
		x="20"
		y="20"
		dx="0"
		dy="0"
	>
		テキストの
		<tspan x="30" y="80" dx="0" dy="10" fill="#00afff">
			テ
			<tspan dx="5" dy="15" rotate="15" fill="#ff0000">
				ス
			</tspan>
			<tspan dx="25" dy="30" rotate="30">
				ト
			</tspan>
		</tspan>
	</text>

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト」という文字列が「テキストの」までは通常の横書きで出力され、
その後の「テ」「ス」「ト」にはtspanで定義したdx dy rotate fillがそれぞれ個別に影響して出力されていることがわかります。

また、ネストされている要素で、後半の「テスト」全体をfill要素で色の指定をしているので、
親要素の定義が子要素の定義に引き継がれて「テスト」全体が青色に着色されることがわかります。

ただし、2文字目の「ス」は個別にfill要素が定義されているので、その文字だけは赤色になります。
3文字目の「ト」については、親要素のfill属性を引き継いで青色で出力されています。

SVGについて – テキストについて(7)

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて(7)

前々回の x属性の変更のサンプルに対して、writing-mode属性をつけてみます。

writing-mode属性は文字列の出力方向を決定します。

writing-mode="lr"
左から右に出力する(通常の出力と同じ)

writing-mode="rl"
右から左に出力する(通常の出力とは逆になる)

writing-mode="tb"
上から下に出力する(縦書きになる)

具体的なサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-top: 30px;
}

.range {
	width: 300px;
}
</style>


</head>
<body>

<svg width="500" height="200" viewBox="0 0 500 200">

	<text
		id="test_text1"
		x="20"
		y="20"
		dx="0"
		dy="0"
		transform="rotate(0, 20,40)"
		writing-mode="tb"
	>
	テキストのテスト
	</text>

</svg>


<div>
	<div class="params_box">
		<span class="param_title">パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range1_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ2</span>
		<div><input type="range" class="range" id="range2" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range2_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ3</span>
		<div><input type="range" class="range" id="range3" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range3_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ4</span>
		<div><input type="range" class="range" id="range4" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range4_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ5</span>
		<div><input type="range" class="range" id="range5" value="20" max="400"></div>
		<span>x :</span>
		<span class="params" id="range5_value"></span>
	<div>

</div>


<script>

// スライダ range1 の要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');
let range5_dom = document.getElementById('range5');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);
range5_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);
	console.log("range2_dom.value -> " + range2_dom.value);
	console.log("range3_dom.value -> " + range3_dom.value);
	console.log("range4_dom.value -> " + range4_dom.value);
	console.log("range5_dom.value -> " + range5_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	let test_text2_dom = document.getElementById('test_text2');
	let test_text3_dom = document.getElementById('test_text3');
	let test_text4_dom = document.getElementById('test_text4');
	let test_text5_dom = document.getElementById('test_text5');

	console.log("test_text1_dom -> " + test_text1_dom);
	console.log("test_text2_dom -> " + test_text2_dom);
	console.log("test_text3_dom -> " + test_text3_dom);
	console.log("test_text4_dom -> " + test_text4_dom);
	console.log("test_text5_dom -> " + test_text5_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let param1_value = range1_dom.value;
	let param2_value = range2_dom.value;
	let param3_value = range3_dom.value;
	let param4_value = range4_dom.value;
	let param5_value = range5_dom.value;

	let set_param_value = param1_value + " "
	                    + param2_value + " "
	                    + param3_value + " "
	                    + param4_value + " "
	                    + param5_value;

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x属性 を変更する
	test_text1_dom.setAttribute('x', set_param_value);
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	let range2_value_dom = document.getElementById('range2_value');
	let range3_value_dom = document.getElementById('range3_value');
	let range4_value_dom = document.getElementById('range4_value');
	let range5_value_dom = document.getElementById('range5_value');

	range1_value_dom.innerHTML = range1_dom.value + '<br />';
	range2_value_dom.innerHTML = range2_dom.value + '<br />';
	range3_value_dom.innerHTML = range3_dom.value + '<br />';
	range4_value_dom.innerHTML = range4_dom.value + '<br />';
	range5_value_dom.innerHTML = range5_dom.value + '<br />';

}

</script>


</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト」という文字列が縦書きで表示されます。

また、画面下部のパラメータ1~5は、前々回のサンプルのまま設置しています。

縦書きの属性にしても、x方向の各文字の移動はそのまま処理できることがわかります。

SVGについて – テキストについて(6)

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて(6)

テキストの y属性 について試してみます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-top: 30px;
}

.range {
	width: 300px;
}
</style>


</head>
<body>

<svg width="500" height="200" viewBox="0 0 500 200">

	<text
		id="test_text1"
		x="50"
		y="20"
		dx="0"
		dy="0"
		transform="rotate(0, 20,40)"
	>
	テキストのテスト
	</text>

</svg>


<div>
	<div class="params_box">
		<span class="param_title">パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="20" max="400"></div>
		<span>y :</span>
		<span class="params" id="range1_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ2</span>
		<div><input type="range" class="range" id="range2" value="20" max="400"></div>
		<span>y :</span>
		<span class="params" id="range2_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ3</span>
		<div><input type="range" class="range" id="range3" value="20" max="400"></div>
		<span>y :</span>
		<span class="params" id="range3_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ4</span>
		<div><input type="range" class="range" id="range4" value="20" max="400"></div>
		<span>y :</span>
		<span class="params" id="range4_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ5</span>
		<div><input type="range" class="range" id="range5" value="20" max="400"></div>
		<span>y :</span>
		<span class="params" id="range5_value"></span>
	<div>

</div>


<script>

// スライダ range1 の要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');
let range5_dom = document.getElementById('range5');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);
range5_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);
	console.log("range2_dom.value -> " + range2_dom.value);
	console.log("range3_dom.value -> " + range3_dom.value);
	console.log("range4_dom.value -> " + range4_dom.value);
	console.log("range5_dom.value -> " + range5_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	let test_text2_dom = document.getElementById('test_text2');
	let test_text3_dom = document.getElementById('test_text3');
	let test_text4_dom = document.getElementById('test_text4');
	let test_text5_dom = document.getElementById('test_text5');

	console.log("test_text1_dom -> " + test_text1_dom);
	console.log("test_text2_dom -> " + test_text2_dom);
	console.log("test_text3_dom -> " + test_text3_dom);
	console.log("test_text4_dom -> " + test_text4_dom);
	console.log("test_text5_dom -> " + test_text5_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let param1_value = range1_dom.value;
	let param2_value = range2_dom.value;
	let param3_value = range3_dom.value;
	let param4_value = range4_dom.value;
	let param5_value = range5_dom.value;

	let set_param_value = param1_value + " "
	                    + param2_value + " "
	                    + param3_value + " "
	                    + param4_value + " "
	                    + param5_value;

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x属性 を変更する
	test_text1_dom.setAttribute('y', set_param_value);
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	let range2_value_dom = document.getElementById('range2_value');
	let range3_value_dom = document.getElementById('range3_value');
	let range4_value_dom = document.getElementById('range4_value');
	let range5_value_dom = document.getElementById('range5_value');

	range1_value_dom.innerHTML = range1_dom.value + '<br />';
	range2_value_dom.innerHTML = range2_dom.value + '<br />';
	range3_value_dom.innerHTML = range3_dom.value + '<br />';
	range4_value_dom.innerHTML = range4_dom.value + '<br />';
	range5_value_dom.innerHTML = range5_dom.value + '<br />';

}

</script>


</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト」という文字列が表示されます。

前回は、x方向の文字列位置を変更するサンプルでしたが、今回は、y方向に文字列の位置が変化します。

x方向のサンプルと同様に、5つ目のスライダは残り全ての文字列の y座標の位置が変化します。

SVGについて – テキストについて(5)

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて(5)

テキストのx属性 について試してみます。

前回のサンプルをもとに、x 属性の値を可変するサンプルを書きました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-top: 30px;
}

.range {
	width: 300px;
}
</style>


</head>
<body>

<svg width="500" height="200" viewBox="0 0 500 200">

	<text
		id="test_text1"
		x="50"
		y="50"
		dx="0"
		dy="0"
		transform="rotate(0, 20,40)"
	>
	テキストのテスト
	</text>

</svg>


<div>
	<div class="params_box">
		<span class="param_title">パラメータ1</span>
		<div><input type="range" class="range" id="range1" value="0" max="400"></div>
		<span>x :</span>
		<span class="params" id="range1_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ2</span>
		<div><input type="range" class="range" id="range2" value="0" max="400"></div>
		<span>x :</span>
		<span class="params" id="range2_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ3</span>
		<div><input type="range" class="range" id="range3" value="0" max="400"></div>
		<span>x :</span>
		<span class="params" id="range3_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ4</span>
		<div><input type="range" class="range" id="range4" value="0" max="400"></div>
		<span>x :</span>
		<span class="params" id="range4_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ5</span>
		<div><input type="range" class="range" id="range5" value="0" max="400"></div>
		<span>x :</span>
		<span class="params" id="range5_value"></span>
	<div>

</div>


<script>

// スライダ range1 の要素を取得し、イベントを付与する
let range1_dom = document.getElementById('range1');
let range2_dom = document.getElementById('range2');
let range3_dom = document.getElementById('range3');
let range4_dom = document.getElementById('range4');
let range5_dom = document.getElementById('range5');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
range1_dom.addEventListener('input', change_range_slider);
range2_dom.addEventListener('input', change_range_slider);
range3_dom.addEventListener('input', change_range_slider);
range4_dom.addEventListener('input', change_range_slider);
range5_dom.addEventListener('input', change_range_slider);

// スライダーを動かし時の処理
function change_range_slider()
{
	console.log("range1_dom.value -> " + range1_dom.value);
	console.log("range2_dom.value -> " + range2_dom.value);
	console.log("range3_dom.value -> " + range3_dom.value);
	console.log("range4_dom.value -> " + range4_dom.value);
	console.log("range5_dom.value -> " + range5_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	let test_text2_dom = document.getElementById('test_text2');
	let test_text3_dom = document.getElementById('test_text3');
	let test_text4_dom = document.getElementById('test_text4');
	let test_text5_dom = document.getElementById('test_text5');

	console.log("test_text1_dom -> " + test_text1_dom);
	console.log("test_text2_dom -> " + test_text2_dom);
	console.log("test_text3_dom -> " + test_text3_dom);
	console.log("test_text4_dom -> " + test_text4_dom);
	console.log("test_text5_dom -> " + test_text5_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let param1_value = range1_dom.value;
	let param2_value = range2_dom.value;
	let param3_value = range3_dom.value;
	let param4_value = range4_dom.value;
	let param5_value = range5_dom.value;

	let set_param_value = param1_value + " "
	                    + param2_value + " "
	                    + param3_value + " "
	                    + param4_value + " "
	                    + param5_value;

	console.log("set_param_value -> " + set_param_value);

	// SVG要素の x属性 を変更する
	test_text1_dom.setAttribute('x', set_param_value);
	
	// 画面出力
	let range1_value_dom = document.getElementById('range1_value');
	let range2_value_dom = document.getElementById('range2_value');
	let range3_value_dom = document.getElementById('range3_value');
	let range4_value_dom = document.getElementById('range4_value');
	let range5_value_dom = document.getElementById('range5_value');

	range1_value_dom.innerHTML = range1_dom.value + '<br />';
	range2_value_dom.innerHTML = range2_dom.value + '<br />';
	range3_value_dom.innerHTML = range3_dom.value + '<br />';
	range4_value_dom.innerHTML = range4_dom.value + '<br />';
	range5_value_dom.innerHTML = range5_dom.value + '<br />';

}

</script>


</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト」という文字列が表示されます。

スライダは全部で5つあり、それぞれのスライダを動かすと、文字列の1~4までは、
スライダの1から4までの値で、x軸の位置が変化し、5つ目のスライダは残り全ての文字列を1つの要素して
x軸方向に位置が変化します。

ここで注意が必要なことは

	test_text1_dom.setAttribute('x', set_param_value);

の箇所で、set_param_value の値をセットしていますが、
この変数の値は、空白で区切られたリスト形式の値をセットしています。

セットする項目は「x」で、1つの項目ですが、セットする値は、単一でも複数(リスト)の値でも動作します。

SVGについて – テキストについて(4)

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて(4)

テキストのtextLength属性 について試してみます。

前回のサンプルをもとに、textLength 属性の値を可変するサンプルを書きました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-top: 30px;
}

.transform {
	width: 400px;
}
</style>


</head>
<body>
<svg width="500" height="200" viewBox="0 0 500 200">

	<text
		id="test_text1"
		x="50"
		y="50"
		dx="0"
		dy="0"
		transform="rotate(0, 20,40)"
	>
	テキストのテスト
	</text>

</svg>


<div>
	<div class="params_box">
		<span class="param_title">パラメータ1</span>
		<div><input type="range" class="transform" id="transform1" value="0" max="400"></div>
		<span>textLength :</span>
		<span class="params" id="transform1_value"></span>
	</div>

</div>


<script>

// スライダtransform1の要素を取得し、イベントを付与する
let transform1_dom = document.getElementById('transform1');
transform1_dom.addEventListener('input', function(e) {

	console.log("transform1_dom.value -> " + transform1_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	console.log("test_text1_dom -> " + test_text1_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let rotate_value = transform1_dom.value;

	// SVG要素のtextLength属性を変更する
	test_text1_dom.setAttribute('textLength', rotate_value);
	
	// 画面出力
	let transform1_value_dom = document.getElementById('transform1_value');
	transform1_value_dom.innerHTML = transform1_dom.value + '<br />';

});

</script>


</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト」という文字列が表示されます。

また、スライダを動かすと、0~400までの範囲で値が可変し、textLength属性の値を
動的に変更しています。

スライダを動かすとわかりますが、値が増えるほど、テキストの文字間隔が広がり、
値が減ると、文字間隔が狭くなることがわかります。

SVGについて – テキストについて(3)

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて(3)

テキストのtransform属性のrotateについて

前回のサンプルの rotate の値は、単一の値を指定して、各文字列の角度を指定しました。

今回は、指定する角度を配列形式のリストで指定してみます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
.params_box {
	padding-top: 30px;
}

#transform {
	width: 200px;
}
</style>


</head>
<body>
<svg width="200" height="200" viewBox="0 0 200 200">

	<text
		id="test_text1"
		x="50"
		y="50"
		dx="0"
		dy="0"
		transform="rotate(0, 20,40)"
	>
	テキストのテスト
	</text>

</svg>


<div>
	<div class="params_box">
		<span class="param_title">パラメータ1</span>
		<div><input type="range" id="transform1" value="0" max="360"></div>
		<span>transform (rotate) :</span>
		<span class="params" id="transform1_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ2</span>
		<div><input type="range" id="transform2" value="0" max="360"></div>
		<span>transform (rotate) :</span>
		<span class="params" id="transform2_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ3</span>
		<div><input type="range" id="transform3" value="0" max="360"></div>
		<span>transform (rotate) :</span>
		<span class="params" id="transform3_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ4</span>
		<div><input type="range" id="transform4" value="0" max="360"></div>
		<span>transform (rotate) :</span>
		<span class="params" id="transform4_value"></span>
	</div>

	<div class="params_box">
		<span class="param_title">パラメータ5</span>
		<div><input type="range" id="transform5" value="0" max="360"></div>
		<span>transform (rotate) :</span>
		<span class="params" id="transform5_value"></span>
	</div>

</div>


<script>

// スライダtransform1の要素を取得し、イベントを付与する
let transform1_dom = document.getElementById('transform1');
transform1_dom.addEventListener('input', function(e) {

	console.log("transform1_dom.value -> " + transform1_dom.value);
	console.log("transform2_dom.value -> " + transform2_dom.value);
	console.log("transform3_dom.value -> " + transform3_dom.value);
	console.log("transform4_dom.value -> " + transform4_dom.value);
	console.log("transform5_dom.value -> " + transform5_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	console.log("test_text1_dom -> " + test_text1_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let rotate_value = transform1_dom.value
	                 + ',' + transform2_dom.value
	                 + ',' + transform3_dom.value
	                 + ',' + transform4_dom.value
	                 + ',' + transform5_dom.value;

	// SVG要素のtransform1属性を変更する
	test_text1_dom.setAttribute('rotate', rotate_value);
	
	// 画面出力
	let transform1_value_dom = document.getElementById('transform1_value');
	transform1_value_dom.innerHTML = transform1_dom.value + '<br />';

});

// スライダtransform2の要素を取得し、イベントを付与する
let transform2_dom = document.getElementById('transform2');
transform2_dom.addEventListener('input', function(e) {

	console.log("transform1_dom.value -> " + transform1_dom.value);
	console.log("transform2_dom.value -> " + transform2_dom.value);
	console.log("transform3_dom.value -> " + transform3_dom.value);
	console.log("transform4_dom.value -> " + transform4_dom.value);
	console.log("transform5_dom.value -> " + transform5_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	console.log("test_text1_dom -> " + test_text1_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let rotate_value = transform1_dom.value
	                 + ',' + transform2_dom.value
	                 + ',' + transform3_dom.value
	                 + ',' + transform4_dom.value
	                 + ',' + transform5_dom.value;

	// SVG要素のtransform2属性を変更する
	test_text1_dom.setAttribute('rotate', rotate_value);
	
	// 画面出力
	let transform2_value_dom = document.getElementById('transform2_value');
	transform2_value_dom.innerHTML = transform2_dom.value + '<br />';

});

// スライダtransform3の要素を取得し、イベントを付与する
let transform3_dom = document.getElementById('transform3');
transform3_dom.addEventListener('input', function(e) {

	console.log("transform1_dom.value -> " + transform1_dom.value);
	console.log("transform2_dom.value -> " + transform2_dom.value);
	console.log("transform3_dom.value -> " + transform3_dom.value);
	console.log("transform4_dom.value -> " + transform4_dom.value);
	console.log("transform5_dom.value -> " + transform5_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	console.log("test_text1_dom -> " + test_text1_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let rotate_value = transform1_dom.value
	                 + ',' + transform2_dom.value
	                 + ',' + transform3_dom.value
	                 + ',' + transform4_dom.value
	                 + ',' + transform5_dom.value;

	// SVG要素のtransform3属性を変更する
	test_text1_dom.setAttribute('rotate', rotate_value);
	
	// 画面出力
	let transform3_value_dom = document.getElementById('transform3_value');
	transform3_value_dom.innerHTML = transform3_dom.value + '<br />';

});

// スライダtransform4の要素を取得し、イベントを付与する
let transform4_dom = document.getElementById('transform4');
transform4_dom.addEventListener('input', function(e) {

	console.log("transform1_dom.value -> " + transform1_dom.value);
	console.log("transform2_dom.value -> " + transform2_dom.value);
	console.log("transform3_dom.value -> " + transform3_dom.value);
	console.log("transform4_dom.value -> " + transform4_dom.value);
	console.log("transform5_dom.value -> " + transform5_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	console.log("test_text1_dom -> " + test_text1_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let rotate_value = transform1_dom.value
	                 + ',' + transform2_dom.value
	                 + ',' + transform3_dom.value
	                 + ',' + transform4_dom.value
	                 + ',' + transform5_dom.value;

	// SVG要素のtransform4属性を変更する
	test_text1_dom.setAttribute('rotate', rotate_value);
	
	// 画面出力
	let transform4_value_dom = document.getElementById('transform4_value');
	transform4_value_dom.innerHTML = transform4_dom.value + '<br />';

});

// スライダtransform5の要素を取得し、イベントを付与する
let transform5_dom = document.getElementById('transform5');
transform5_dom.addEventListener('input', function(e) {

	console.log("transform1_dom.value -> " + transform1_dom.value);
	console.log("transform2_dom.value -> " + transform2_dom.value);
	console.log("transform3_dom.value -> " + transform3_dom.value);
	console.log("transform4_dom.value -> " + transform4_dom.value);
	console.log("transform5_dom.value -> " + transform5_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	console.log("test_text1_dom -> " + test_text1_dom);

	// パラメータ1~パラメータ5まで値をリスト(配列)形式にして角度を決定する
	let rotate_value = transform1_dom.value
	                 + ',' + transform2_dom.value
	                 + ',' + transform3_dom.value
	                 + ',' + transform4_dom.value
	                 + ',' + transform5_dom.value;

	// SVG要素のtransform5属性を変更する
	test_text1_dom.setAttribute('rotate', rotate_value);
	
	// 画面出力
	let transform5_value_dom = document.getElementById('transform5_value');
	transform5_value_dom.innerHTML = transform5_dom.value + '<br />';

});

</script>


</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト」という文字列が表示されます。

スライダーは1から5まであり、1、2、3、4までのスライダを動かすと、それぞれ
1文字目、2文字目、3文字目、4文字目までの各文字が角度指定されて回転します。

ただ、スライダの5番目だけは挙動が異なり、5文字目以降の「のテスト」全体に効果がかかります。

このことから、setAttributeのrotateの指定は、上記の仕様で動作することがわかります。

SVGについて – テキストについて(2)

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて(2)

テキストのtransform属性のrotateについて

SVGで出力したテキストのtransform属性について調べてみます。

MDNドキュメントを確認すると、「transform 属性は、要素とその要素の子に適用される変換定義のリストを定義します。」とあります。

ここでは、rotate の値を試してみます。

簡単なサンプルとして以下のコードを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
#transform {
	width: 200px;
}
</style>


</head>
<body>
<svg width="200" height="200" viewBox="0 0 200 200">

	<text
		id="test_text1"
		x="50"
		y="50"
		dx="0"
		dy="0"
		transform="rotate(0, 20,40)"
	>
	テキストのテスト
	</text>

</svg>


<div>
	<span class="param_title">パラメータ</span>

	<div class="params_box">
		<div><input type="range" id="transform" value="0" max="360"></div>
		<span>transform (rotate) :</span>
		<span class="params" id="transform_value"></span>
	</div>

</div>


<script>

// スライダtransformの要素を取得し、イベントを付与する
let transform_dom = document.getElementById('transform');
transform_dom.addEventListener('input', function(e) {

	console.log("transform_dom.value -> " + transform_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	console.log("test_text1_dom -> " + test_text1_dom);

	// SVG要素のtransform属性を変更する
	test_text1_dom.setAttribute('transform', 'rotate(' + transform_dom.value + ')');
	
	// 画面出力
	let transform_value_dom = document.getElementById('transform_value');
	transform_value_dom.innerHTML = transform_dom.value + '<br />';

});

</script>


</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト」という文字列が表示されます。

さらに、画面上のスライダを移動すると、「id=”test_text1″」で定義したテキスト要素の
rotateが更新され、標示している文字列が回転します。

初期値は「0度」から始まり、最大値は「360度」になります。
viewboxのサイズの都合上、90度以上になると画面出力のエリア外になりますが、
360度に近づくにつれてまた画面上に出力されることがわかります。

テキストのrotate属性のについて

では次に、上記サンプルを少し変更し、

このサンプルを基に、text要素の各パラメータについて調べます。

SVGについて – テキストのrotate属性について

先程のサンプルのtransformをrotateに変更してみます。

これは前回投稿したサンプルと同じ結果になります。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style>
#transform {
	width: 200px;
}
</style>


</head>
<body>
<svg width="200" height="200" viewBox="0 0 200 200">

	<text
		id="test_text1"
		x="20"
		y="20"
		dx="0"
		dy="0"
	>
	テキストのテスト
	</text>

</svg>


<div>
	<span class="param_title">パラメータ</span>

	<div class="params_box">
		<div><input type="range" id="transform" value="0" max="360"></div>
		<span>rotate :</span>
		<span class="params" id="transform_value"></span>
	</div>

</div>


<script>

// スライダtransformの要素を取得し、イベントを付与する
let transform_dom = document.getElementById('transform');
transform_dom.addEventListener('input', function(e) {

	console.log("transform_dom.value -> " + transform_dom.value);

	// パターン内のDOM情報を取得する
	let test_text1_dom = document.getElementById('test_text1');
	console.log("test_text1_dom -> " + test_text1_dom);

	// SVG要素のrotateを変更する
	test_text1_dom.setAttribute('rotate', transform_dom.value);

	// 画面出力
	let transform_value_dom = document.getElementById('transform_value');
	transform_value_dom.innerHTML = transform_dom.value + '<br />';

});

</script>


</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクアスすると、テキスト文字列が標示されます。

スライダを変更すると、1文字づつ各文字が回転します。

先程のテスト1では、 transform の属性として rotate の値を変更しています。
この場合は、テキスト全体を回転する動きになり、

テスト2では、テキストのDOM要素に対して各文字ごとに rotate が反映されて回転することがわかります。

SVGについて – テキストについて

Posted コメントするカテゴリー: javascript

SVGについて – テキストについて

SVGでテキスト出力について試してみます。

簡単なサンプルとして以下のコードを用意しました。

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

<svg width="200" height="200" viewBox="0 0 200 200">

	<text
		x="0"
		y="20"
		dx="0"
		dy="0"
	>
	テキストのテスト
	</text>

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、「テキストのテスト」という文字列が表示されます。

viewBoxで指定した領域に、text要素を定義しているだけのシンプルなものです。

このサンプルを基に、text要素の各パラメータについて調べます。

SVGについて – テキストのrotate属性について

先程のサンプルのtext要素に、rotate属性を追加し値を20に設定してみます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

</head>
<body>
<svg width="200" height="200" viewBox="0 0 200 200">

	<text
		x="0"
		y="20"
		dx="0"
		dy="0"
		rotate="20"
	>
	テキストのテスト
	</text>

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクアスすると、各文字列に対して20度の角度がついていることがわかります。

SVGについて – グラデーションについて(その4)

Posted コメントするカテゴリー: javascript

SVGについて – グラデーションについて(その4)

パターンについて

前回のサンプルに対して、パターンを試してみます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>

<style type="text/css">
.params {
	float: left;
}
.params_box {
	display: flex;
}
.param_title {
	font-weght: bold;
}
</style>

</head>
<body>
<svg width="200" height="200" viewBox="0 0 200 200">

	<defs>
		<radialGradient
			id="radial_gradient1"
		>
			<stop offset="0%" stop-color="#333"/>
			<stop offset="100%" stop-color="#fff"/>

		</radialGradient>
		
		<pattern
			id="test_pattern1"
			x="0"
			y="0"
			width="0.3"
			height="0.4"
		>
			<circle
				id="test_circle1"
				cx="23"
				cy="23"
				r="25"
				fill="url(#radial_gradient1)"
			/>
		</pattern>
		
	</defs>

	<rect
        x            = "0"
        y            = "0"
        width        = "150"
        height       = "150"
        fill         = "url(#test_pattern1)"
    />

</svg>


<div>
	<span class="param_title">patternタグのパラメータ</span>

	<div class="params_box">
		<input type="range" id="pattern_x" value="0">
		<div>x:</div>
		<div class="params" id="test_pattern_x"></div>
	</div>

	<div class="params_box">
		<input type="range" id="pattern_y" value="0">
		<div>y:</div>
		<div class="params" id="test_pattern_y"></div>
	</div>

</div>

<div>
	<span class="param_title">circleタグのパラメータ</span>

	<div class="params_box">
		<input type="range" id="circle_cx">
		<div>cx:</div>
		<div class="params" id="test_circle_cx"></div>
	</div>

	<div class="params_box">
		<input type="range" id="circle_cy">
		<div>cy:</div>
		<div class="params" id="test_circle_cy"></div>
	</div>

	<div class="params_box">
		<input type="range" id="circle_r">
		<div>r :</div>
		<div class="params" id="test_circle_r"></div>
	</div>

</div>


<script>

// スライダpattern_xの要素を取得し、イベントを付与する
let pattern_x_dom = document.getElementById('pattern_x');
pattern_x_dom.addEventListener('input', function(e) {

	console.log("pattern_x_dom.value -> " + pattern_x_dom.value);

	// パターン内の円情報(DOM)を取得する
	let test_pattern1_dom = document.getElementById('test_pattern1');
	console.log("test_pattern1_dom -> " + test_pattern1_dom);

	// SVG要素のcxを変更する
	test_pattern1_dom.setAttribute('x', pattern_x_dom.value);
	
	// 画面出力
	let test_pattern_x_dom = document.getElementById('test_pattern_x');
	test_pattern_x_dom.innerHTML = pattern_x_dom.value + '<br />';

});

// スライダpattern_yの要素を取得し、イベントを付与する
let pattern_y_dom = document.getElementById('pattern_y');
pattern_y_dom.addEventListener('input', function(e) {

	console.log("pattern_y_dom.value -> " + pattern_y_dom.value);

	// パターン内の円情報(DOM)を取得する
	let test_pattern1_dom = document.getElementById('test_pattern1');
	console.log("test_pattern1_dom -> " + test_pattern1_dom);

	// SVG要素のcxを変更する
	test_pattern1_dom.setAttribute('y', pattern_y_dom.value);
	
	// 画面出力
	let test_pattern_y_dom = document.getElementById('test_pattern_y');
	test_pattern_y_dom.innerHTML = pattern_y_dom.value + '<br />';

});


// スライダcircle_cxの要素を取得し、イベントを付与する
let circle_cx_dom = document.getElementById('circle_cx');
circle_cx_dom.addEventListener('input', function(e) {

	console.log("circle_cx_dom.value -> " + circle_cx_dom.value);

	// パターン内の円情報(DOM)を取得する
	let test_circle1_dom = document.getElementById('test_circle1');
	console.log("test_circle1_dom -> " + test_circle1_dom);

	// SVG要素のcxを変更する
	test_circle1_dom.setAttribute('cx', circle_cx_dom.value);
	
	// 画面出力
	let test_circle_cx_dom = document.getElementById('test_circle_cx');
	test_circle_cx_dom.innerHTML = circle_cx_dom.value + '<br />';

});

// スライダcircle_cyの要素を取得し、イベントを付与する
let circle_cy_dom = document.getElementById('circle_cy');
circle_cy_dom.addEventListener('input', function(e) {

	console.log("circle_cy_dom.value -> " + circle_cy_dom.value);

	// パターン内の円情報(DOM)を取得する
	let test_circle1_dom = document.getElementById('test_circle1');
	console.log("test_circle1_dom -> " + test_circle1_dom);

	// SVG要素のcxを変更する
	test_circle1_dom.setAttribute('cy', circle_cy_dom.value);
	
	// 画面出力
	let test_circle_cy_dom = document.getElementById('test_circle_cy');
	test_circle_cy_dom.innerHTML = circle_cy_dom.value + '<br />';

});

// スライダcircle_rの要素を取得し、イベントを付与する
let circle_r_dom = document.getElementById('circle_r');
circle_r_dom.addEventListener('input', function(e) {

	console.log("circle_r_dom.value -> " + circle_r_dom.value);

	// パターン内の円情報(DOM)を取得する
	let test_circle1_dom = document.getElementById('test_circle1');
	console.log("test_circle1_dom -> " + test_circle1_dom);

	// SVG要素のcxを変更する
	test_circle1_dom.setAttribute('r', circle_r_dom.value);
	
	// 画面出力
	let test_circle_r_dom = document.getElementById('test_circle_r');
	test_circle_r_dom.innerHTML = circle_r_dom.value + '<br />';

});

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、放射状のグラデーションの円が、パターン表示されたものが表示されます。

また、画面内のパラメータは、patternのDOM要素と、circleのDOM要素を、パラメータを変化させることにより、
動的に描画結果を見られるように設置しています。

初期状態から、各パラメータを変えることにより、各パラメータがどのように描画に影響するかが確認できます。

SVGについて – グラデーションについて(その3)

Posted コメントするカテゴリー: javascript

SVGについて – グラデーションについて(その3)

放射型グラデーション

放射型グラデーションはradialGradient要素で定義されています。

		<radialGradient
			id="radial_gradient1"
		>
			<stop offset="0%" stop-color="#333"/>
			<stop offset="100%" stop-color="#fff"/>

		</radialGradient>

全体は下記です。

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

<svg width="200" height="200" viewBox="0 0 200 200">

	<defs>
		<radialGradient
			id = "radial_gradient1"
		>
			<stop offset="0%" stop-color="#333"/>
			<stop offset="100%" stop-color="#fff"/>

		</radialGradient>
	</defs>

	<rect
        x      = "0"
        y      = "0"
        width  = "150"
        height = "150"
        fill   = "url(#radial_gradient1)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、放射状のグラデーションの円が表示されます。

上記のサンプルはrect(矩形)に対してのグラデーション指定です。

次にcircleのグラデーションを試してみます。

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

<svg width="200" height="200" viewBox="0 0 200 200">

	<defs>
		<radialGradient
			id = "radial_gradient2"
			cx = "0.5"
			cy = "0.5"
			r  = "0.5"
			fx = "0.7"
			fy = "0.3"
		>
			<stop offset="0%" stop-color="#333"/>
			<stop offset="100%" stop-color="#fff"/>

		</radialGradient>
	</defs>

	<rect
        x      = "0"
        y      = "0"
        width  = "150"
        height = "150"
        fill   = "url(#radial_gradient2)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、fxとfyで指定した位置が焦点とされ、やや右上の座標に放射状にグラデーションがかかる描画になります。

「radialGradient」に設定した各パラメータは、次の意味になります。

cx        グラデーションの中心点のX座標
cy        グラデーションの中心点のY座標
r         グラデーションの半径
fx        グラデーションの焦点のX軸方向の値
fy        グラデーションの焦点のY軸方向の値

放射型グラデーションのspreadMethodについて

前回のサンプルをもとに、放射型グラデーションのspreadMethod属性について、試してみます。

spreadMethod属性は、グラデーションが終了した後に塗りつぶされていない領域をどう出力するかを制御します。

属性の値は「pad」「reflect」「repeat」があります。

属性値:padの場合

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

<svg width="200" height="200" viewBox="0 0 200 200">

	<defs>
		<radialGradient
			id           = "radial_gradient2"
			cx           = "0.5"
			cy           = "0.5"
			r            = "0.5"
			fx           = "0.7"
			fy           = "0.3"
			spreadMethod = "pad"
		>
			<stop offset="0%" stop-color="#333"/>
			<stop offset="100%" stop-color="#fff"/>

		</radialGradient>
	</defs>

	<rect
        x      = "0"
        y      = "0"
        width  = "150"
        height = "150"
        fill   = "url(#radial_gradient2)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test3.html)

画面にアクセスすると、さきほどのサンプルと同様の出力になり、あまり違いはわかりません(これは各パラメータの値によります)

spreadMethod属性が「pad」の場合は、グラデーションが終了すると、最終的なオフセットの値をもとに周囲を埋めて描画します。

属性値:reflectの場合

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

<svg width="200" height="200" viewBox="0 0 200 200">

	<defs>
		<radialGradient
			id           = "radial_gradient2"
			cx           = "0.5"
			cy           = "0.5"
			r            = "0.5"
			fx           = "0.7"
			fy           = "0.3"
			spreadMethod = "reflect"
		>
			<stop offset="0%" stop-color="#333"/>
			<stop offset="100%" stop-color="#fff"/>

		</radialGradient>
	</defs>

	<rect
        x      = "0"
        y      = "0"
        width  = "150"
        height = "150"
        fill   = "url(#radial_gradient2)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test4.html)

画面にアクセスすると、spreadMethod属性が「reflect」なので、グラデーションが継続されて描画されますが、グラデーションの終わりから逆に反射した形で描画していることがわかります。

属性値:repeatの場合

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

<svg width="200" height="200" viewBox="0 0 200 200">

	<defs>
		<radialGradient
			id           = "radial_gradient2"
			cx           = "0.5"
			cy           = "0.5"
			r            = "0.5"
			fx           = "0.7"
			fy           = "0.3"
			spreadMethod = "repeat"
		>
			<stop offset="0%" stop-color="#333"/>
			<stop offset="100%" stop-color="#fff"/>

		</radialGradient>
	</defs>

	<rect
        x      = "0"
        y      = "0"
        width  = "150"
        height = "150"
        fill   = "url(#radial_gradient2)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test5.html)

画面にアクセスすると、spreadMethod属性が「repeat」なので、グラデーションが最初の値から改めてグラデーションが開始されて描画されます。

SVGについて – グラデーションについて(その2)

Posted コメントするカテゴリー: javascript

SVGについて – グラデーションについて(その2)

線形グラデーションの透明度について

前回のサンプルに対して、パラメータを調整してみます。

下記の箇所で、グラデーションの開始位置と、色情報を指定していますが、

    <linearGradient
        id = "grad1"
        x1 = "0"
        y1 = "0"
        x2 = "1"
        y2 = "0"
    >
	    <stop offset="0%"   stop-color="#000000" />
	    <stop offset="100%" stop-color="#ffffff" />
    </linearGradient>

このパラメータの最初の色情報と、最後の色情報に対して、透明度を追加します。

    <linearGradient
        id = "grad1"
        x1 = "0"
        y1 = "0"
        x2 = "1"
        y2 = "0"
    >
	    <stop offset="0%"   stop-color="#000000" stop-opacity="0.2" />
	    <stop offset="100%" stop-color="#ffffff" stop-opacity="0.5" />
    </linearGradient>

全体は下記です。

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

<svg width="200" height="200" viewBox="0 0 200 200">

    <linearGradient
        id = "grad1"
        x1 = "0"
        y1 = "0"
        x2 = "1"
        y2 = "0"
    >
	    <stop offset="0%"   stop-color="#000000" stop-opacity="0.2" />
	    <stop offset="100%" stop-color="#ffffff" stop-opacity="0.5" />
    </linearGradient>

    <rect
        x            = "0"
        y            = "0"
        stroke       = "#cccccc"
        stroke-width = "1"
        width        = "150"
        height       = "150"
        fill         = "url(#grad1)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、

stop-opacity

で、指定した値で色の透明度が決まります。

上記のサンプルの値を少し変えて比較してみます。

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

<svg width="200" height="200" viewBox="0 0 200 200">

    <linearGradient
        id = "grad1"
        x1 = "0"
        y1 = "0"
        x2 = "1"
        y2 = "0"
    >
	    <stop offset="0%"   stop-color="#000000" stop-opacity="0.7" />
	    <stop offset="100%" stop-color="#ffffff" stop-opacity="0.8" />
    </linearGradient>

    <rect
        x            = "0"
        y            = "0"
        stroke       = "#cccccc"
        stroke-width = "1"
        width        = "150"
        height       = "150"
        fill         = "url(#grad1)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、最初に書いたサンプルより、濃い配色でSVGが出力されることがわかります。
stop-opacityの値が1に近づくほど、透明度は元の色に近くなります。

線形グラデーションの方向指定

linearGradient 要素に対して、x1, x2, y1, y2 の指定で、グラデーションの方向を決定できます。

先程のサンプルの、下記の箇所

    <linearGradient
        id = "grad1"
        x1 = "0"
        y1 = "0"
        x2 = "1"
        y2 = "0"
    >

を、以下に変更します。

    <linearGradient
        id = "grad1"
        x1 = "0"
        y1 = "0"
        x2 = "0"
        y2 = "1"
    >

全体です。

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

<svg width="200" height="200" viewBox="0 0 200 200">

    <linearGradient
        id = "grad1"
        x1 = "0"
        y1 = "0"
        x2 = "0"
        y2 = "1"
    >
	    <stop offset="0%"   stop-color="#000000" stop-opacity="0.7" />
	    <stop offset="100%" stop-color="#ffffff" stop-opacity="0.8" />
    </linearGradient>

    <rect
        x            = "0"
        y            = "0"
        stroke       = "#cccccc"
        stroke-width = "1"
        width        = "150"
        height       = "150"
        fill         = "url(#grad1)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test3.html)

画面にアクセスすると、グラデーションの方向が、上から下に変化していることがわかります。

SVGについて – グラデーションについて

Posted コメントするカテゴリー: javascript

SVGについて – グラデーションについて

線形グラデーション

図形の着色をグラデーション化します。

まずはシンプルなサンプルコードを用意しました。

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

<svg width="200" height="200" viewBox="0 0 200 200">

    <linearGradient
        id = "grad1"
        x1 = "0"
        y1 = "0"
        x2 = "1"
        y2 = "0"
    >

    <stop offset="0%"   stop-color="#000000" />
    <stop offset="100%" stop-color="#ffffff" />

    </linearGradient>

    <rect
        x            = "0"
        y            = "0"
        stroke       = "#cccccc"
        stroke-width = "1"
        width        = "150"
        height       = "150"
        fill         = "url(#grad1)"
    />

</svg>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、縦150、横150の正方形が表示され、
内部の背景色は、黒(#000000)から白(#ffffff)へグラデーションで着色されます。

グラデーションの描画について、次回以降の投稿で詳細を調べていきます。

SVGについて – 塗りについて

Posted コメントするカテゴリー: javascript

SVGについて – 塗りについて

図形を着色する

stroke属性が図形を囲む線の着色、fill属性が図形内部の着色です。

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

<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d            = "M 20 20
                        A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
    />
</svg>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

実行結果

stroke属性の値は

色名
RGB値
16進数
RGBA値

の表記方法になります。

透明度を決定する

図形を囲む線の透明度はstroke-opacity属性、
図形の透明度はfill-opacity属性でそれぞれ決定します。

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

<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d              = "M 20 20
                          A 20 20 0 0 1 100 100"
        stroke         = "#4f4f4f"
        stroke-width   = "1"
        stroke-opacity = "0.3"
        fill           = "#cccccc"
        fill-opacity   = "0.3"
    />
</svg>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

実行結果

ストローク(線の種類)を決定する

ストロークの属性(stroke-linecap)を指定すると、ストロークの端の描画方法を制御できます。
属性の値と効果は以下になります。

stroke-width      幅
stroke-linecap    形状
    butt    ストローク方向に垂直な直線
    square  ストロークの終端をstroke-widthの半分の値で描画(垂直)
    round   ストロークの終端を丸める(非垂直に描画)

サンプル

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

<div>例1 (butt)</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d              = "M 30 30
                          A 30 30 0 0 1 110 110"
        stroke         = "#4f4f4f"
        stroke-width   = "15"
        stroke-linecap = "butt"
        stroke-opacity = "0.3"
        fill           = "#cccccc"
        fill-opacity   = "0.3"
    />
</svg>

<div>例2 (square)</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d              = "M 30 30
                          A 30 30 0 0 1 110 110"
        stroke         = "#4f4f4f"
        stroke-width   = "15"
        stroke-linecap = "square"
        stroke-opacity = "0.3"
        fill           = "#cccccc"
        fill-opacity   = "0.3"
    />
</svg>

<div>例3 (round)</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d              = "M 30 30
                          A 30 30 0 0 1 110 110"
        stroke         = "#4f4f4f"
        stroke-width   = "15"
        stroke-linecap = "round"
        stroke-opacity = "0.3"
        fill           = "#cccccc"
        fill-opacity   = "0.3"
    />
</svg>

</body>
</html>

サーバ上のHTMLはこちら(test3.html)

実行結果

例1 (butt)

例2 (square)

例3 (round)

ストローク(線の種類)を決定する (破線)

ストロークの線種(stroke-dasharray)を制御できます。

値は「カンマ区切りで複数の数値」で指定できます。
下記の例では、「stroke-dasharray = “15, 5″」としており、
動作例を見てみると、実線で15ピクセル描画した後、5ピクセルの空白、その次にまた実線で15ピクセル、空白で5ピクセルという順で線が描画されています。

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

<div>例1</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d                = "M 30 30
                            A 30 30 0 0 1 110 110"
        stroke           = "#4f4f4f"
        stroke-width     = "15"
        stroke-linecap   = "butt"
        stroke-dasharray = "15, 5"
        stroke-opacity   = "0.3"
        fill             = "#cccccc"
        fill-opacity     = "0.3"
    />
</svg>

</body>
</html>

実行結果

サーバ上のHTMLはこちら(test4.html)

stroke-dasharrayの値をカンマ区切りで複数の数値を記載したパターンを試します。
下記のサンプルを用意しました。

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

<div>例1</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d                = "M 30 30
                            A 30 30 0 0 1 110 110"
        stroke           = "#4f4f4f"
        stroke-width     = "15"
        stroke-linecap   = "butt"
        stroke-dasharray = "15, 5, 30"
        stroke-opacity   = "0.3"
        fill             = "#cccccc"
        fill-opacity     = "0.3"
    />
</svg>

</body>
</html>

サーバ上のHTMLはこちら(test5.html)

画面にアクセスすると下記のような表示になります。

実行結果

この破線の描画ルールは、「15, 5, 30」の各ピクセルごとに、実線 → 空白 → 実線 という幅で破線が描画されています。
また、始点から終点まで上記のルールを繰り返して描画します。

各、実線と空白、そして幅のルールがわかりやすいように数値と色をつけたものが下記の図です。

最初、赤文字で「15, 5, 30」の間隔で破線(実線 → 空白 → 実線)を描画し、
次に、青文字で「15, 5, 30」の間隔で破線(空白 → 実線 → 空白)を描画しています。

その次に、また赤文字の「15, 5, 30」の間隔で描画がされ、その後、青文字での描画 → 赤文字での描画 ・・・と線分が終わるまで繰り返されます。


(注:図形のサイズは、数値をわかりやすくする為に拡大しています)

SVGについて – パス(円孤)について

Posted コメントするカテゴリー: javascript

SVGについて – パス(円孤)について

円孤について(正円)

今回はパス(円孤)の使い方について、調べてみます。

円孤を出力するコマンドは Aで記載します。
円孤は開始、終了の座標の値により、描かれるパスが変わり正円と楕円になります。
また、x軸とy軸 の方向にどれだけの長さで線を描画するかで、正円か楕円かが決まります。
(注:円の種類を決める目的で座標を決める訳ではなく、結果的に正円か楕円の描画になるかならないかです)

簡単なサンプルを書きました。

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

<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d            = "M 20 20
                        A 20 20 0 0 1 100 100"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
    />
</svg>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、以下の円孤が表示されます。

孤がどのように描画されるかのポイントとなる点は、 M と A のパラメータの値です。

例えば、以下のパラメータの場合、

M 20 20
A 20 20 0 0 1 100 100

それぞれのパラメータの意味は次のようになります。

パラメータの値の下の行に、汎用的な名称を記載しています。

M 20 20
  x1 y1

A 20 20 0 0  1  100 100
  rx ry k f1 f2 x2  y2

各パラメータの意味は以下のようになります。

x1     円弧の開始 x座標
y1     円弧の開始 y座標
rx     円のx軸半径
ry     円のy軸半径
k      回転度(プラスで右方向、マイナスで左方向)
f1     0 : 180未満の円弧
       1 : 180以上の円弧
f2     0 : 正の角度で動き始めるか (反時計回りに描画)
       1 : 負の角度で動き始めるか (時計回りに描画)
x2     円弧の終了 x座標
y2     円弧の終了 y座標

上記のサンプルでは、描画される孤は x軸方向、y軸方向の開始座標、終了座標が同じ座標を示しており、正円の軌道になります。

円孤について(楕円)

サンプルを少し変更して、次のコードを用意しました。

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

<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d            = "M 30 30
                        A 20 30 0 0 1 100 150"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
    />
</svg>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、以下の円孤が表示されます。

先ほどのサンプルから、A のパラメータを以下のように変更しました。

A 20 30 0 0 1 100 150

最初のサンプルとは違い、開始点から描画される円の「x方向の半径」、「y方向の半径」が異なります。
また、引数の最後の終了x座標、終了y座標も異なります。

このパラメータ指定の場合は、正円の孤にはならず、楕円上の軌道で描画されます。

円孤について(他のパラメータ)

それでは、2つ目のサンプルを調整し、他のパラメータを変更してみます。

Aのパラメータの第三引数が回転度になるので、
それぞれ、0度、45度、90度、135度、180度の指定を試してみます。

Aのみを抜粋すると、以下です。

A 20 30   0 0 1 100 150
A 20 30  45 0 1 100 150
A 20 30  90 0 1 100 150
A 20 30 135 0 1 100 150
A 20 30 180 0 1 100 150

HTML全体は次のようになります。

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

<div>0度</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d            = "M 30 30
                        A 20 30 0 0 1 100 150"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
    />
</svg>


<div>45度</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d            = "M 30 30
                        A 20 30 45 0 1 100 150"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
    />
</svg>


<div>90度</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d            = "M 30 30
                        A 20 30 90 0 1 100 150"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
    />
</svg>


<div>135度</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d            = "M 30 30
                        A 20 30 135 0 1 100 150"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
    />
</svg>


<div>180度</div>
<svg width="200" height="200" viewBox="0 0 200 200">
    <path 
        d            = "M 30 30
                        A 20 30 180 1 1 100 150"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "#cccccc"
    />
</svg>


</body>
</html>

サーバ上のHTMLはこちら(test3.html)

画面にアクセスすると、以下の円孤が表示されます。

それぞれの度数によって、楕円の座標の描画が回転して描画されます。
ただ、0度の出力と、180度の出力は同じ結果になります。

SVGについて – パス(2次ベジェ曲線)について

Posted コメントするカテゴリー: javascript

SVGについて – パス(2次ベジェ曲線)について

2次ベジェ曲線について

前回の投稿は3次ベジェ曲線でしたが、今回はパス(2次ベジェ曲線)の使い方について、調べてみます。

2次ベジェ曲線は「Q」コマンドを使って指定します。
3次ベジェ曲線は制御点を2箇所持ちましたが、2次ベジェ曲線は制御点を1つだけ持ちます。

前回のサンプルを調整して以下のHTMLを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
 
<svg width="300" height="250" viewBox="0 0 300 250">
    <path 
        d            = "M 10,10 Q 160,240 290,10"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "transparent"
    />
</svg>
 
</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、以下のベジェ曲線が表示されます。

ポイントとなる点は、dのパラメータの値です。

        d            = "M 10,10 Q 160,200 290,10"

まず、最初の「M 10, 10」で、曲線の始点を決めています。
次に「Q 160,200」で、始点から次の曲線までの座標(制御点)を決定し、
その制御点から終点への座標への曲線を決定しています。

2次ベジェ曲線について – 複数の制御点を持つ場合

2次ベジェ曲線の制御点を組み合わせることができます。
制御点を組み合わせる場合は Tコマンド を使います。
下記サンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
 
<svg width="300" height="300" viewBox="0 0 300 300">
    <path 
        d            = "M 10,150 Q 50 10, 150 150 T 290,150"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "transparent"
    />
</svg>
 
</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、以下のベジェ曲線が表示されます。

今回はシンプルな例でしたが、状況に合わせて制御点を追加してベジェ曲線をコントロールします。

SVGについて – パス(ベジェ曲線)について

Posted コメントするカテゴリー: javascript

SVGについて – パス(ベジェ曲線)について

パス(ベジェ曲線)の使い方について、調べてみます。

SVGで扱えるベジェ曲線は2種類で、
三次ベジェ曲線「C」と二次ベジェ曲線「Q」です。

三次ベジェ曲線

まずは三次ベジェ曲線を試します。

前回のサンプルを調整して以下のHTMLを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
 
<svg width="300" height="250" viewBox="0 0 300 250">
    <path 
        d            = "M 10,10 C 20,50 270,50 290,10"
        stroke       = "#4f4f4f"
        stroke-width = "2"
        fill         = "transparent"
    />
</svg>
 
</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、以下のベジェ曲線が表示されます。

ポイントとなる点は、dのパラメータの値です。

        d            = "M 10,10 C 20,50 270,50 290,10"

まず、最初の「M 10, 10」で、曲線の始点を決めています。
次に「C 20,50」で、始点から次の曲線までの座標(制御点)を決定し、
「270,50」で、終点への座標(制御点)を決定しています。

上記の場合は「10, 10」から次の点までは「20, 50」さらに次の点までは「270,50」という値で座標を決定しています。

一番最後の「290,10」は曲線の終点です。

複数の三次ベジェ曲線

上記の例をさらに発展させて、複数の制御点を持つベジェ曲線を試してみます。

複数の制御点については

        d            = "M 10,10 C 20,50 270,50 290,10"

上記のdのパラメータに、S を追加します。

以下のHTMLを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
 
<svg width="300" height="250" viewBox="0 0 300 250">
    <path 
        d            = "M 10,10 C 20,50 100,50 120,10 S 130,60 250,200"
        stroke       = "#4f4f4f"
        stroke-width = "1"
        fill         = "transparent"
    />
</svg>
 
</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、以下のベジェ曲線が表示されます。

パタメータのdは、以下のように設定しています。

        d            = "M 10,10 C 20,50 100,50 120,10 S 130,60 250,200"

最初の始点「M 10,10」から開始し、最初の制御点「C 20,50」に向けて曲線が描画され、
次の終点に向かう制御点「100,50」から終点「120,10」にむけて曲線が描画されます。

その後に「S 130,60」の制御点が決定されますが、ここでは、終点に向かう制御点「100,50」から
対向する形で曲線が描画されます。

最後は終点「250,200」まで曲線が描画されて終わります。

SVGについて – パスについて

Posted コメントするカテゴリー: javascript

SVGについて – パスについて

パスの使い方について、調べてみます。

下記の簡単なサンプルを用意しました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
 
<svg width="300" height="250">
    <path 
    	d            = "M 10,10 90,150 120,20 10,10"
    	stroke       = "#999999"
    	stroke-width = "1"
    	fill         = "#cccccc"
    />
</svg>
 
</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、以下のように画面上に3角形の図形が表示されます。

先程のHTML内で、パスを表す箇所は次のように書きました。

<path 
	d            = "M 10,10 90,150 120,20 10,10"
	stroke       = "#999999"
	stroke-width = "1"
	fill         = "#cccccc"
/>

便宜上、それぞれのパラメータごとに、改行して表記し、パラメータ名と値の縦の記載を揃えています。
実際のプログラミングでは必ずしも上記のように書かなくとも良いですが、
ここではパラメータと名称を把握しやすくする為に、この形にしています。

パラメータの d は形状によって定義されています。

また、値の M は、Move toコマンドといい、省略した意味で M と記載されています。

d            = "M 10,10 90,150 120,20 10,10"

パラメータ名 d の 値である一番最初の「M 10,10」は

座標 x = 10 y = 10 の座標位置にパスを移動する。という意味になります。

また、

d            = "M 10,10 90,150 120,20 10,10"

「M 10,10」の次の「90,150」は、 x = 90 y = 150 の位置にパスを移動する。という意味になります。

試しに、上記の2つのパス移動だけのパラメータにしてみます。
先程の path情報の d の定義を、以下のように変更します。

<path 
	d            = "M 10,10 90,150"
	stroke       = "#999999"
	stroke-width = "1"
	fill         = "#cccccc"
/>

HTML全体では、次のように書きました。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
 
<svg width="300" height="250">
    <path 
    	d            = "M 10,10 90,150"
    	stroke       = "#999999"
    	stroke-width = "1"
    	fill         = "#cccccc"
    />
</svg>
 
</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、次のように出力されます。

出力画面をみるとわかるように、最初の x = 10 y = 10 の位置から、x = 90 y = 150 の位置にパスが移動(描画)されていることがわかります。

ここで、最初のサンプルに戻ります。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
 
<svg width="300" height="250">
    <path 
    	d            = "M 10,10 90,150 120,20 10,10"
    	stroke       = "#999999"
    	stroke-width = "1"
    	fill         = "#cccccc"
    />
</svg>
 
</body>
</html>

コードを改めて確認すると、パラメータ d の値は「M 10,10 90,150 120,20 10,10」となっており、

1つ目のパス → 10,10
2つ目のパス → 90,150
3つ目のパス → 120,20
4つ目のパス → 10,10

という情報を持っています。

ここで登場する4つ目のパスは、1つ目のパスと同じ情報「10, 10」と記載しています。

こうすることで、パスが一周して閉じたかのように描画されます。

ただし、これは便宜的に図形が閉じる座標を書いただけにすぎません。

パスの値として、最後に Z を書くことで、パスを1つ目のパス(始点)に戻るようにすることができます。

<svg width="300" height="250">
    <path 
    	d            = "M 10,10 90,150 120,20 Z"
    	stroke       = "#999999"
    	stroke-width = "1"
    	fill         = "#cccccc"
    />
</svg>

HTML全体では、次のように書きます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
 
<svg width="300" height="250">
    <path 
    	d            = "M 10,10 90,150 120,20 Z"
    	stroke       = "#999"
    	stroke-width = "1"
    	fill         = "#cccccc"
    />
</svg>
 
</body>
</html>

サーバ上のHTMLはこちら(test3.html)

画面にアクセスすると、次のように出力されます。

一番最初に試したサンプルと同じ出力結果になることがわかります。

SVGについて – viewBoxについて

Posted コメントするカテゴリー: javascript

SVGについて – viewBoxについて

前回のサンプルHTMLコードで、SVGのDOM要素を以下のように指定しました。

<svg id="svg_tag" width="500" height="400" viewBox="0 0 500 400" xmlns="http://www.w3.org/2000/svg"></svg> 

この際、SVGのDOM要素の幅と高さを500と400に指定しています。
また、属性として「viewBox」という属性も合わせて「0 0 500 400」と指定しています。

この「viewBox」の値がどのような効果があるのかを比較してみます。
まず、わかりやすいように、比較用のHTMLサンプルを用意しました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<svg id="svg_tag" width="500" height="400" viewBox="0 0 500 400" xmlns="http://www.w3.org/2000/svg"></svg> 

<script type="text/javascript">
let svg_dom = document.getElementById("svg_tag");
svg_dom.setAttribute("style", "background-color:#dbdbdb;");

let line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
line.setAttribute('id'    , 'svg_line_id1');
line.setAttribute('x1'    , '10');
line.setAttribute('y1'    , '10');
line.setAttribute('x2'    , '490');
line.setAttribute('y2'    , '390');
line.setAttribute('stroke', '#000000');

svg_dom.appendChild(line);

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

画面にアクセスすると、次のようなグレーのDOM領域に対して、DOM領域のx=0, y=0から10ピクセル離れた点から、
DOM領域全体のx=500, y=400から同様に10ピクセル離れた点までの直線が表示されます。

では次に、viewBoxの値のみを、ぞれぞれ半分にしてみます。

記述としては、以下になります。

<svg id="svg_tag" width="500" height="400" viewBox="0 0 250 200" xmlns="http://www.w3.org/2000/svg"></svg> 

HTML全体では、以下のようになります。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<svg id="svg_tag" width="500" height="400" viewBox="0 0 250 200" xmlns="http://www.w3.org/2000/svg"></svg> 

<script type="text/javascript">
let svg_dom = document.getElementById("svg_tag");
svg_dom.setAttribute("style", "background-color:#dbdbdb;");

let line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
line.setAttribute('id'    , 'svg_line_id1');
line.setAttribute('x1'    , '10');
line.setAttribute('y1'    , '10');
line.setAttribute('x2'    , '490');
line.setAttribute('y2'    , '390');
line.setAttribute('stroke', '#000000');

svg_dom.appendChild(line);

</script>

</body>
</html>

サーバ上のHTMLはこちら(test2.html)

画面にアクセスすると、ややわかりにくいですが、SVGのDOM要素の幅(500)と高さ(400)のグレー色になっている領域のサイズは変わらないですが、javascriptで定義したSVGの直線(line)は、2倍の大きさで描画されていることがわかります。

では、さらに、viewBoxの値のみを、ぞれぞれ2倍にしてみます。

記述としては、以下になります。

<svg id="svg_tag" width="500" height="400" viewBox="0 0 1000 800" xmlns="http://www.w3.org/2000/svg"></svg> 

HTML全体では、以下のようになります。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<svg id="svg_tag" width="500" height="400" viewBox="0 0 1000 800" xmlns="http://www.w3.org/2000/svg"></svg> 

<script type="text/javascript">
let svg_dom = document.getElementById("svg_tag");
svg_dom.setAttribute("style", "background-color:#dbdbdb;");

let line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
line.setAttribute('id'    , 'svg_line_id1');
line.setAttribute('x1'    , '10');
line.setAttribute('y1'    , '10');
line.setAttribute('x2'    , '490');
line.setAttribute('y2'    , '390');
line.setAttribute('stroke', '#000000');

svg_dom.appendChild(line);

</script>

</body>
</html>

サーバ上のHTMLはこちら(test3.html)

画面にアクセスすると、さきほどと同様に SVGのDOM要素の幅(500)と高さ(400)のグレー色になっている領域のサイズは変わらないですが、今度はjavascriptで定義したSVGの直線(line)は、半分(2分の1)の大きさで描画されていることがわかります。

ここまで試したことから、viewBoxの座標指定(開始X座標、開始Y座標、終了X座標、終了Y座標) はSVG内の要素をどのくらいの大きさで表示するかを決定していることがわかります。
また、SVGのDOM要素の幅(width)と高さ(height)は、画面上に表示するDOM要素のサイズを決定していることがわかります。

例えば、SVGのDOM要素の幅を500 x 400で決定しておき、SVG内の描画サイズを5倍の2500 x 2000で描画することもできるはずです。

実際にどのように表示されるかを検証してみました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<svg id="svg_tag" width="500" height="400" viewBox="0 0 2500 2000" xmlns="http://www.w3.org/2000/svg"></svg> 

<script type="text/javascript">
let svg_dom = document.getElementById("svg_tag");
svg_dom.setAttribute("style", "background-color:#dbdbdb;");

let line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
line.setAttribute('id'    , 'svg_line_id1');
line.setAttribute('x1'    , '10');
line.setAttribute('y1'    , '10');
line.setAttribute('x2'    , '490');
line.setAttribute('y2'    , '390');
line.setAttribute('stroke', '#000000');

svg_dom.appendChild(line);

</script>

</body>
</html>

サーバ上のHTMLはこちら(test4.html)

画面にアクセスすると、次のようになりました。

5倍のviewBoxの座標指定にすると、やや内容が確認しづらくなりました。
ただ、SVGはベクター情報ではなく、ラスター情報なので、描画サイズを大きくしても、小さくしても座標の計算に基づく表示をしていると言えます。

例は直線(line)のみでしたが、より複雑なベクター情報をもつSVG要素でもどうようの動きをします。
実際の開発時にはviewBoxのサイズ指定を考慮した実装にすると良いと思います。