[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;
|
||||
|
||||
import flash.geom.Point;
|
||||
import flash.display.Bitmap;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.PixelSnapping;
|
||||
import flash.display.Sprite;
|
||||
import flash.geom.Point;
|
||||
|
||||
class PartView extends Sprite {
|
||||
|
||||
@@ -24,8 +25,7 @@ class PartView extends Sprite {
|
||||
super();
|
||||
this.id = id;
|
||||
this.size = size;
|
||||
bitmap = new Bitmap();
|
||||
bitmap.bitmapData = image;
|
||||
bitmap = new Bitmap(image, PixelSnapping.ALWAYS, true);
|
||||
addChild(bitmap);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import openfl.Assets;
|
||||
import promhx.Promise;
|
||||
import ru.m.puzzlez.core.ImageSource;
|
||||
import ru.m.puzzlez.core.Part;
|
||||
import ru.m.puzzlez.render.mask.PartMask;
|
||||
|
||||
class RenderUtil {
|
||||
|
||||
@@ -39,7 +40,7 @@ class RenderUtil {
|
||||
var canvas:Shape = new Shape();
|
||||
canvas.cacheAsBitmap = true;
|
||||
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.endFill();
|
||||
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;
|
||||
scale.position = render.scale - scale.ratio;
|
||||
|
||||
new JsonLoader<PixabayResponse>()
|
||||
/*new JsonLoader<PixabayResponse>()
|
||||
.GET('https://pixabay.com/api/?key=14915210-5eae157281211e0ad28bc8def&category=nature')
|
||||
.then(function(result:PixabayResponse) {
|
||||
images.data = images.data.concat([for (item in result.hits) URL(item.largeImageURL)]);
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
private function imageViewFactory(index:Int, image:ImageSource):ImageView {
|
||||
|
||||
Reference in New Issue
Block a user