クリッピング mask 要素について(その2) グラデーション

javascript

クリッピング mask 要素について(その2) グラデーション

クリッピングのmask要素をグラデーションにした場合を試してみます。

前回同様に鳥の画像に対して、radialGradient 指定したDOMを作成し、
その内部に2つの異なる色要素を指定してグラデーションを用意します。

<radialGradient id="radial_gradient1">
    <stop offset="35%" stop-color="#333" id="gradient_offset1" />
    <stop offset="70%" stop-color="#fff" id="gradient_offset2" />
</radialGradient>

また、以下のマスク要素のDOMを用意します。
この要素のfillには「fill = “url(#radial_gradient1)”」として、
上記のradialGradientで用意したグラデーション要素のIDを指定しています。

<mask id="test_mask">
    <path
        id           = "test_mask_dom1"
        d            = "M 50,250 400,200 110,5 Z"
        stroke       = "#999999"
        stroke-width = "1"
        fill         = "url(#radial_gradient1)"
    />
</mask>

上記の2つの要素を組み合わせ、マスク要素にグラデーションがどのように
効果するのかを試してみます。

全体のサンプルは以下です。

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

<style>
.params_box {
    font-size: 0.8em;
}
.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="300" viewBox="0 0 500 300">
    <defs>

        <radialGradient id="radial_gradient1">
            <stop offset="35%" stop-color="#333" id="gradient_offset1" />
            <stop offset="70%" stop-color="#fff" id="gradient_offset2" />
        </radialGradient>

        <mask id="test_mask">
            <path
                id           = "test_mask_dom1"
                d            = "M 50,250 400,200 110,5 Z"
                stroke       = "#999999"
                stroke-width = "1"
                fill         = "url(#radial_gradient1)"
            />
        </mask>

    </defs>

    <image href="./sima.jpg" mask="url(#test_mask)"/>

</svg>

<div>
    <div class="params_box">
        <span>param1 (グラデーションの色指定1) : </span><span class="params" id="range1_value"></span>
        <div><input type="range" class="range" id="range1" value="35" max="100"></div>
    </div>

    <div class="params_box">
        <span>param2 (グラデーションの色指定2) : <span class="params" id="range2_value"></span></span>
        <div><input type="range" class="range" id="range2" value="70" max="100"></div>
    </div>

    <div class="params_box">
        <span>param3 マスクの座標指定1のx座標) : <span class="params" id="range3_value"></span></span>
        <div><input type="range" class="range" id="range3" value="50" max="500"></div>
    </div>

    <div class="params_box">
        <span>param4 マスクの座標指定1のy座標) : <span class="params" id="range4_value"></span></span>
        <div><input type="range" class="range" id="range4" value="250" max="500"></div>
    </div>

    <div class="params_box">
        <span>param5 マスクの座標指定2のx座標) : <span class="params" id="range5_value"></span></span>
        <div><input type="range" class="range" id="range5" value="400" max="500"></div>
    </div>

    <div class="params_box">
        <span>param6 マスクの座標指定2のy座標) : <span class="params" id="range6_value"></span></span>
        <div><input type="range" class="range" id="range6" value="200" max="500"></div>
    </div>

    <div class="params_box">
        <span>param7 マスクの座標指定3のx座標) : <span class="params" id="range7_value"></span></span>
        <div><input type="range" class="range" id="range7" value="110" max="500"></div>
    </div>

    <div class="params_box">
        <span>param8 マスクの座標指定3のy座標) : <span class="params" id="range8_value"></span></span>
        <div><input type="range" class="range" id="range8" value="5" max="500"></div>
    </div>
</div>

<div class="code_view">
&lt;svg width="500" height="300" viewBox="0 0 500 300"&gt;<br />
    &lt;defs&gt;<br /><br />

        &lt;radialGradient id="radial_gradient1"&gt;<br />
            &lt;stop offset="<span id="code_view1"></span>%" stop-color="#333" id="gradient_offset1" /&gt;<br />
            &lt;stop offset="<span id="code_view2"></span>%" stop-color="#fff" id="gradient_offset2" /&gt;<br />
         &lt;/radialGradient&gt;<br /><br />

        &lt;mask id="test_mask_dom1"&gt;<br />
            &lt;path <br />
                d            = "<span id="code_view3"></span>"<br />
                stroke       = "#999999"<br />
                stroke-width = "1"<br />
                fill         = "url(#radial_gradient1)"<br />
            /&gt;<br />
        &lt;/mask&gt;<br />
    &lt;/defs&gt;<br /><br />

    &lt;image href="./sima.jpg" mask="url(#test_mask_dom1)"/&gt;<br />

&lt;/svg&gt;
</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');
let range7_dom = document.getElementById('range7');
let range8_dom = document.getElementById('range8');

// 各スライダーごとのイベントに、共通の関数を割り当てて処理する
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);
range7_dom.addEventListener('input', change_range_slider);
range8_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);
    console.log("range7_dom.value -> " + range7_dom.value);
    console.log("range8_dom.value -> " + range8_dom.value);

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

    // DOM要素 「id="dom_radial_gradient1" 」の offset値 を動的に変更する
    dom_gradient_offset1.setAttribute('offset', range1_dom.value + '%');
    dom_gradient_offset2.setAttribute('offset', range2_dom.value + '%');

	// マスク要素の d の値を動的に変更する
	// dの値は3点をとり、三角形のマスク領域を指定する
    let dom_test_mask_dom1 = document.getElementById('test_mask_dom1');

    // DOM要素 「id="test_mask_dom1" 」の d のパラメータを決定する
    let d_value = 'M ' + range3_dom.value + ', ' + range4_dom.value + ' '
                       + range5_dom.value + ', ' + range6_dom.value + ' '
                       + range7_dom.value + '  ' + range8_dom.value + ' Z';

    // SVG要素の d の値を設定する
    dom_test_mask_dom1.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');
    let range7_value_dom = document.getElementById('range7_value');
    let range8_value_dom = document.getElementById('range8_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;
    range7_value_dom.innerHTML = range7_dom.value;
    range8_value_dom.innerHTML = range8_dom.value;

    // DOM要素 「id="radial_gradient1" 」の offset 値をパラメータを出力する
    // また、マスク要素の d の値も同様に出力する
    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 = d_value;

}

</script>

</body>
</html>

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

画面にアクセスすると、もとの画像に対して、マスク要素内にグラデーション指定した効果がかかっていることがわかります。

グラデーションの濃さ(0~100%)の指定は今回のサンプルでは、常にマスク要素の中心にかかっています。

また、マスク要素の三角形の位置を変化されると、グラデーション効果の位置も併せて変化する(常に中心からグラデーションする)こともわかります。

以下は3パターンの出力例をキャプチャしたものです。

サンプルHTMLの画面から、実際にパラメータを変化させてみるとどのような効果になるのかがわかります。

出力サンプル1

出力サンプル2

出力サンプル3

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です