Skip to content

Commit

Permalink
#154 maskプロパティを実装(WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
ienaga committed Dec 1, 2024
1 parent f131772 commit 4629c6f
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 82 deletions.
43 changes: 0 additions & 43 deletions packages/display/src/DisplayObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { IParent } from "./interface/IParent";
import type { IPlaceObject } from "./interface/IPlaceObject";
import type { IBlendMode } from "./interface/IBlendMode";
import type { IFilterArray } from "./interface/IFilterArray";
import type { IDisplayObject } from "./interface/IDisplayObject";
import type { MovieClip } from "./MovieClip";
import type { ISprite } from "./interface/ISprite";
import type {
Expand Down Expand Up @@ -372,16 +371,6 @@ export class DisplayObject extends EventDispatcher
*/
private _$variables: Map<any, any> | null;

/**
* @description セットされてるDisplayObjectがマスクとして使用されます。
* The DisplayObject set is used as a mask.
*
* @type {IDisplayObject<any>|null}
* @default null
* @private
*/
private _$mask: IDisplayObject<any> | null;

/**
* @description マスクとしてDisplayObjectにセットされているかを示します。
* Indicates whether the DisplayObject is set as a mask.
Expand Down Expand Up @@ -437,7 +426,6 @@ export class DisplayObject extends EventDispatcher
this.$blendMode = null;

this._$visible = true;
this._$mask = null;
this._$scale9Grid = null;
this._$variables = null;

Expand Down Expand Up @@ -564,37 +552,6 @@ export class DisplayObject extends EventDispatcher
: null;
}

/**
* @description 呼び出し元の表示オブジェクトは、指定された mask オブジェクトによってマスクされます。
* The calling display object is masked by the specified mask object.
*
* @member {DisplayObject|null}
* @public
*/
get mask (): IDisplayObject<any> | null
{
return this._$mask;
}
set mask (mask: IDisplayObject<any> | null)
{
if (mask === this._$mask) {
return ;
}

// 初期化
if (this._$mask) {
this._$mask.isMask = false;
this._$mask = null;
}

if (mask) {
mask.isMask = true;
this._$mask = mask;
}

displayObjectApplyChangesService(this);
}

/**
* @description マウスまたはユーザー入力デバイスの x 軸の位置をピクセルで示します。
* Indicates the x coordinate of the mouse or user input device position, in pixels.
Expand Down
45 changes: 45 additions & 0 deletions packages/display/src/DisplayObjectContainer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { DisplayObject } from "./DisplayObject";
import type { IDisplayObject } from "./interface/IDisplayObject";
import { execute as displayObjectApplyChangesService } from "./DisplayObject/service/DisplayObjectApplyChangesService";
import { execute as displayObjectContainerAddChildUseCase } from "./DisplayObjectContainer/usecase/DisplayObjectContainerAddChildUseCase";
import { execute as displayObjectContainerRemoveChildUseCase } from "./DisplayObjectContainer/usecase/DisplayObjectContainerRemoveChildUseCase";
import { $getArray } from "./DisplayObjectUtil";
Expand Down Expand Up @@ -34,6 +35,16 @@ export class DisplayObjectContainer extends InteractiveObject
*/
protected readonly _$children: IDisplayObject<any>[];

/**
* @description セットされてるDisplayObjectがマスクとして使用されます。
* The DisplayObject set is used as a mask.
*
* @type {IDisplayObject<any>|null}
* @default null
* @private
*/
private _$mask: IDisplayObject<any> | null;

/**
* @description オブジェクトの子がマウスまたはユーザー入力デバイスに対応しているかどうかを判断します。
* Determine if the object's children are compatible with mouse or user input devices.
Expand Down Expand Up @@ -62,9 +73,12 @@ export class DisplayObjectContainer extends InteractiveObject
{
super();

// public
this.isContainerEnabled = true;
this.mouseChildren = true;

// private
this._$mask = null;
this._$children = $getArray();
}

Expand All @@ -81,6 +95,37 @@ export class DisplayObjectContainer extends InteractiveObject
return this.children.length;
}

/**
* @description 呼び出し元の表示オブジェクトは、指定された mask オブジェクトによってマスクされます。
* The calling display object is masked by the specified mask object.
*
* @member {DisplayObject|null}
* @public
*/
get mask (): IDisplayObject<any> | null
{
return this._$mask;
}
set mask (mask: IDisplayObject<any> | null)
{
if (mask === this._$mask) {
return ;
}

// 初期化
if (this._$mask) {
this._$mask.isMask = false;
this._$mask = null;
}

if (mask) {
mask.isMask = true;
this._$mask = mask;
}

displayObjectApplyChangesService(this);
}

/**
* @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。
* Adds a child DisplayObject instance to this DisplayObjectContainer instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,57 @@ export const execute = <P extends DisplayObjectContainer>(
// todo
}

// mask
const maskInstance = display_object_container.mask;
if (maskInstance) {

const bounds = displayObjectIsMaskReflectedInDisplayUseCase(
maskInstance,
tMatrix,
renderer_width,
renderer_height,
point_x,
point_y
);

if (!bounds) {
maskInstance.changed = false;
render_queue.push(0);
} else {

render_queue.push(1);

// マスクの描画範囲
render_queue.push(...bounds);

switch (true) {

case maskInstance.isContainerEnabled: // 0x00
break;

case maskInstance.isShape: // 0x01
shapeGenerateClipQueueUseCase(
maskInstance as Shape,
render_queue,
tMatrix
);
break;

case maskInstance.isText: // 0x02
break;

case maskInstance.isVideo: // 0x03
break;

default:
break;
}
}

} else {
render_queue.push(0);
}

const colorTransform = isLayer
? $COLOR_ARRAY_IDENTITY
: tColorTransform;
Expand All @@ -120,6 +171,9 @@ export const execute = <P extends DisplayObjectContainer>(
for (let idx = 0; idx < children.length; ++idx) {

const child = children[idx] as DisplayObject;
if (child.isMask) {
continue;
}

render_queue.push(child.placeId, child.clipDepth);
if (clipDepth && child.placeId > clipDepth) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ export const execute = <P extends DisplayObjectContainer, D extends DisplayObjec
}
}

let hitTest = false;

// mask hit test
const maskInstance = instance.mask as D | null;
if (maskInstance) {
Expand All @@ -173,7 +175,6 @@ export const execute = <P extends DisplayObjectContainer, D extends DisplayObjec
maskMatrix = matrix.rawData;
}

let hitTest = false;
switch (true) {

case maskInstance.isContainerEnabled:
Expand Down Expand Up @@ -216,42 +217,43 @@ export const execute = <P extends DisplayObjectContainer, D extends DisplayObjec
if (!hitTest) {
continue;
}
}

let hitTest = false;
switch (true) {

case instance.isContainerEnabled:
hitTest = execute(
instance as unknown as DisplayObjectContainer,
hit_context, tMatrix, hit_object, mouseChildren
);
break;

case instance.isShape:
hitTest = shapeHitTestUseCase(
instance as unknown as Shape,
hit_context, tMatrix, hit_object
);
break;

case instance.isText:
hitTest = textFieldHitTestUseCase(
instance as unknown as TextField,
hit_context, tMatrix, hit_object
);
break;

case instance.isVideo:
hitTest = videoHitTestUseCase(
instance as unknown as Video,
hit_context, tMatrix, hit_object
);
break;

default:
break;
} else {

switch (true) {

case instance.isContainerEnabled:
hitTest = execute(
instance as unknown as DisplayObjectContainer,
hit_context, tMatrix, hit_object, mouseChildren
);
break;

case instance.isShape:
hitTest = shapeHitTestUseCase(
instance as unknown as Shape,
hit_context, tMatrix, hit_object
);
break;

case instance.isText:
hitTest = textFieldHitTestUseCase(
instance as unknown as TextField,
hit_context, tMatrix, hit_object
);
break;

case instance.isVideo:
hitTest = videoHitTestUseCase(
instance as unknown as Video,
hit_context, tMatrix, hit_object
);
break;

default:
break;

}
}

if (!hitTest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Graphics } from "../../Graphics";
*/
export const execute = (
context: CanvasRenderingContext2D,
recodes: any[],
recodes: Float32Array,
hit_object: IPlayerHitObject
): boolean => {

Expand Down
4 changes: 2 additions & 2 deletions packages/display/src/Shape/usecase/ShapeHitTestUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const execute = (
): boolean => {

const graphics = shape.graphics;
if (!graphics.$recodes) {
if (!graphics.isDrawable) {
return false;
}

Expand All @@ -46,7 +46,7 @@ export const execute = (
);

const hit = graphicsHitTestService(
hit_context, graphics.$recodes, hit_object
hit_context, graphics.buffer, hit_object
);

if (tMatrix !== matrix) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,46 @@ export const execute = (
index: number,
image_bitmaps: ImageBitmap[] | null
): number => {

const useMask = render_queue[index++];
if (useMask) {

// これまでの描画データを描画して初期化
$context.drawArraysInstanced();

// 設定値を保存
$context.save();

// マスク描画の開始準備
$context.beginMask();

$context.startMask(
render_queue[index++],
render_queue[index++],
render_queue[index++],
render_queue[index++]
);

const type = render_queue[index++];
switch (type) {

case 0x00: // container
break;

case 0x01: // shape
index = shapeClipRenderUseCase(render_queue, index);
break;

case 0x02: // text
break;

case 0x03: // video
break;

}
$context.endMask();
}

let endClipDepth = 0;
let canRenderMask = true;

Expand Down Expand Up @@ -122,7 +162,7 @@ export const execute = (
}

// end mask
if (endClipDepth) {
if (endClipDepth || useMask) {
$context.restore();
$context.leaveMask();
}
Expand Down

0 comments on commit 4629c6f

Please sign in to comment.