[add] (render) PartMaskBuilder
This commit is contained in:
@@ -1,67 +0,0 @@
|
|||||||
package ru.m.puzzlez.render;
|
|
||||||
|
|
||||||
import flash.display.GraphicsPathCommand;
|
|
||||||
import flash.display.Shape;
|
|
||||||
import flash.geom.Rectangle;
|
|
||||||
import flash.Vector;
|
|
||||||
import ru.m.puzzlez.core.Part;
|
|
||||||
|
|
||||||
|
|
||||||
class PartMask extends Shape {
|
|
||||||
|
|
||||||
private static function createBound(commands:Vector<GraphicsPathCommand>, data:Vector<Float>, fromX:Float, fromY:Float, toX:Float, toY:Float, type:BoundType) {
|
|
||||||
var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX);
|
|
||||||
var dy = toY == fromY ? 0 : (toY - fromY) / Math.abs(toY - fromY);
|
|
||||||
var boundLength = Math.max(Math.abs(toX - fromX), Math.abs(toY - fromY));
|
|
||||||
var spikeWidth = boundLength * 0.2;
|
|
||||||
var spikeOffset = (boundLength - spikeWidth) / 2;
|
|
||||||
var spikeDepth = switch type {
|
|
||||||
case NONE: 0;
|
|
||||||
case IN: spikeWidth;
|
|
||||||
case OUT: -spikeWidth;
|
|
||||||
}
|
|
||||||
switch type {
|
|
||||||
case NONE:
|
|
||||||
case IN | OUT:
|
|
||||||
commands.push(GraphicsPathCommand.LINE_TO);
|
|
||||||
data.push(fromX + spikeOffset * dx);
|
|
||||||
data.push(fromY + spikeOffset * dy);
|
|
||||||
commands.push(GraphicsPathCommand.LINE_TO);
|
|
||||||
data.push(fromX + spikeOffset * dx - spikeDepth * dy);
|
|
||||||
data.push(fromY + spikeDepth * dx + spikeOffset * dy);
|
|
||||||
commands.push(GraphicsPathCommand.LINE_TO);
|
|
||||||
data.push(fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy);
|
|
||||||
data.push(fromY + spikeDepth * dx + (spikeOffset + spikeWidth) * dy);
|
|
||||||
commands.push(GraphicsPathCommand.LINE_TO);
|
|
||||||
data.push(fromX + (spikeOffset + spikeWidth) * dx);
|
|
||||||
data.push(fromY + (spikeOffset + spikeWidth) * dy);
|
|
||||||
}
|
|
||||||
commands.push(GraphicsPathCommand.LINE_TO);
|
|
||||||
data.push(toX);
|
|
||||||
data.push(toY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public var rect(default, null):Rectangle;
|
|
||||||
|
|
||||||
public function new(rect:Rectangle, bound:Bounds) {
|
|
||||||
super();
|
|
||||||
graphics.beginFill(0xff00ff, 1);
|
|
||||||
var commands = new Vector<GraphicsPathCommand>();
|
|
||||||
var data = new Vector<Float>();
|
|
||||||
commands.push(GraphicsPathCommand.MOVE_TO);
|
|
||||||
data.push(rect.left);
|
|
||||||
data.push(rect.top);
|
|
||||||
createBound(commands, data, rect.left, rect.top, rect.right, rect.top, bound.top);
|
|
||||||
createBound(commands, data, rect.right, rect.top, rect.right, rect.bottom, bound.right);
|
|
||||||
createBound(commands, data, rect.right, rect.bottom, rect.left, rect.bottom, bound.bottom);
|
|
||||||
createBound(commands, data, rect.left, rect.bottom, rect.left, rect.top, bound.left);
|
|
||||||
graphics.drawPath(commands, data);
|
|
||||||
graphics.endFill();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package ru.m.puzzlez.render;
|
package ru.m.puzzlez.render;
|
||||||
|
|
||||||
import flash.geom.Point;
|
|
||||||
import flash.display.Bitmap;
|
import flash.display.Bitmap;
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
|
import flash.display.PixelSnapping;
|
||||||
import flash.display.Sprite;
|
import flash.display.Sprite;
|
||||||
|
import flash.geom.Point;
|
||||||
|
|
||||||
class PartView extends Sprite {
|
class PartView extends Sprite {
|
||||||
|
|
||||||
@@ -24,8 +25,7 @@ class PartView extends Sprite {
|
|||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
bitmap = new Bitmap();
|
bitmap = new Bitmap(image, PixelSnapping.ALWAYS, true);
|
||||||
bitmap.bitmapData = image;
|
|
||||||
addChild(bitmap);
|
addChild(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import openfl.Assets;
|
|||||||
import promhx.Promise;
|
import promhx.Promise;
|
||||||
import ru.m.puzzlez.core.ImageSource;
|
import ru.m.puzzlez.core.ImageSource;
|
||||||
import ru.m.puzzlez.core.Part;
|
import ru.m.puzzlez.core.Part;
|
||||||
|
import ru.m.puzzlez.render.mask.PartMask;
|
||||||
|
|
||||||
class RenderUtil {
|
class RenderUtil {
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ class RenderUtil {
|
|||||||
var canvas:Shape = new Shape();
|
var canvas:Shape = new Shape();
|
||||||
canvas.cacheAsBitmap = true;
|
canvas.cacheAsBitmap = true;
|
||||||
canvas.mask = mask;
|
canvas.mask = mask;
|
||||||
canvas.graphics.beginBitmapFill(source);
|
canvas.graphics.beginBitmapFill(source, null, false, true);
|
||||||
canvas.graphics.drawRect(0, 0, source.width, source.height);
|
canvas.graphics.drawRect(0, 0, source.width, source.height);
|
||||||
canvas.graphics.endFill();
|
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(mask.rect.width), Std.int(mask.rect.height), true, 0x00000000);
|
||||||
|
|||||||
34
src/haxe/ru/m/puzzlez/render/mask/BaseMaskBuilder.hx
Normal file
34
src/haxe/ru/m/puzzlez/render/mask/BaseMaskBuilder.hx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package ru.m.puzzlez.render.mask;
|
||||||
|
|
||||||
|
import flash.display.GraphicsPathCommand;
|
||||||
|
import flash.geom.Rectangle;
|
||||||
|
import openfl.Vector;
|
||||||
|
import ru.m.puzzlez.core.Part;
|
||||||
|
import ru.m.puzzlez.render.mask.IPartMaskBuilder;
|
||||||
|
|
||||||
|
class BaseMaskBuilder implements IPartMaskBuilder {
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, type:BoundType):Void {
|
||||||
|
path.commands.push(GraphicsPathCommand.LINE_TO);
|
||||||
|
path.data.push(toX);
|
||||||
|
path.data.push(toY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build(rect:Rectangle, bounds:Bounds):DrawPath {
|
||||||
|
var path:DrawPath = {
|
||||||
|
commands: new Vector<GraphicsPathCommand>(),
|
||||||
|
data: new Vector<Float>(),
|
||||||
|
}
|
||||||
|
path.commands.push(GraphicsPathCommand.MOVE_TO);
|
||||||
|
path.data.push(rect.left);
|
||||||
|
path.data.push(rect.top);
|
||||||
|
createBound(path, rect.left, rect.top, rect.right, rect.top, bounds.top);
|
||||||
|
createBound(path, rect.right, rect.top, rect.right, rect.bottom, bounds.right);
|
||||||
|
createBound(path, rect.right, rect.bottom, rect.left, rect.bottom, bounds.bottom);
|
||||||
|
createBound(path, rect.left, rect.bottom, rect.left, rect.top, bounds.left);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/haxe/ru/m/puzzlez/render/mask/ClassicMaskBuilder.hx
Normal file
39
src/haxe/ru/m/puzzlez/render/mask/ClassicMaskBuilder.hx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package ru.m.puzzlez.render.mask;
|
||||||
|
|
||||||
|
import flash.display.GraphicsPathCommand;
|
||||||
|
import ru.m.puzzlez.core.Part;
|
||||||
|
import ru.m.puzzlez.render.mask.IPartMaskBuilder;
|
||||||
|
|
||||||
|
class ClassicMaskBuilder extends BaseMaskBuilder {
|
||||||
|
|
||||||
|
override private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, type:BoundType):Void {
|
||||||
|
var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX);
|
||||||
|
var dy = toY == fromY ? 0 : (toY - fromY) / Math.abs(toY - fromY);
|
||||||
|
var boundLength = Math.max(Math.abs(toX - fromX), Math.abs(toY - fromY));
|
||||||
|
var spikeWidth = boundLength * 0.2;
|
||||||
|
var spikeOffset = (boundLength - spikeWidth) / 2;
|
||||||
|
var spikeDepth = switch type {
|
||||||
|
case NONE: 0;
|
||||||
|
case IN: spikeWidth;
|
||||||
|
case OUT: -spikeWidth;
|
||||||
|
};
|
||||||
|
switch type {
|
||||||
|
case NONE:
|
||||||
|
case IN | OUT:
|
||||||
|
path.commands.push(GraphicsPathCommand.LINE_TO);
|
||||||
|
path.data.push(fromX + spikeOffset * dx);
|
||||||
|
path.data.push(fromY + spikeOffset * dy);
|
||||||
|
path.commands.push(GraphicsPathCommand.CURVE_TO);
|
||||||
|
path.data.push(fromX + (spikeOffset * 0.8) * dx - spikeDepth * dy);
|
||||||
|
path.data.push(fromY + spikeDepth * dx + (spikeOffset * 0.8) * dy);
|
||||||
|
path.data.push(fromX + (spikeOffset + spikeWidth / 2) * dx - (spikeDepth * 1.1) * dy);
|
||||||
|
path.data.push(fromY + (spikeDepth * 1.1) * dx + (spikeOffset + spikeWidth / 2) * dy);
|
||||||
|
path.commands.push(GraphicsPathCommand.CURVE_TO);
|
||||||
|
path.data.push(fromX + (spikeOffset + spikeWidth + spikeOffset * 0.2) * dx - spikeDepth * dy);
|
||||||
|
path.data.push(fromY + spikeDepth * dx + (spikeOffset + spikeWidth + spikeOffset * 0.2) * dy);
|
||||||
|
path.data.push(fromX + (spikeOffset + spikeWidth) * dx);
|
||||||
|
path.data.push(fromY + (spikeOffset + spikeWidth) * dy);
|
||||||
|
}
|
||||||
|
super.createBound(path, fromY, fromY, toX, toY, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/haxe/ru/m/puzzlez/render/mask/IPartMaskBuilder.hx
Normal file
15
src/haxe/ru/m/puzzlez/render/mask/IPartMaskBuilder.hx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package ru.m.puzzlez.render.mask;
|
||||||
|
|
||||||
|
import flash.display.GraphicsPathCommand;
|
||||||
|
import flash.geom.Rectangle;
|
||||||
|
import flash.Vector;
|
||||||
|
import ru.m.puzzlez.core.Part;
|
||||||
|
|
||||||
|
typedef DrawPath = {
|
||||||
|
var commands:Vector<GraphicsPathCommand>;
|
||||||
|
var data:Vector<Float>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IPartMaskBuilder {
|
||||||
|
public function build(rect:Rectangle, bound:Bounds):DrawPath;
|
||||||
|
}
|
||||||
25
src/haxe/ru/m/puzzlez/render/mask/PartMask.hx
Normal file
25
src/haxe/ru/m/puzzlez/render/mask/PartMask.hx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package ru.m.puzzlez.render.mask;
|
||||||
|
|
||||||
|
import flash.display.Shape;
|
||||||
|
import flash.geom.Rectangle;
|
||||||
|
import ru.m.puzzlez.core.Part;
|
||||||
|
|
||||||
|
|
||||||
|
class PartMask extends Shape {
|
||||||
|
|
||||||
|
public var rect(default, null):Rectangle;
|
||||||
|
|
||||||
|
public function new(rect:Rectangle, bounds:Bounds) {
|
||||||
|
super();
|
||||||
|
graphics.beginFill(0xff00ff, 1);
|
||||||
|
var path = new ClassicMaskBuilder().build(rect, bounds);
|
||||||
|
graphics.drawPath(path.commands, path.data);
|
||||||
|
graphics.endFill();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/haxe/ru/m/puzzlez/render/mask/SquareMaskBuilder.hx
Normal file
38
src/haxe/ru/m/puzzlez/render/mask/SquareMaskBuilder.hx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package ru.m.puzzlez.render.mask;
|
||||||
|
|
||||||
|
import flash.display.GraphicsPathCommand;
|
||||||
|
import ru.m.puzzlez.core.Part;
|
||||||
|
import ru.m.puzzlez.render.mask.IPartMaskBuilder;
|
||||||
|
|
||||||
|
class SquareMaskBuilder extends BaseMaskBuilder {
|
||||||
|
|
||||||
|
override private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, type:BoundType):Void {
|
||||||
|
var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX);
|
||||||
|
var dy = toY == fromY ? 0 : (toY - fromY) / Math.abs(toY - fromY);
|
||||||
|
var boundLength = Math.max(Math.abs(toX - fromX), Math.abs(toY - fromY));
|
||||||
|
var spikeWidth = boundLength * 0.2;
|
||||||
|
var spikeOffset = (boundLength - spikeWidth) / 2;
|
||||||
|
var spikeDepth = switch type {
|
||||||
|
case NONE: 0;
|
||||||
|
case IN: spikeWidth;
|
||||||
|
case OUT: -spikeWidth;
|
||||||
|
}
|
||||||
|
switch type {
|
||||||
|
case NONE:
|
||||||
|
case IN | OUT:
|
||||||
|
path.commands.push(GraphicsPathCommand.LINE_TO);
|
||||||
|
path.data.push(fromX + spikeOffset * dx);
|
||||||
|
path.data.push(fromY + spikeOffset * dy);
|
||||||
|
path.commands.push(GraphicsPathCommand.LINE_TO);
|
||||||
|
path.data.push(fromX + spikeOffset * dx - spikeDepth * dy);
|
||||||
|
path.data.push(fromY + spikeDepth * dx + spikeOffset * dy);
|
||||||
|
path.commands.push(GraphicsPathCommand.LINE_TO);
|
||||||
|
path.data.push(fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy);
|
||||||
|
path.data.push(fromY + spikeDepth * dx + (spikeOffset + spikeWidth) * dy);
|
||||||
|
path.commands.push(GraphicsPathCommand.LINE_TO);
|
||||||
|
path.data.push(fromX + (spikeOffset + spikeWidth) * dx);
|
||||||
|
path.data.push(fromY + (spikeOffset + spikeWidth) * dy);
|
||||||
|
}
|
||||||
|
super.createBound(path, fromY, fromY, toX, toY, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,11 +34,11 @@ typedef PixabayResponse = {
|
|||||||
render.scale = 0.75;
|
render.scale = 0.75;
|
||||||
scale.position = render.scale - scale.ratio;
|
scale.position = render.scale - scale.ratio;
|
||||||
|
|
||||||
new JsonLoader<PixabayResponse>()
|
/*new JsonLoader<PixabayResponse>()
|
||||||
.GET('https://pixabay.com/api/?key=14915210-5eae157281211e0ad28bc8def&category=nature')
|
.GET('https://pixabay.com/api/?key=14915210-5eae157281211e0ad28bc8def&category=nature')
|
||||||
.then(function(result:PixabayResponse) {
|
.then(function(result:PixabayResponse) {
|
||||||
images.data = images.data.concat([for (item in result.hits) URL(item.largeImageURL)]);
|
images.data = images.data.concat([for (item in result.hits) URL(item.largeImageURL)]);
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private function imageViewFactory(index:Int, image:ImageSource):ImageView {
|
private function imageViewFactory(index:Int, image:ImageSource):ImageView {
|
||||||
|
|||||||
Reference in New Issue
Block a user