/**
* @class
* @extends {GradientFilterController}
* @memberOf view.controller
*/
class FilterController extends GradientFilterController
{
/**
* @constructor
* @public
*/
constructor ()
{
super("filter");
/**
* @type {number}
* @default 0
* @private
*/
this._$filterId = 0;
/**
* @type {Map}
* @private
*/
this._$filters = new Map();
}
/**
* @return {number}
* @const
* @static
*/
static get MIN_BLUR ()
{
return 0;
}
/**
* @return {number}
* @const
* @static
*/
static get MAX_BLUR ()
{
return 255;
}
/**
* @return {number}
* @const
* @static
*/
static get MIN_ALPHA ()
{
return 0;
}
/**
* @return {number}
* @const
* @static
*/
static get MAX_ALPHA ()
{
return 100;
}
/**
* @return {number}
* @const
* @static
*/
static get MIN_STRENGTH ()
{
return 0;
}
/**
* @return {number}
* @const
* @static
*/
static get MAX_STRENGTH ()
{
return 255;
}
/**
* @return {number}
* @const
* @static
*/
static get MIN_ROTATE ()
{
return -360;
}
/**
* @return {number}
* @const
* @static
*/
static get MAX_ROTATE ()
{
return 360;
}
/**
* @return {number}
* @const
* @static
*/
static get MIN_DISTANCE ()
{
return -255;
}
/**
* @return {number}
* @const
* @static
*/
static get MAX_DISTANCE ()
{
return 255;
}
/**
* @return {number}
* @const
* @static
*/
static get MIN_COLOR ()
{
return 0;
}
/**
* @return {number}
* @const
* @static
*/
static get MAX_COLOR ()
{
return 0xffffff;
}
/**
* @return {number}
* @const
* @static
*/
static get MIN_QUALITY ()
{
return 0;
}
/**
* @return {number}
* @const
* @static
*/
static get MAX_QUALITY ()
{
return 16;
}
/**
* @description 初期起動関数
*
* @return {void}
* @method
* @public
*/
initialize ()
{
super.initialize();
const element = document.getElementById("filter-add");
if (element) {
element
.addEventListener("mousedown", () =>
{
this.addFilter();
this.disposeCharacterImage();
this.reloadScreen();
});
}
}
/**
* @description 幅高さの変更のロックのOn/Off関数
*
* @param {MouseEvent} event
* @return {void}
* @method
* @public
*/
lock (event)
{
event.stopPropagation();
// ロックのOn/Off
const filterId = event.currentTarget.dataset.filterId | 0;
if (!this._$filters.has(filterId)) {
return ;
}
const object = this._$filters.get(filterId);
object.lock = !object.lock;
// 初期化
this._$currentValue = null;
event
.currentTarget
.childNodes[1]
.setAttribute("class", object.lock
? "active"
: "disable"
);
}
/**
* @description フィルターの表示・非表示の処理
*
* @param {MouseEvent} event
* @return {void}
* @method
* @public
*/
clickNodeTitle (event)
{
const filterId = event.target.dataset.filterId | 0;
const element = document
.getElementById(`filter-view-area-${filterId}`);
if (element.style.display === "none") {
element.style.display = "";
document
.getElementById(`filter-title-arrow-${filterId}`)
.setAttribute("class", "arrow active");
} else {
element.style.display = "none";
document
.getElementById(`filter-title-arrow-${filterId}`)
.setAttribute("class", "arrow disable");
}
}
/**
* @description フィルターの有効・無効の処理
*
* @param {MouseEvent} event
* @return {void}
* @method
* @public
*/
changeState (event)
{
const filterId = event.target.dataset.filterId | 0;
if (!this._$filters.has(filterId)) {
return ;
}
const object = this._$filters.get(filterId);
// 値を更新
object.filter.state = !object.filter.state;
document
.getElementById(`filter-state-${filterId}`)
.setAttribute("class", object.filter.state
? "filter-active"
: "filter-disable"
);
this.disposeCharacterImage();
}
/**
* @description フィルターの削除の処理
*
* @param {MouseEvent} event
* @return {void}
* @method
* @public
*/
removeFilter (event)
{
/**
* @type {ArrowTool}
*/
const tool = Util.$tools.getDefaultTool("arrow");
const activeElements = tool.activeElements;
if (!activeElements.length) {
return ;
}
const filterId = event.target.dataset.filterId | 0;
const target = activeElements[0];
const layer = Util
.$currentWorkSpace()
.scene
.getLayer(
target.dataset.layerId | 0
);
const character = layer.getCharacter(
target.dataset.characterId | 0
);
const frame = Util.$timelineFrame.currentFrame;
let place = character.getPlace(frame);
if (place.tweenFrame) {
if (character.endFrame - 1 > frame && !character.hasTween(frame)) {
Util
.$timelineTool
.executeTimelineKeyAdd();
place = character.getPlace(frame);
}
place = character.getPlace(place.tweenFrame);
}
const object = this._$filters.get(filterId);
const index = place.filter.indexOf(object.filter);
place.filter.splice(index, 1);
// tween情報があれば更新
character.updateTweenFilter(frame);
// remove
this._$filters.delete(filterId);
if (!this._$filters.size) {
document
.querySelectorAll(".filter-none")[0]
.style.display = "";
}
document
.getElementById(`filter-id-${filterId}`)
.remove();
super.focusOut();
// 再描画用にキャッシュを削除
character._$image = null;
}
/**
* @description InputElementにフォーカスした際の処理関数
*
* @param {Event} event
* @return {void}
* @method
* @public
*/
focusIn (event)
{
super.focusIn(event);
this.setLockElement(event);
}
/**
* @description InputElement上でマウスを押下した際の処理関数
*
* @param {MouseEvent} event
* @return {void}
* @method
* @public
*/
mouseDown (event)
{
super.mouseDown(event);
this.setLockElement(event);
}
/**
* @description ロックが有効の際に対象となるElementを変数にセット
*
* @param {Event} event
* @return {void}
* @method
* @public
*/
setLockElement (event)
{
if (this._$focus) {
return ;
}
const filterId = event.target.dataset.filterId | 0;
if (!this._$filters.has(filterId)) {
return ;
}
const object = this._$filters.get(filterId);
if (!object.lock) {
return ;
}
switch (this._$currentTarget.dataset.name) {
case "blurX":
this._$lockTarget = document
.getElementById(`blurY-${filterId}`);
break;
case "blurY":
this._$lockTarget = document
.getElementById(`blurX-${filterId}`);
break;
default:
break;
}
}
/**
* @description blueXの変更値を更新
*
* @param {string} value
* @return {number}
* @method
* @public
*/
changeBlurX (value)
{
value = Util.$clamp(
+value,
FilterController.MIN_BLUR,
FilterController.MAX_BLUR
);
this.updateProperty("blurX", value);
return value;
}
/**
* @description blueYの変更値を更新
*
* @param {string} value
* @return {number}
* @method
* @public
*/
changeBlurY (value)
{
value = Util.$clamp(
+value,
FilterController.MIN_BLUR,
FilterController.MAX_BLUR
);
this.updateProperty("blurY", value);
return value;
}
/**
* @description strengthの変更値を更新
*
* @param {string} value
* @return {number}
* @method
* @public
*/
changeStrength (value)
{
value = Util.$clamp(
+value,
FilterController.MIN_STRENGTH,
FilterController.MAX_STRENGTH
);
this.updateProperty("strength", value);
return value;
}
/**
* @description filterの透明度を更新
*
* @param {string} value
* @return {number}
* @method
* @public
*/
changeAlpha (value)
{
value = Util.$clamp(
+value,
FilterController.MIN_ALPHA,
FilterController.MAX_ALPHA
);
this.updateProperty("alpha", value);
return value;
}
/**
* @description filterのシャドーの透明度を更新
*
* @param {string} value
* @return {number}
* @method
* @public
*/
changeShadowAlpha (value)
{
value = Util.$clamp(
+value,
FilterController.MIN_ALPHA,
FilterController.MAX_ALPHA
);
this.updateProperty("shadowAlpha", value);
return value;
}
/**
* @description filterのハイライトの透明度を更新
*
* @param {string} value
* @return {number}
* @method
* @public
*/
changeHighlightAlpha (value)
{
value = Util.$clamp(
+value,
FilterController.MIN_ALPHA,
FilterController.MAX_ALPHA
);
this.updateProperty("highlightAlpha", value);
return value;
}
/**
* @description filterの回転の値を更新
*
* @param {string} value
* @return {number}
* @method
* @public
*/
changeAngle (value)
{
value = Util.$clamp(
(value | 0) % 360,
FilterController.MIN_ROTATE,
FilterController.MAX_ROTATE
);
if (0 > value) {
value += 360;
}
this.updateProperty("angle", value);
return value;
}
/**
* @description filterのdistanceの値を更新
*
* @param {string} value
* @return {number}
* @method
* @public
*/
changeDistance (value)
{
value = Util.$clamp(
+value,
FilterController.MIN_DISTANCE,
FilterController.MAX_DISTANCE
);
this.updateProperty("distance", value);
return value;
}
/**
* @description filterの指定カラーの値を更新
*
* @param {string} value
* @return {string}
* @method
* @public
*/
changeColor (value)
{
this.updateProperty("color", Util.$clamp(
`0x${value.slice(1)}` | 0,
FilterController.MIN_COLOR,
FilterController.MAX_COLOR
));
return value;
}
/**
* @description filterの指定シャドーカラーの値を更新
*
* @param {string} value
* @return {string}
* @method
* @public
*/
changeShadowColor (value)
{
this.updateProperty("shadowColor", Util.$clamp(
`0x${value.slice(1)}` | 0,
FilterController.MIN_COLOR,
FilterController.MAX_COLOR
));
return value;
}
/**
* @description filterの指定ハイライトカラーの値を更新
*
* @param {string} value
* @return {string}
* @method
* @public
*/
changeHighlightColor (value)
{
this.updateProperty("highlightColor", Util.$clamp(
`0x${value.slice(1)}` | 0,
FilterController.MIN_COLOR,
FilterController.MAX_COLOR
));
return value;
}
/**
* @description filterの指定カラーの値を更新
*
* @param {string} value
* @return {void}
* @method
* @public
*/
changeQuality (value)
{
value = Util.$clamp(
value | 0,
FilterController.MIN_QUALITY,
FilterController.MAX_QUALITY
);
this.updateProperty("quality", value);
}
/**
* @description filterのタイプの値を更新
*
* @param {string} value
* @return {void}
* @method
* @public
*/
changeType (value)
{
switch (value) {
case "inner":
case "outer":
case "full":
this.updateProperty("type", value);
break;
default:
break;
}
}
/**
* @description Knockoutの変更値を更新
*
* @return {void}
* @method
* @public
*/
changeKnockout ()
{
this.updateProperty("knockout", this._$currentTarget.checked);
}
/**
* @description innerの変更値を更新
*
* @return {void}
* @method
* @public
*/
changeInner ()
{
this.updateProperty("inner", this._$currentTarget.checked);
}
/**
* @description hideObjectの変更値を更新
*
* @return {void}
* @method
* @public
*/
changeHideObject ()
{
this.updateProperty("hideObject", this._$currentTarget.checked);
}
/**
* @description filterのプロパティーを更新
*
* @param {string} name
* @param {*} value
* @return {void}
* @method
* @public
*/
updateProperty (name, value)
{
const filterId = this._$currentTarget.dataset.filterId | 0;
if (!this._$filters.has(filterId)) {
return ;
}
const object = this._$filters.get(filterId);
if (object.filter[name] === value) {
return ;
}
object.filter[name] = value;
this.disposeCharacterImage();
}
/**
* @description 更新したDisplayObjectを再描画する為、内部キャッシュを削除する
*
* @return {void}
* @method
* @public
*/
disposeCharacterImage ()
{
/**
* @type {ArrowTool}
*/
const tool = Util.$tools.getDefaultTool("arrow");
const activeElements = tool.activeElements;
if (!activeElements.length) {
return ;
}
const element = activeElements[0];
const layer = Util
.$currentWorkSpace()
.scene
.getLayer(
element.dataset.layerId | 0
);
const character = layer.getCharacter(
element.dataset.characterId | 0
);
// tween情報があれば更新
character.relocationTween(
Util.$timelineFrame.currentFrame
);
// 再描画用にキャッシュを削除
character._$image = null;
}
/**
* @description フィルターの共有イベント処理
* (ロック・表示/非表示・有効/無効・削除)
*
* @param {number} id
* @return {void}
* @method
* @public
*/
setCommonEvent (id)
{
this.setLockEvent(
document.getElementById(`filter-${id}-lock`)
);
this.setTitleEvent(
document.getElementById(`filter-name-${id}`)
);
this.setStateEvent(
document.getElementById(`filter-state-${id}`)
);
this.setTrashEvent(
document.getElementById(`trash-${id}`)
);
}
/**
* @description blurのロックイベントを登録
*
* @param {HTMLDivElement} element
* @return {void}
* @method
* @public
*/
setLockEvent (element)
{
if (!element) {
return ;
}
element.addEventListener("mousedown", (event) =>
{
this.lock(event);
});
}
/**
* @description フィルターの表示・非表示イベント
*
* @param {HTMLDivElement} element
* @return {void}
* @method
* @public
*/
setTitleEvent (element)
{
if (!element) {
return ;
}
element.addEventListener("mousedown", (event) =>
{
this.clickNodeTitle(event);
});
}
/**
* @description フィルターの有効・無効イベント
*
* @param {HTMLDivElement} element
* @return {void}
* @method
* @public
*/
setStateEvent (element)
{
if (!element) {
return ;
}
const filterId = element.dataset.filterId | 0;
if (this._$filters.has(filterId)) {
const object = this._$filters.get(filterId);
element
.setAttribute("class", object.filter.state
? "filter-active"
: "filter-disable"
);
}
element.addEventListener("mousedown", (event) =>
{
this.save();
this.changeState(event);
this.reloadScreen();
this._$saved = false;
});
}
/**
* @description フィルターの削除イベント
*
* @param {HTMLDivElement} element
* @return {void}
* @method
* @public
*/
setTrashEvent (element)
{
if (!element) {
return ;
}
element.addEventListener("click", (event) =>
{
this.removeFilter(event);
this.reloadScreen();
});
}
/**
* @description フィルターの追加処理関数
*
* @return {void}
* @method
* @public
*/
addFilter ()
{
document
.querySelectorAll(".filter-none")[0]
.style.display = "none";
const select = document.getElementById("filter-select");
this[`add${select.value}`](
document.getElementById("filter-setting-list")
);
}
/**
* @description フィルター表示を初期化
*
* @return {void}
* @methodq
* @public
*/
clearFilters ()
{
this._$filterId = 0;
this._$filters.clear();
const element = document
.getElementById("filter-setting-list");
if (!element) {
return ;
}
// テキストのElementは消えてもいいようにここで変数に格納しておく
const textElement = document
.querySelectorAll(".filter-none")[0];
while (element.children.length) {
element.children[0].remove();
}
// 表示してDOMに追加
textElement.style.display = "";
element.appendChild(textElement);
}
/**
* @param {function} filterClass
* @param {DropShadowFilter|BlurFilter|GlowFilter|BevelFilter|GradientGlowFilter|GradientBevelFilter} [filter=null]
* @return {number}
*/
createFilter (filterClass, filter = null)
{
const id = this._$filterId++;
if (!filter) {
filter = new filterClass();
/**
* @type {ArrowTool}
*/
const tool = Util.$tools.getDefaultTool("arrow");
const activeElements = tool.activeElements;
if (!activeElements.length) {
return ;
}
const target = activeElements[0];
const scene = Util.$currentWorkSpace().scene;
const layer = scene.getLayer(
target.dataset.layerId | 0
);
const character = layer.getCharacter(
target.dataset.characterId | 0
);
const frame = Util.$timelineFrame.currentFrame;
let place = character.getPlace(frame);
if (place.tweenFrame) {
if (character.endFrame - 1 > frame && !character.hasTween(frame)) {
Util
.$timelineTool
.executeTimelineKeyAdd();
place = character.getPlace(frame);
}
place = character.getPlace(place.tweenFrame);
}
place.filter.push(filter);
// tweenの情報を更新
character.updateTweenFilter(frame);
}
// 複数のフィルターを管理するので、Mapで状態管理を行う
this._$filters.set(id, {
"id": id,
"lock": false,
"filter": filter,
"context": null
});
return id;
}
/**
* @description フィルター表示で共有化しているマークアップを返す
*
* @param {number} id
* @param {string} name
* @return {string}
* @method
* @public
*/
getFilterHeaderHTML (id, name)
{
return `
<div id="filter-id-${id}" class="filter-border">
<div class="filter-title">
<i id="filter-title-arrow-${id}" class="arrow active"></i>
<span id="filter-name-${id}" data-filter-id="${id}">${name}</span>
<i class="filter-active" id="filter-state-${id}" data-filter-id="${id}" data-detail="{{フィルターを表示・非表示する}}"></i>
<i class="trash" id="trash-${id}" data-filter-id="${id}" data-detail="{{フィルターを削除}}"></i>
</div>
<div id="filter-view-area-${id}" class="filter-view-area">
<div class="filter-view-area-left">
<div id="filter-${id}-lock" data-filter-id="${id}" class="filter-lock">
┌
<div class="disable" data-detail="{{比率を固定}}"></div>
└
</div>
</div>
`;
}
/**
* @description DropShadowFilterを追加
*
* @param {HTMLDivElement} element
* @param {DropShadowFilter} [filter=null]
* @param {boolean} [reload=true]
* @return {void}
* @method
* @public
*/
addDropShadowFilter (element, filter = null, reload = true)
{
const id = this.createFilter(DropShadowFilter, filter);
if (!filter) {
filter = this._$filters.get(id).filter;
}
const htmlTag = this.getFilterHeaderHTML(id, "DropShadow") + `
<div class="filter-view-area-right">
<div class="filter-container">
<div class="filter-text">BlurX</div>
<div><input type="text" id="blurX-${id}" value="${filter.blurX}" data-name="blurX" data-filter-id="${id}" data-detail="{{水平方向にぼかす}}"></div>
<div class="filter-text">Strength</div>
<div><input type="text" id="strength-${id}" value="${filter.strength}" data-filter-id="${id}" data-name="strength" data-detail="{{フィルター強度}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">BlurY</div>
<div><input type="text" id="blurY-${id}" value="${filter.blurY}" data-name="blurY" data-filter-id="${id}" data-detail="{{垂直方向にぼかす}}"></div>
<div class="filter-text">Angle</div>
<div><input type="text" id="angle-${id}" value="${filter.angle}" data-filter-id="${id}" data-name="angle" data-detail="{{フィルター角度}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">Distance</div>
<div><input type="text" id="distance-${id}" value="${filter.distance}" data-filter-id="${id}" data-name="distance" data-detail="{{フィルター距離}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">Shadow</div>
<div><input type="color" id="color-${id}" value="#${filter.color.toString(16).padStart(6, "0")}" data-filter-id="${id}" data-name="color" data-detail="{{シャドウのカラー}}"></div>
<div class="filter-text">Alpha</div>
<div><input type="text" id="alpha-${id}" value="${filter.alpha}" data-filter-id="${id}" data-name="alpha" data-detail="{{シャドウのアルファ}}"></div>
</div>
<div class="filter-container">
<div><input type="checkbox" id="knockout-${id}" data-name="knockout" data-filter-id="${id}"></div>
<div class="filter-text-long">
<label for="knockout-${id}">Knockout</label>
</div>
</div>
<div class="filter-container">
<div><input type="checkbox" id="inner-${id}" data-name="inner" data-filter-id="${id}"></div>
<div class="filter-text-long">
<label for="inner-${id}">Inner Shadow</label>
</div>
</div>
<div class="filter-container">
<div><input type="checkbox" id="hideObject-${id}" data-name="hideObject" data-filter-id="${id}"></div>
<div class="filter-text-long">
<label for="hideObject-${id}">Hide Object</label>
</div>
</div>
<div class="filter-container">
<div class="filter-text-long">Quality</div>
<div>
<select id="quality-${id}" data-name="quality" data-filter-id="${id}">
<option value="1">Low</option>
<option value="2">Middle</option>
<option value="3">High</option>
</select>
</div>
</div>
</div>
</div>
</div>
`;
// added element
element.insertAdjacentHTML("beforeend", htmlTag);
// 共有イベント処理
this.setCommonEvent(id);
// 保存データの場合はcheckboxの値を更新
if (filter.knockout) {
document
.getElementById(`knockout-${id}`)
.checked = true;
}
if (filter.inner) {
document
.getElementById(`inner-${id}`)
.checked = true;
}
if (filter.hideObject) {
document
.getElementById(`hideObject-${id}`)
.checked = true;
}
const inputIds = [
`blurX-${id}`,
`blurY-${id}`,
`strength-${id}`,
`angle-${id}`,
`alpha-${id}`,
`distance-${id}`
];
for (let idx = 0; idx < inputIds.length; ++idx) {
this.setInputEvent(
document.getElementById(inputIds[idx])
);
}
const clickIds = [
`knockout-${id}`,
`inner-${id}`,
`hideObject-${id}`
];
for (let idx = 0; idx < clickIds.length; ++idx) {
this.setClickEvent(
document.getElementById(clickIds[idx])
);
}
const changeIds = [
`color-${id}`,
`quality-${id}`
];
for (let idx = 0; idx < changeIds.length; ++idx) {
this.setChangeEvent(
document.getElementById(changeIds[idx])
);
}
// 内部キャッシュを削除
if (reload) {
this.disposeCharacterImage();
}
Util.$addModalEvent(
document.getElementById(`filter-id-${id}`)
);
}
/**
* @param {HTMLDivElement} element
* @param {BlurFilter} [filter=null]
* @param {boolean} [reload=true]
* @return {void}
* @method
* @public
*/
addBlurFilter (element, filter = null, reload = true)
{
const id = this.createFilter(BlurFilter, filter);
if (!filter) {
filter = this._$filters.get(id).filter;
}
const htmlTag = this.getFilterHeaderHTML(id, "Blur") + `
<div class="filter-view-area-right">
<div class="filter-container">
<div class="filter-text">BlurX</div>
<div><input type="text" id="blurX-${id}" value="${filter.blurX}" data-name="blurX" data-filter-id="${id}" data-detail="{{水平方向にぼかす}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">BlurY</div>
<div><input type="text" id="blurY-${id}" value="${filter.blurY}" data-name="blurY" data-filter-id="${id}" data-detail="{{垂直方向にぼかす}}"></div>
</div>
<div class="filter-container">
<div class="filter-text-long">Quality</div>
<div>
<select id="quality-${id}" data-name="quality" data-filter-id="${id}">
<option value="1">Low</option>
<option value="2">Middle</option>
<option value="3">High</option>
</select>
</div>
</div>
</div>
</div>
</div>
`;
// added element
element.insertAdjacentHTML("beforeend", htmlTag);
// 共有イベント処理
this.setCommonEvent(id);
const inputIds = [
`blurX-${id}`,
`blurY-${id}`
];
for (let idx = 0; idx < inputIds.length; ++idx) {
this.setInputEvent(
document.getElementById(inputIds[idx])
);
}
const changeIds = [
`quality-${id}`
];
for (let idx = 0; idx < changeIds.length; ++idx) {
this.setChangeEvent(
document.getElementById(changeIds[idx])
);
}
// 内部キャッシュを削除
if (reload) {
this.disposeCharacterImage();
}
Util.$addModalEvent(
document.getElementById(`filter-id-${id}`)
);
}
/**
* @param {HTMLDivElement} element
* @param {GlowFilter} [filter=null]
* @param {boolean} [reload=true]
* @return {void}
* @method
* @public
*/
addGlowFilter (element, filter = null, reload = true)
{
const id = this.createFilter(GlowFilter, filter);
if (!filter) {
filter = this._$filters.get(id).filter;
}
const htmlTag = this.getFilterHeaderHTML(id, "Glow") + `
<div class="filter-view-area-right">
<div class="filter-container">
<div class="filter-text">BlurX</div>
<div><input type="text" id="blurX-${id}" value="${filter.blurX}" data-name="blurX" data-filter-id="${id}" data-detail="{{水平方向にぼかす}}"></div>
<div class="filter-text">Strength</div>
<div><input type="text" id="strength-${id}" value="${filter.strength}" data-filter-id="${id}" data-name="strength" data-detail="{{フィルター強度}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">BlurY</div>
<div><input type="text" id="blurY-${id}" value="${filter.blurY}" data-name="blurY" data-filter-id="${id}" data-detail="{{垂直方向にぼかす}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">Color</div>
<div><input type="color" id="color-${id}" value="#${filter.color.toString(16).padStart(6, "0")}" data-filter-id="${id}" data-name="color" data-detail="{{シャドウのカラー}}"></div>
<div class="filter-text">Alpha</div>
<div><input type="text" id="alpha-${id}" value="${filter.alpha}" data-filter-id="${id}" data-name="alpha" data-detail="{{シャドウのアルファ}}"></div>
</div>
<div class="filter-container">
<div><input type="checkbox" id="inner-${id}" data-name="inner" data-filter-id="${id}"></div>
<div class="filter-text-long">
<label for="inner-${id}">Inner Glow</label>
</div>
</div>
<div class="filter-container">
<div><input type="checkbox" id="knockout-${id}" data-name="knockout" data-filter-id="${id}"></div>
<div class="filter-text-long">
<label for="knockout-${id}">Knockout</label>
</div>
</div>
<div class="filter-container">
<div class="filter-text-long">Quality</div>
<div>
<select id="quality-${id}" data-name="quality" data-filter-id="${id}">
<option value="1">Low</option>
<option value="2">Middle</option>
<option value="3">High</option>
</select>
</div>
</div>
</div>
</div>
</div>
`;
// added element
element.insertAdjacentHTML("beforeend", htmlTag);
// 共有イベント処理
this.setCommonEvent(id);
// 保存データの場合はcheckboxの値を更新
if (filter.knockout) {
document
.getElementById(`knockout-${id}`)
.checked = true;
}
if (filter.inner) {
document
.getElementById(`inner-${id}`)
.checked = true;
}
const inputIds = [
`blurX-${id}`,
`blurY-${id}`,
`strength-${id}`,
`alpha-${id}`,
`distance-${id}`
];
for (let idx = 0; idx < inputIds.length; ++idx) {
this.setInputEvent(
document.getElementById(inputIds[idx])
);
}
const clickIds = [
`knockout-${id}`,
`inner-${id}`
];
for (let idx = 0; idx < clickIds.length; ++idx) {
this.setClickEvent(
document.getElementById(clickIds[idx])
);
}
const changeIds = [
`color-${id}`,
`quality-${id}`
];
for (let idx = 0; idx < changeIds.length; ++idx) {
this.setChangeEvent(
document.getElementById(changeIds[idx])
);
}
// 内部キャッシュを削除
if (reload) {
this.disposeCharacterImage();
}
Util.$addModalEvent(
document.getElementById(`filter-id-${id}`)
);
}
/**
* @param {HTMLDivElement} element
* @param {BevelFilter} [filter=null]
* @param {boolean} [reload=true]
* @return {void}
* @method
* @public
*/
addBevelFilter (element, filter = null, reload = true)
{
const id = this.createFilter(BevelFilter, filter);
if (!filter) {
filter = this._$filters.get(id).filter;
}
const htmlTag = this.getFilterHeaderHTML(id, "Bevel") + `
<div class="filter-view-area-right">
<div class="filter-container">
<div class="filter-text">BlurX</div>
<div><input type="text" id="blurX-${id}" value="${filter.blurX}" data-name="blurX" data-filter-id="${id}" data-detail="{{水平方向にぼかす}}"></div>
<div class="filter-text">Strength</div>
<div><input type="text" id="strength-${id}" value="${filter.strength}" data-filter-id="${id}" data-name="strength" data-detail="{{フィルター強度}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">BlurY</div>
<div><input type="text" id="blurY-${id}" value="${filter.blurY}" data-name="blurY" data-filter-id="${id}" data-detail="{{垂直方向にぼかす}}"></div>
<div class="filter-text">Angle</div>
<div><input type="text" id="angle-${id}" value="${filter.angle}" data-filter-id="${id}" data-name="angle" data-detail="{{フィルター角度}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">Distance</div>
<div><input type="text" id="distance-${id}" value="${filter.distance}" data-filter-id="${id}" data-name="distance" data-detail="{{フィルター距離}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">Shadow<br>Color</div>
<div><input type="color" id="shadowColor-${id}" value="#${filter.shadowColor.toString(16).padStart(6, "0")}" data-filter-id="${id}" data-name="shadowColor" data-detail="{{シャドウのカラー}}"></div>
<div class="filter-text">Shadow<br>Alpha</div>
<div><input type="text" id="shadowAlpha-${id}" value="${filter.shadowAlpha}" data-filter-id="${id}" data-name="shadowAlpha" data-detail="{{シャドウのアルファ}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">Highlight<br>Color</div>
<div><input type="color" id="highlightColor-${id}" value="#${filter.highlightColor.toString(16).padStart(6, "0")}" data-filter-id="${id}" data-name="highlightColor" data-detail="{{ハイライトのカラー}}"></div>
<div class="filter-text">Highlight<br>Alpha</div>
<div><input type="text" id="highlightAlpha-${id}" value="${filter.highlightAlpha}" data-filter-id="${id}" data-name="highlightAlpha" data-detail="{{ハイライトのアルファ}}"></div>
</div>
<div class="filter-container">
<div><input type="checkbox" id="knockout-${id}" data-name="knockout" data-filter-id="${id}"></div>
<div class="filter-text-long">
<label for="knockout-${id}">Knockout</label>
</div>
</div>
<div class="filter-container">
<div class="filter-text-long">Type</div>
<div>
<select id="type-${id}" data-name="type" data-filter-id="${id}">
<option value="inner">Inner</option>
<option value="outer">Outer</option>
<option value="full">Full</option>
</select>
</div>
<div class="filter-text-long">Quality</div>
<div>
<select id="quality-${id}" data-name="quality" data-filter-id="${id}">
<option value="1">Low</option>
<option value="2">Middle</option>
<option value="3">High</option>
</select>
</div>
</div>
</div>
</div>
</div>
`;
// added element
element.insertAdjacentHTML("beforeend", htmlTag);
// 共有イベント処理
this.setCommonEvent(id);
// 保存データの場合はcheckboxの値を更新
if (filter.knockout) {
document
.getElementById(`knockout-${id}`)
.checked = true;
}
const inputIds = [
`blurX-${id}`,
`blurY-${id}`,
`strength-${id}`,
`angle-${id}`,
`shadowAlpha-${id}`,
`highlightAlpha-${id}`,
`distance-${id}`
];
for (let idx = 0; idx < inputIds.length; ++idx) {
this.setInputEvent(
document.getElementById(inputIds[idx])
);
}
const clickIds = [
`knockout-${id}`
];
for (let idx = 0; idx < clickIds.length; ++idx) {
this.setClickEvent(
document.getElementById(clickIds[idx])
);
}
const changeIds = [
`shadowColor-${id}`,
`highlightColor-${id}`,
`type-${id}`,
`quality-${id}`
];
for (let idx = 0; idx < changeIds.length; ++idx) {
this.setChangeEvent(
document.getElementById(changeIds[idx])
);
}
// 内部キャッシュを削除
if (reload) {
this.disposeCharacterImage();
}
Util.$addModalEvent(
document.getElementById(`filter-id-${id}`)
);
}
/**
* @param {HTMLDivElement} element
* @param {GradientGlowFilter} [filter=null]
* @param {boolean} [reload=true]
* @return {void}
* @method
* @public
*/
addGradientGlowFilter (element, filter = null, reload = true)
{
const id = this.createFilter(GradientGlowFilter, filter);
if (!filter) {
filter = this._$filters.get(id).filter;
}
const htmlTag = this.getFilterHeaderHTML(id, "GradientGlow") + `
<div class="filter-view-area-right">
<div class="filter-container">
<div class="filter-text">BlurX</div>
<div><input type="text" id="blurX-${id}" value="${filter.blurX}" data-name="blurX" data-filter-id="${id}" data-detail="{{水平方向にぼかす}}"></div>
<div class="filter-text">Strength</div>
<div><input type="text" id="strength-${id}" value="${filter.strength}" data-filter-id="${id}" data-name="strength" data-detail="{{フィルター強度}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">BlurY</div>
<div><input type="text" id="blurY-${id}" value="${filter.blurY}" data-name="blurY" data-filter-id="${id}" data-detail="{{垂直方向にぼかす}}"></div>
<div class="filter-text">Angle</div>
<div><input type="text" id="angle-${id}" value="${filter.angle}" data-filter-id="${id}" data-name="angle" data-detail="{{フィルター角度}}"></div>
</div>
<div class="filter-container">
<div class="filter-text">Distance</div>
<div><input type="text" id="distance-${id}" value="${filter.distance}" data-filter-id="${id}" data-name="distance" data-detail="{{フィルター距離}}"></div>
</div>
<div class="filter-container">
<div id="gradient-color-palette-${id}" class="gradient-color-palette">
<div id="color-palette-${id}" class="color-palette">
<canvas id="gradient-canvas-${id}"></canvas>
</div>
<div id="color-pointer-list-${id}" data-filter-id="${id}" class="color-pointer-list" data-detail="{{カラーポインターを追加}}"></div>
</div>
</div>
<div class="filter-container">
<div class="filter-text">Color</div>
<div><input type="color" id="gradientColor-${id}" value="#000000" data-detail="{{グラデーションカラー}}"></div>
<div class="filter-text">Alpha</div>
<div><input type="text" id="gradientAlpha-${id}" value="100" data-detail="{{グラデーションのアルファ}}"></div>
</div>
<div class="filter-container">
<div><input type="checkbox" id="knockout-${id}" data-name="knockout" data-filter-id="${id}"></div>
<div class="filter-text-long">
<label for="knockout-${id}">Knockout</label>
</div>
</div>
<div class="filter-container">
<div class="filter-text-long">Type</div>
<div>
<select id="type-${id}" data-name="type" data-filter-id="${id}">
<option value="inner">Inner</option>
<option value="outer">Outer</option>
<option value="full">Full</option>
</select>
</div>
<div class="filter-text-long">Quality</div>
<div>
<select id="quality-${id}" data-name="quality" data-filter-id="${id}">
<option value="1">Low</option>
<option value="2">Middle</option>
<option value="3">High</option>
</select>
</div>
</div>
</div>
</div>
</div>
`;
// added element
element.insertAdjacentHTML("beforeend", htmlTag);
// グラデーションコントロール用のcanvas
const canvas = document.getElementById(`gradient-canvas-${id}`);
canvas.width = FilterController.GRADIENT_CANVAS_WIDTH * window.devicePixelRatio;
canvas.height = FilterController.GRADIENT_CANVAS_HEIGHT * window.devicePixelRatio;
canvas.style.transform = `scale(${1 / window.devicePixelRatio}, ${1 / window.devicePixelRatio})`;
canvas.style.backfaceVisibility = "hidden";
canvas.style.transformOrigin = "0 0";
filter.context = canvas.getContext("2d");
// 共有イベント処理
this.setCommonEvent(id);
// 保存データの場合はcheckboxの値を更新
if (filter.knockout) {
document
.getElementById(`knockout-${id}`)
.checked = true;
}
const inputIds = [
`blurX-${id}`,
`blurY-${id}`,
`strength-${id}`,
`angle-${id}`,
`gradientAlpha-${id}`,
`distance-${id}`
];
for (let idx = 0; idx < inputIds.length; ++idx) {
this.setInputEvent(
document.getElementById(inputIds[idx])
);
}
const clickIds = [
`knockout-${id}`
];
for (let idx = 0; idx < clickIds.length; ++idx) {
this.setClickEvent(
document.getElementById(clickIds[idx])
);
}
const changeIds = [
`gradientColor-${id}`,
`type-${id}`,
`quality-${id}`
];
for (let idx = 0; idx < changeIds.length; ++idx) {
this.setChangeEvent(
document.getElementById(changeIds[idx])
);
}
// ポインターを追加
for (let idx = 0; idx < filter.ratios.length; ++idx) {
const ratio = filter.ratios[idx];
const color = `#${filter.colors[idx].toString(16).padStart(6, "0")}`;
const alpha = filter.alphas[idx];
this.addFilterGradientColorPointer(id, idx, ratio, color, alpha);
}
// ポインター追加イベント
this.setCreateGradientColorPointerEvent(id);
// canvasを更新
this.updateFilterGradientCanvas(filter);
// 内部キャッシュを削除
if (reload) {
this.disposeCharacterImage();
}
Util.$addModalEvent(
document.getElementById(`filter-id-${id}`)
);
}
}
Util.$filterController = new FilterController();
Source: view/controller/FilterController.js