Skip to content

Commit

Permalink
#147 feat: マスク移動を実装(WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
ienaga committed Jul 20, 2024
1 parent 968f7f4 commit 4d3e1bb
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { execute as characterCalcGetScaleXService } from "@/core/application/Cha
import { execute as characterCalcGetScaleYService } from "@/core/application/Character/service/CharacterCalcGetScaleYService";
import { execute as characterCalcGetRotationService } from "@/core/application/Character/service/CharacterCalcGetRotationService";
import { $getCurrentWorkSpace } from "@/core/application/CoreUtil";
import { $BITMAP_TYPE, $MOVIE_CLIP_TYPE, $SHAPE_TYPE } from "@/config/InstanceConfig";

/**
* @description 行列の掛け算
Expand Down Expand Up @@ -155,4 +156,62 @@ export const $createTransformBitmapStyle = (
transform.unshift(`translate(${-multiMatrix[4]}px, ${-multiMatrix[5]}px)`);

return `transform: ${transform.join(" ")}; `;
};

/**
* @description Bitmapのマスク用の行列を返却
* Returns the matrix for the mask of the Bitmap
*
* @param {Character} character
* @return {array}
* @method
* @public
*/
export const $getBitmapMaskMatrix = (character: Character): number[] =>
{

const matrix = [1, 0, 0, 1, 0, 0];
const concatenatedMatrix = $getConcatenatedMatrix();
const multiMatrix = $multiplicationMatrix(concatenatedMatrix, character.matrix);

matrix[0] = characterCalcGetScaleXService(multiMatrix);
matrix[3] = characterCalcGetScaleYService(multiMatrix);

// 変形分の座標を補正
matrix[4] = concatenatedMatrix[4];
matrix[5] = concatenatedMatrix[5];

return matrix;
};

