From fe6d605b13cf0cbf1c246a5a80d067287d371ad0 Mon Sep 17 00:00:00 2001 From: shmyga Date: Wed, 12 Feb 2020 11:57:53 +0300 Subject: [PATCH] [improve] (render) part shadow --- src/haxe/ru/m/draw/DrawPath.hx | 28 +++++++++ src/haxe/ru/m/puzzlez/render/PartView.hx | 5 +- src/haxe/ru/m/puzzlez/render/RenderUtil.hx | 63 +++++++++++-------- .../m/puzzlez/render/mask/IPartMaskBuilder.hx | 15 ----- src/haxe/ru/m/puzzlez/render/mask/PartMask.hx | 30 --------- .../BasePartBuilder.hx} | 13 ++-- .../ClassicPartBuilder.hx} | 6 +- .../ru/m/puzzlez/render/part/IPartBuilder.hx | 9 +++ src/haxe/ru/m/puzzlez/render/part/PartMask.hx | 14 +++++ .../SquarePartBuilder.hx} | 6 +- 10 files changed, 100 insertions(+), 89 deletions(-) create mode 100644 src/haxe/ru/m/draw/DrawPath.hx delete mode 100644 src/haxe/ru/m/puzzlez/render/mask/IPartMaskBuilder.hx delete mode 100644 src/haxe/ru/m/puzzlez/render/mask/PartMask.hx rename src/haxe/ru/m/puzzlez/render/{mask/BaseMaskBuilder.hx => part/BasePartBuilder.hx} (79%) rename src/haxe/ru/m/puzzlez/render/{mask/ClassicMaskBuilder.hx => part/ClassicPartBuilder.hx} (94%) create mode 100644 src/haxe/ru/m/puzzlez/render/part/IPartBuilder.hx create mode 100644 src/haxe/ru/m/puzzlez/render/part/PartMask.hx rename src/haxe/ru/m/puzzlez/render/{mask/SquareMaskBuilder.hx => part/SquarePartBuilder.hx} (92%) diff --git a/src/haxe/ru/m/draw/DrawPath.hx b/src/haxe/ru/m/draw/DrawPath.hx new file mode 100644 index 0000000..2131583 --- /dev/null +++ b/src/haxe/ru/m/draw/DrawPath.hx @@ -0,0 +1,28 @@ +package ru.m.draw; + +import flash.display.Graphics; +import flash.display.GraphicsPathCommand; +import flash.Vector; + +class DrawPath { + public var commands(default, null):Vector; + public var data(default, null):Vector; + + public function new() { + commands = new Vector(); + data = new Vector(); + } + + public function draw(graphics:Graphics):Void { + graphics.drawPath(commands, data); + } + + public function move(x:Float, y:Float):DrawPath { + var result = new DrawPath(); + result.commands = commands.slice(); + for (value in data) { + result.data.push(value + x); + } + return result; + } +} diff --git a/src/haxe/ru/m/puzzlez/render/PartView.hx b/src/haxe/ru/m/puzzlez/render/PartView.hx index d2de079..2a7b507 100644 --- a/src/haxe/ru/m/puzzlez/render/PartView.hx +++ b/src/haxe/ru/m/puzzlez/render/PartView.hx @@ -1,10 +1,10 @@ package ru.m.puzzlez.render; -import haxework.geom.Point; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.PixelSnapping; import flash.display.Sprite; +import haxework.geom.Point; import ru.m.puzzlez.core.Part; class PartView extends Sprite { @@ -33,9 +33,6 @@ class PartView extends Sprite { public function new(part:Part) { super(); - #if !android - filters = RenderUtil.buildFilters(); - #end this.id = part.id; this.size = part.rect.size.clone(); this.target = new Point(part.gridX * size.x, part.gridY * size.y); diff --git a/src/haxe/ru/m/puzzlez/render/RenderUtil.hx b/src/haxe/ru/m/puzzlez/render/RenderUtil.hx index cb723c5..5141a41 100644 --- a/src/haxe/ru/m/puzzlez/render/RenderUtil.hx +++ b/src/haxe/ru/m/puzzlez/render/RenderUtil.hx @@ -2,15 +2,15 @@ package ru.m.puzzlez.render; import flash.display.BitmapData; import flash.display.Shape; -import flash.filters.BitmapFilter; -import flash.filters.BitmapFilterQuality; -import flash.filters.DropShadowFilter; import flash.geom.Matrix; import haxework.geom.Rectangle; import ru.m.puzzlez.core.Part; -import ru.m.puzzlez.render.mask.PartMask; +import ru.m.puzzlez.render.part.ClassicPartBuilder; +import ru.m.puzzlez.render.part.IPartBuilder; +import ru.m.puzzlez.render.part.PartMask; class RenderUtil { + private static var builder:IPartBuilder = new ClassicPartBuilder(); public static function cropImage(source:BitmapData, rect:Rectangle):BitmapData { var image = new BitmapData(Std.int(rect.width), Std.int(rect.height)); @@ -22,37 +22,48 @@ class RenderUtil { return image; } - public static function buildFilters():Array { - var alpha = 0.6; - var blur = 1; - var strength = 4; - var distance = 2; - var quality = BitmapFilterQuality.HIGH; - var inner = true; - var knockout = false; - return [ - new DropShadowFilter(distance, 45 + 180, 0xffffff, alpha, blur, blur, strength, quality, inner, knockout), - new DropShadowFilter(distance, 45, 0x000000, alpha, blur, blur, strength, quality, inner, knockout), - ]; + private static function buildPartGeometry(part:Part):{rect:Rectangle, drawRect:Rectangle} { + var source = new Rectangle(part.rect.width * part.gridX, part.rect.height * part.gridY, part.rect.width, part.rect.height); + var rect = source.clone(); + var offset = rect.width / 4 + rect.width * 0.05; + rect.x -= offset; + rect.y -= offset; + rect.width += offset * 2; + rect.height += offset * 2; + var drawRect = source.clone(); + drawRect.x = offset; + drawRect.y = offset ; + return {rect:rect, drawRect:drawRect}; } public static function cropImagePart(source:BitmapData, part:Part):BitmapData { - var rect = new Rectangle(part.rect.width * part.gridX, part.rect.height * part.gridY, part.rect.width, part.rect.width); - var mask = new PartMask(rect, part.bounds); + var geometry = buildPartGeometry(part); + var path = builder.build(geometry.drawRect, part.bounds); var canvas:Shape = new Shape(); canvas.cacheAsBitmap = true; - canvas.mask = mask; + canvas.mask = new PartMask(path); var matrix = new Matrix(); - matrix.translate(-mask.rect.x, -mask.rect.y); + matrix.translate(-geometry.rect.x, -geometry.rect.y); canvas.graphics.beginBitmapFill(source, matrix, false, true); - canvas.graphics.drawRect(0, 0, mask.rect.width, mask.rect.height); + canvas.graphics.drawRect(0, 0, geometry.rect.width, geometry.rect.height); canvas.graphics.endFill(); - var image = new BitmapData(Std.int(mask.rect.width), Std.int(mask.rect.height), true, 0x00000000); + var image = new BitmapData(Std.int(geometry.rect.width), Std.int(geometry.rect.height), true, 0x00000000); image.draw(canvas, null, null, null, null, true); - /*for (filter in buildFilters()) { - image.applyFilter(image, image.rect, image.rect.topLeft, filter); - }*/ - return image; + var shadow = 2; + var canvas2 = new Shape(); + canvas2.cacheAsBitmap = true; + canvas2.graphics.beginFill(0x000000, 0.4); + path.move(-shadow, -shadow).draw(canvas2.graphics); + canvas2.graphics.endFill(); + canvas2.graphics.beginFill(0xffffff, 0.4); + path.move(shadow, shadow).draw(canvas2.graphics); + canvas2.graphics.endFill(); + canvas2.graphics.beginBitmapFill(image, null, false, true); + canvas2.graphics.drawRect(0, 0, geometry.rect.width, geometry.rect.height); + canvas2.graphics.endFill(); + var image2 = new BitmapData(image.width, image.height, true, 0x00000000); + image2.draw(canvas2, null, null, null, null, true); + return image2; } public static function containRectangle(source:Rectangle, target:Rectangle):Rectangle { diff --git a/src/haxe/ru/m/puzzlez/render/mask/IPartMaskBuilder.hx b/src/haxe/ru/m/puzzlez/render/mask/IPartMaskBuilder.hx deleted file mode 100644 index 43cc6e6..0000000 --- a/src/haxe/ru/m/puzzlez/render/mask/IPartMaskBuilder.hx +++ /dev/null @@ -1,15 +0,0 @@ -package ru.m.puzzlez.render.mask; - -import flash.display.GraphicsPathCommand; -import flash.Vector; -import haxework.geom.Rectangle; -import ru.m.puzzlez.core.Part; - -typedef DrawPath = { - var commands:Vector; - var data:Vector; -} - -interface IPartMaskBuilder { - public function build(rect:Rectangle, bound:PartBounds):DrawPath; -} diff --git a/src/haxe/ru/m/puzzlez/render/mask/PartMask.hx b/src/haxe/ru/m/puzzlez/render/mask/PartMask.hx deleted file mode 100644 index b29b656..0000000 --- a/src/haxe/ru/m/puzzlez/render/mask/PartMask.hx +++ /dev/null @@ -1,30 +0,0 @@ -package ru.m.puzzlez.render.mask; - -import flash.display.Shape; -import haxework.geom.Rectangle; -import ru.m.puzzlez.core.Part; -import ru.m.puzzlez.render.mask.IPartMaskBuilder; - -class PartMask extends Shape { - - public var rect(default, null):Rectangle; - - private static var builder:IPartMaskBuilder = new ClassicMaskBuilder(); - - public function new(rect:Rectangle, bounds:PartBounds) { - super(); - this.rect = rect.clone(); - var offset = rect.width / 4 + rect.width * 0.05; - this.rect.x -= offset; - this.rect.y -= offset; - this.rect.width += offset * 2; - this.rect.height += offset * 2; - var drawRect = rect.clone(); - drawRect.x = offset; - drawRect.y = offset; - var drawPath = builder.build(drawRect, bounds); - graphics.beginFill(0xff00ff, 1); - graphics.drawPath(drawPath.commands, drawPath.data); - graphics.endFill(); - } -} diff --git a/src/haxe/ru/m/puzzlez/render/mask/BaseMaskBuilder.hx b/src/haxe/ru/m/puzzlez/render/part/BasePartBuilder.hx similarity index 79% rename from src/haxe/ru/m/puzzlez/render/mask/BaseMaskBuilder.hx rename to src/haxe/ru/m/puzzlez/render/part/BasePartBuilder.hx index ad40d35..01f2ea2 100644 --- a/src/haxe/ru/m/puzzlez/render/mask/BaseMaskBuilder.hx +++ b/src/haxe/ru/m/puzzlez/render/part/BasePartBuilder.hx @@ -1,12 +1,12 @@ -package ru.m.puzzlez.render.mask; +package ru.m.puzzlez.render.part; import flash.display.GraphicsPathCommand; import haxework.geom.Rectangle; -import openfl.Vector; +import ru.m.draw.DrawPath; import ru.m.puzzlez.core.Part; -import ru.m.puzzlez.render.mask.IPartMaskBuilder; +import ru.m.puzzlez.render.part.IPartBuilder; -class BaseMaskBuilder implements IPartMaskBuilder { +class BasePartBuilder implements IPartBuilder { public function new() { } @@ -21,10 +21,7 @@ class BaseMaskBuilder implements IPartMaskBuilder { } public function build(rect:Rectangle, bounds:PartBounds):DrawPath { - var path:DrawPath = { - commands: new Vector(), - data: new Vector(), - } + var path = new DrawPath(); createAngle(path, rect.left, rect.top); createBound(path, rect.left, rect.top, rect.right, rect.top, bounds.top); createAngle(path, rect.right, rect.top); diff --git a/src/haxe/ru/m/puzzlez/render/mask/ClassicMaskBuilder.hx b/src/haxe/ru/m/puzzlez/render/part/ClassicPartBuilder.hx similarity index 94% rename from src/haxe/ru/m/puzzlez/render/mask/ClassicMaskBuilder.hx rename to src/haxe/ru/m/puzzlez/render/part/ClassicPartBuilder.hx index 59405b0..e3343bc 100644 --- a/src/haxe/ru/m/puzzlez/render/mask/ClassicMaskBuilder.hx +++ b/src/haxe/ru/m/puzzlez/render/part/ClassicPartBuilder.hx @@ -1,11 +1,11 @@ -package ru.m.puzzlez.render.mask; +package ru.m.puzzlez.render.part; import flash.display.GraphicsPathCommand; +import ru.m.draw.DrawPath; import ru.m.puzzlez.core.BoundType; import ru.m.puzzlez.core.Part; -import ru.m.puzzlez.render.mask.IPartMaskBuilder; -class ClassicMaskBuilder extends BaseMaskBuilder { +class ClassicPartBuilder extends BasePartBuilder { override private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void { var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX); diff --git a/src/haxe/ru/m/puzzlez/render/part/IPartBuilder.hx b/src/haxe/ru/m/puzzlez/render/part/IPartBuilder.hx new file mode 100644 index 0000000..01d47fc --- /dev/null +++ b/src/haxe/ru/m/puzzlez/render/part/IPartBuilder.hx @@ -0,0 +1,9 @@ +package ru.m.puzzlez.render.part; + +import haxework.geom.Rectangle; +import ru.m.draw.DrawPath; +import ru.m.puzzlez.core.Part; + +interface IPartBuilder { + public function build(rect:Rectangle, bound:PartBounds):DrawPath; +} diff --git a/src/haxe/ru/m/puzzlez/render/part/PartMask.hx b/src/haxe/ru/m/puzzlez/render/part/PartMask.hx new file mode 100644 index 0000000..46520b5 --- /dev/null +++ b/src/haxe/ru/m/puzzlez/render/part/PartMask.hx @@ -0,0 +1,14 @@ +package ru.m.puzzlez.render.part; + +import flash.display.Shape; +import ru.m.draw.DrawPath; + +class PartMask extends Shape { + + public function new(path:DrawPath) { + super(); + graphics.beginFill(0xff00ff, 1); + path.draw(graphics); + graphics.endFill(); + } +} diff --git a/src/haxe/ru/m/puzzlez/render/mask/SquareMaskBuilder.hx b/src/haxe/ru/m/puzzlez/render/part/SquarePartBuilder.hx similarity index 92% rename from src/haxe/ru/m/puzzlez/render/mask/SquareMaskBuilder.hx rename to src/haxe/ru/m/puzzlez/render/part/SquarePartBuilder.hx index 386742a..58cc7f1 100644 --- a/src/haxe/ru/m/puzzlez/render/mask/SquareMaskBuilder.hx +++ b/src/haxe/ru/m/puzzlez/render/part/SquarePartBuilder.hx @@ -1,11 +1,11 @@ -package ru.m.puzzlez.render.mask; +package ru.m.puzzlez.render.part; import flash.display.GraphicsPathCommand; +import ru.m.draw.DrawPath; import ru.m.puzzlez.core.BoundType; import ru.m.puzzlez.core.Part; -import ru.m.puzzlez.render.mask.IPartMaskBuilder; -class SquareMaskBuilder extends BaseMaskBuilder { +class SquarePartBuilder extends BasePartBuilder { override private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void { var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX);