From 4d3e1bb855a23f05f35412a7c86843fbe5868cb3 Mon Sep 17 00:00:00 2001 From: ienaga Date: Sat, 20 Jul 2024 15:14:28 +0900 Subject: [PATCH] =?UTF-8?q?#147=20feat:=20=E3=83=9E=E3=82=B9=E3=82=AF?= =?UTF-8?q?=E7=A7=BB=E5=8B=95=E3=82=92=E5=AE=9F=E8=A3=85(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TransformSetting/TransformSettingUtil.ts | 59 +++++++++++++++++++ ...BitmapCreateDisplayObjectElementUseCase.ts | 9 ++- ...ieClipCreateDisplayObjectElementUseCase.ts | 9 ++- .../ShapeCreateDisplayObjectElementUseCase.ts | 9 ++- .../ExternalCharacterUpdateXUseCase.ts | 3 +- .../ExternalCharacterUpdateYUseCase.ts | 3 +- ...layObjectUpdateMaskInCanvasStyleService.ts | 44 ++++++-------- ...DisplayObjectSelectedMoveElementUseCase.ts | 8 ++- ...ayObjectUpdateLayerMaskInElementUseCase.ts | 4 +- .../usecase/ScreenAreaRedrawUseCase.ts | 53 ----------------- 10 files changed, 115 insertions(+), 86 deletions(-) diff --git a/src/js/controller/application/TransformSetting/TransformSettingUtil.ts b/src/js/controller/application/TransformSetting/TransformSettingUtil.ts index 2794f29b..d8f8fe88 100644 --- a/src/js/controller/application/TransformSetting/TransformSettingUtil.ts +++ b/src/js/controller/application/TransformSetting/TransformSettingUtil.ts @@ -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 行列の掛け算 @@ -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; + + } }; \ No newline at end of file diff --git a/src/js/core/application/Bitmap/usecase/BitmapCreateDisplayObjectElementUseCase.ts b/src/js/core/application/Bitmap/usecase/BitmapCreateDisplayObjectElementUseCase.ts index 1127b075..9a02c391 100644 --- a/src/js/core/application/Bitmap/usecase/BitmapCreateDisplayObjectElementUseCase.ts +++ b/src/js/core/application/Bitmap/usecase/BitmapCreateDisplayObjectElementUseCase.ts @@ -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に描画して返却する @@ -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()) { diff --git a/src/js/core/application/MovieClip/usecase/MovieClipCreateDisplayObjectElementUseCase.ts b/src/js/core/application/MovieClip/usecase/MovieClipCreateDisplayObjectElementUseCase.ts index cfb6fcc0..54efd902 100644 --- a/src/js/core/application/MovieClip/usecase/MovieClipCreateDisplayObjectElementUseCase.ts +++ b/src/js/core/application/MovieClip/usecase/MovieClipCreateDisplayObjectElementUseCase.ts @@ -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に描画して返却する @@ -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()) { diff --git a/src/js/core/application/Shape/usecase/ShapeCreateDisplayObjectElementUseCase.ts b/src/js/core/application/Shape/usecase/ShapeCreateDisplayObjectElementUseCase.ts index a1d16512..a32fe305 100644 --- a/src/js/core/application/Shape/usecase/ShapeCreateDisplayObjectElementUseCase.ts +++ b/src/js/core/application/Shape/usecase/ShapeCreateDisplayObjectElementUseCase.ts @@ -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に描画して返却する @@ -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()) { diff --git a/src/js/external/core/application/ExternalCharacter/usecase/ExternalCharacterUpdateXUseCase.ts b/src/js/external/core/application/ExternalCharacter/usecase/ExternalCharacterUpdateXUseCase.ts index 851cef1a..fded33d1 100644 --- a/src/js/external/core/application/ExternalCharacter/usecase/ExternalCharacterUpdateXUseCase.ts +++ b/src/js/external/core/application/ExternalCharacter/usecase/ExternalCharacterUpdateXUseCase.ts @@ -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座標を更新 @@ -85,7 +86,7 @@ export const execute = async ( } await screenDisplayObjectUpdateMaskInCanvasStyleService( - node, layer, x, character.y + node, layer, x, character.y, $getMaskMatrix(character) ); } } diff --git a/src/js/external/core/application/ExternalCharacter/usecase/ExternalCharacterUpdateYUseCase.ts b/src/js/external/core/application/ExternalCharacter/usecase/ExternalCharacterUpdateYUseCase.ts index 2b596a3b..4b369cdc 100644 --- a/src/js/external/core/application/ExternalCharacter/usecase/ExternalCharacterUpdateYUseCase.ts +++ b/src/js/external/core/application/ExternalCharacter/usecase/ExternalCharacterUpdateYUseCase.ts @@ -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座標を更新 @@ -85,7 +86,7 @@ export const execute = async ( } await screenDisplayObjectUpdateMaskInCanvasStyleService( - node, layer, character.x, y + node, layer, character.x, y, $getMaskMatrix(character) ); } } diff --git a/src/js/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService.ts b/src/js/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService.ts index 4715bf5c..b3ff15d4 100644 --- a/src/js/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService.ts +++ b/src/js/screen/application/DisplayObject/service/ScreenDisplayObjectUpdateMaskInCanvasStyleService.ts @@ -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"; @@ -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 @@ -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 => { - if (layer.parentId === -1) { + if (layer.mode !== $MASK_IN_MODE) { return ; } @@ -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`; }; \ No newline at end of file diff --git a/src/js/screen/application/DisplayObject/usecase/ScreenDisplayObjectSelectedMoveElementUseCase.ts b/src/js/screen/application/DisplayObject/usecase/ScreenDisplayObjectSelectedMoveElementUseCase.ts index 0cc9ebdf..87db8b15 100644 --- a/src/js/screen/application/DisplayObject/usecase/ScreenDisplayObjectSelectedMoveElementUseCase.ts +++ b/src/js/screen/application/DisplayObject/usecase/ScreenDisplayObjectSelectedMoveElementUseCase.ts @@ -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を移動する @@ -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); @@ -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) ); } } diff --git a/src/js/screen/application/DisplayObject/usecase/ScreenDisplayObjectUpdateLayerMaskInElementUseCase.ts b/src/js/screen/application/DisplayObject/usecase/ScreenDisplayObjectUpdateLayerMaskInElementUseCase.ts index 323331af..8b791644 100644 --- a/src/js/screen/application/DisplayObject/usecase/ScreenDisplayObjectUpdateLayerMaskInElementUseCase.ts +++ b/src/js/screen/application/DisplayObject/usecase/ScreenDisplayObjectUpdateLayerMaskInElementUseCase.ts @@ -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のマスクスタイルをレイヤーの状態に合わせて更新 @@ -66,7 +67,8 @@ export const execute = async (movie_clip: MovieClip, layer: Layer): Promise => // 再描画状態を設定 $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) { @@ -55,9 +48,6 @@ export const execute = async (movie_clip: MovieClip): Promise => // マスクの親レイヤーでロックされている場合はスキップ if (layer.mode === $MASK_MODE && layer.lock) { - // マスク終了、マスクフラグを解除 - masked = false; - maskStyle = ""; continue; } @@ -66,49 +56,6 @@ export const execute = async (movie_clip: MovieClip): Promise => 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);