export const $getMaskMatrix = (character: Character): number[] =>
{
const matrix = [1, 0, 0, 1, 0, 0];
const workSpace = $getCurrentWorkSpace();
const instance = workSpace.getLibrary(character.libraryId);
if (!instance) {
return matrix;
}

switch (instance.type) {

case $BITMAP_TYPE:
return $getBitmapMaskMatrix(character);

case $MOVIE_CLIP_TYPE:
{
const bounds = instance.getRawBounds(instance.currentFrame);
return [1, 0, 0, 1, bounds.xMin * workSpace.scale, bounds.yMin * workSpace.scale];
}

case $SHAPE_TYPE:
{
const concatMatrix = $getConcatenatedMatrix();
return [1, 0, 0, 1, concatMatrix[4], concatMatrix[5]];
}

default:
return matrix;

}
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { execute as screenAreaHierarchyAdjustmentService } from "@/screen/applic
import { $getDeactivated, $getReDrawState } from "@/screen/application/ScreenArea/ScreenAreaUtil";
import { execute as screenAreaReadOnlyElementService } from "@/screen/application/ScreenArea/service/ScreenAreaReadOnlyElementService";
import { execute as screenDisplayObjectUpdateMaskInCanvasStyleService } from "@/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService";
import { $MASK_IN_MODE } from "@/config/LayerModeConfig";
import { $getMaskMatrix } from "@/controller/application/TransformSetting/TransformSettingUtil";

/**
* @description Bitmapをcanvasに描画して返却する
Expand Down Expand Up @@ -58,7 +60,12 @@ export const execute = async (
div.appendChild(canvas);

// マスクのスタイルを更新
await screenDisplayObjectUpdateMaskInCanvasStyleService(div, layer, character.x, character.y);
if (layer.mode === $MASK_IN_MODE) {
await screenDisplayObjectUpdateMaskInCanvasStyleService(
div, layer, character.x, character.y,
$getMaskMatrix(character)
);
}

// 追加するDisplayObjectのレイヤーの階層を調整
if (!$getReDrawState()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { execute as screenAreaHierarchyAdjustmentService } from "@/screen/applic
import { $getDeactivated, $getReDrawState } from "@/screen/application/ScreenArea/ScreenAreaUtil";
import { execute as screenAreaReadOnlyElementService } from "@/screen/application/ScreenArea/service/ScreenAreaReadOnlyElementService";
import { execute as screenDisplayObjectUpdateMaskInCanvasStyleService } from "@/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService";
import { $MASK_IN_MODE } from "@/config/LayerModeConfig";
import { $getMaskMatrix } from "@/controller/application/TransformSetting/TransformSettingUtil";

/**
* @description MovieClipをcanvasに描画して返却する
Expand Down Expand Up @@ -55,7 +57,12 @@ export const execute = async (
div.appendChild(canvas);

// マスクのスタイルを更新
await screenDisplayObjectUpdateMaskInCanvasStyleService(div, layer, character.x, character.y);
if (layer.mode === $MASK_IN_MODE) {
await screenDisplayObjectUpdateMaskInCanvasStyleService(
div, layer, character.x, character.y,
$getMaskMatrix(character)
);
}

// 追加するDisplayObjectのレイヤーの階層を調整
if (!$getReDrawState()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { execute as screenAreaReadOnlyElementService } from "@/screen/applicatio
import { execute as instanceUpdateBlendModeService } from "@/core/application/Instance/service/InstanceUpdateBlendModeService";
import { $getDeactivated, $getReDrawState } from "@/screen/application/ScreenArea/ScreenAreaUtil";
import { execute as screenDisplayObjectUpdateMaskInCanvasStyleService } from "@/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService";
import { $MASK_IN_MODE } from "@/config/LayerModeConfig";
import { $getMaskMatrix } from "@/controller/application/TransformSetting/TransformSettingUtil";

/**
* @description Shapeをcanvasに描画して返却する
Expand Down Expand Up @@ -55,7 +57,12 @@ export const execute = async (
div.appendChild(canvas);

// マスクのスタイルを更新
await screenDisplayObjectUpdateMaskInCanvasStyleService(div, layer, character.x, character.y);
if (layer.mode === $MASK_IN_MODE) {
await screenDisplayObjectUpdateMaskInCanvasStyleService(
div, layer, character.x, character.y,
$getMaskMatrix(character)
);
}

// 追加するDisplayObjectのレイヤーの階層を調整
if (!$getReDrawState()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { execute as screenStandardPointDeployElementUseCase } from "@/screen/app
import { execute as screenDisplayObjectUpdateMaskInCanvasStyleService } from "@/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService";
import { $MASK_IN_MODE } from "@/config/LayerModeConfig";
import { $SCREEN_STAGE_AREA_ID } from "@/config/ScreenConfig";
import { $getMaskMatrix } from "@/controller/application/TransformSetting/TransformSettingUtil";

/**
* @description DisplayObjectのx座標を更新
Expand Down Expand Up @@ -85,7 +86,7 @@ export const execute = async (
}

await screenDisplayObjectUpdateMaskInCanvasStyleService(
node, layer, x, character.y
node, layer, x, character.y, $getMaskMatrix(character)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { execute as screenStandardPointDeployElementUseCase } from "@/screen/app
import { execute as screenDisplayObjectUpdateMaskInCanvasStyleService } from "@/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService";
import { $MASK_IN_MODE } from "@/config/LayerModeConfig";
import { $SCREEN_STAGE_AREA_ID } from "@/config/ScreenConfig";
import { $getMaskMatrix } from "@/controller/application/TransformSetting/TransformSettingUtil";

/**
* @description DisplayObjectのx座標を更新
Expand Down Expand Up @@ -85,7 +86,7 @@ export const execute = async (
}

await screenDisplayObjectUpdateMaskInCanvasStyleService(
node, layer, character.x, y
node, layer, character.x, y, $getMaskMatrix(character)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { $getCacheCanvas, $setCacheCanvas } from "@/cache/CacheUtil";
import { $getConcatenatedMatrix } from "@/controller/application/TransformSetting/TransformSettingUtil";
import { $MASK_IN_MODE } from "@/config/LayerModeConfig";
import { $getCurrentWorkSpace } from "@/core/application/CoreUtil";
import type { Layer } from "@/core/domain/model/Layer";

Expand All @@ -11,6 +11,7 @@ import type { Layer } from "@/core/domain/model/Layer";
* @param {Layer} layer
* @param {number} x
* @param {number} y
* @param {array} [matrix=[]]
* @return {Promise}
* @method
* @public
Expand All @@ -19,10 +20,11 @@ export const execute = async (
element: HTMLElement,
layer: Layer,
x: number,
y: number
y: number,
matrix: number[] = [1, 0, 0, 1, 0, 0]
): Promise<void> => {

if (layer.parentId === -1) {
if (layer.mode !== $MASK_IN_MODE) {
return ;
}

Expand All @@ -44,48 +46,40 @@ export const execute = async (
return ;
}

const instance = workSpace.getLibrary(maskCharacter.libraryId);
if (!instance) {
const maskInstance = workSpace.getLibrary(maskCharacter.libraryId);
if (!maskInstance) {
return ;
}

const cacheKey = maskCharacter.cacheKey;

let canvas = $getCacheCanvas(workSpace.id, instance.id, cacheKey);
let canvas = $getCacheCanvas(workSpace.id, maskInstance.id, cacheKey);
if (!canvas) {
canvas = await instance.getHTMLElement();
canvas = await maskInstance.getHTMLElement();
if (!canvas) {
return ;
}

// キャッシュに保存
$setCacheCanvas(workSpace.id, instance.id, cacheKey, canvas);
$setCacheCanvas(workSpace.id, maskInstance.id, cacheKey, canvas);
}

if (!canvas.dataset.base64) {
canvas.dataset.base64 = canvas.toDataURL();
}

const base64 = canvas.dataset.base64;
const scale = window.devicePixelRatio;
const width = canvas.width / scale;
const height = canvas.height / scale;
const dx = maskCharacter.x - x;
const dy = maskCharacter.y - y;
// 拡大・縮小に合わせてマスク位置を計算
const devicePixelRatio = window.devicePixelRatio;
const scale = workSpace.scale;

const concatenatedMatrix = $getConcatenatedMatrix();
const matrix = new next2d.geom.Matrix(
concatenatedMatrix[0], concatenatedMatrix[1], concatenatedMatrix[2],
concatenatedMatrix[3], concatenatedMatrix[4], concatenatedMatrix[5]
);
matrix.invert();

const localX = dx * matrix.a + dy * matrix.c + matrix.tx;
const localY = dx * matrix.b + dy * matrix.d + matrix.ty;
const width = canvas.width / devicePixelRatio / matrix[0];
const height = canvas.height / devicePixelRatio / matrix[3];
const dx = (maskCharacter.x - x) * scale / matrix[0];
const dy = (maskCharacter.y - y) * scale / matrix[3];

const style = element.style;
style.mask = style.webkitMask = `url(${base64}), none`;
style.mask = style.webkitMask = `url(${canvas.dataset.base64}), none`;
style.maskSize = style.webkitMaskSize = `${width}px ${height}px`;
style.maskRepeat = style.webkitMaskRepeat = "no-repeat";
style.maskPosition = style.webkitMaskPosition = `${localX}px ${localY}px`;
style.maskPosition = style.webkitMaskPosition = `${-matrix[4] + dx}px ${-matrix[5] + dy}px`;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { $getCurrentWorkSpace } from "@/core/application/CoreUtil";
import { $SCREEN_STAGE_AREA_ID } from "@/config/ScreenConfig";
import { execute as screenDisplayObjectUpdateMaskInCanvasStyleService } from "@/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService";
import { transformSetting } from "@/controller/domain/model/TransformSetting";
import { $getMaskMatrix } from "@/controller/application/TransformSetting/TransformSettingUtil";

/**
* @description スクリーンで選択中のElementを移動する
Expand Down Expand Up @@ -35,6 +36,8 @@ export const execute = async (

// 選択中のElementを移動
const frame = movieClip.currentFrame;
const dx = transformSetting.x / workSpace.scale;
const dy = transformSetting.y / workSpace.scale;
for (const [layerIndex, depths] of movieClip.selectedDepths) {

const layer = movieClip.getLayer(layerIndex);
Expand Down Expand Up @@ -73,8 +76,9 @@ export const execute = async (
// マスクのstyleを更新
await screenDisplayObjectUpdateMaskInCanvasStyleService(
node, layer,
character.x + transformSetting.x,
character.y + transformSetting.y
character.x + dx,
character.y + dy,
$getMaskMatrix(character)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Layer } from "@/core/domain/model/Layer";
import type { MovieClip } from "@/core/domain/model/MovieClip";
import { execute as screenDisplayObjectAllResetMaskStyleUseCase } from "@/screen/application/DisplayObject/usecase/ScreenDisplayObjectAllResetMaskStyleUseCase";
import { execute as screenDisplayObjectUpdateMaskInCanvasStyleService } from "@/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService";
import { $getMaskMatrix } from "@/controller/application/TransformSetting/TransformSettingUtil";

/**
* @description レイヤーに配置された全てのDisplayObjectのマスクスタイルをレイヤーの状態に合わせて更新
Expand Down Expand Up @@ -66,7 +67,8 @@ export const execute = async (movie_clip: MovieClip, layer: Layer): Promise<void
element,
layer,
character.x,
character.y
character.y,
$getMaskMatrix(character)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { $MASK_MODE } from "@/config/LayerModeConfig";
import { $getActiveTool } from "@/tool/application/ToolUtil";
import { timelineHeader } from "@/timeline/domain/model/TimelineHeader";
import { EventType } from "@/tool/domain/event/EventType";
import { $getCurrentWorkSpace } from "@/core/application/CoreUtil";
import { $getCacheCanvas } from "@/cache/CacheUtil";
import { $setReDrawState } from "../ScreenAreaUtil";

/**
Expand Down Expand Up @@ -34,11 +32,6 @@ export const execute = async (movie_clip: MovieClip): Promise<void> =>
// 再描画状態を設定
$setReDrawState(true);

const workSpace = $getCurrentWorkSpace();
const movieClip = workSpace.scene;

let maskStyle = "";
let masked = false;
const frame = movie_clip.currentFrame;
const layers = movie_clip.layers;
for (let idx = layers.length - 1; idx > -1; --idx) {
Expand All @@ -55,9 +48,6 @@ export const execute = async (movie_clip: MovieClip): Promise<void> =>

// マスクの親レイヤーでロックされている場合はスキップ
if (layer.mode === $MASK_MODE && layer.lock) {
// マスク終了、マスクフラグを解除
masked = false;
maskStyle = "";
continue;
}

Expand All @@ -66,49 +56,6 @@ export const execute = async (movie_clip: MovieClip): Promise<void> =>
continue;
}

if (!masked && layer.parentId > -1) {
const maskLayer = movieClip.getLayerById(layer.parentId);
if (maskLayer && maskLayer.lock) {
// マスク用のスタイルを初期化
masked = true;

const activeCharacters = maskLayer.getActiveCharacters(frame);
if (activeCharacters.length) {
const character = activeCharacters[0];
const instance = workSpace.getLibrary(character.libraryId);
if (instance) {
const cacheKey = character.cacheKey;

let canvas = $getCacheCanvas(workSpace.id, instance.id, cacheKey);
if (!canvas) {
canvas = await instance.getHTMLElement();
if (!canvas) {
continue;
}

// キャッシュに保存
// $setCacheCanvas(workSpace.id, instance.id, cacheKey, canvas);
}

const base64 = canvas.toDataURL();
const scale = window.devicePixelRatio;
const width = canvas.width / scale;
const height = canvas.height / scale;

// マスク用のスタイルを生成
maskStyle += `mask: url(${base64}), none;`;
maskStyle += `-webkit-mask: url(${base64}), none;`;
maskStyle += `mask-size: ${width}px ${height}px;`;
maskStyle += `-webkit-mask-size: ${width}px ${height}px;`;
maskStyle += "mask-repeat: no-repeat;";
maskStyle += "-webkit-mask-repeat: no-repeat;";
maskStyle += `mask-position: ${0}px ${0}px;`;
maskStyle += `-webkit-mask-position: ${0}px ${0}px;`;
}
}
}
}

// 昇順に並ぶかえ
const characters = activeCharacters
.sort((a, b) => a.depth < b.depth ? -1 : 1);
Expand Down

0 comments on commit 4d3e1bb

Please sign in to comment.