EaselJS line draw with unnecessary multiple dots issues - createjs

While drawing a line on canvas, it creates multiple dots within the line. I am using easelJS for canvas drawing. Please refer the attached screenshot.
Code for line draw is as below.
Line with multiple dots
scope.init = function(){
stage = new createjs.Stage(element[0].id);
stage.enableDOMEvents(true);
createjs.Touch.enable(stage);
shellWrapper = new createjs.Container();
shellWrapper.id = mainContainerId;
shellWrapper.hitArea = new createjs.Shape(new createjs.Graphics().f('#000').dr(0,0,cacheWidth,cacheHeight));
shellWrapper.cache(0,0,cacheWidth,cacheHeight); // Cache it.
stage.addChild(shellWrapper);
drawing = new createjs.Shape();
shellWrapper.addChild(drawing);
stage.update();
}
scope.mouseDown = function(event) {
oldX = event.stageX;
oldY = event.stageY;
shellWrapper.addEventListener('pressmove', function(evt){
drawing.graphics.beginStroke(color)
.setStrokeStyle(size, 'round')
.moveTo(oldX, oldY)
.lineTo(evt.stageX, evt.stageY);
oldX = evt.stageX;
oldY = evt.stageY;
shellWrapper.updateCache(erase?'destination-out':'source-over');
drawing.graphics.clear();
stage.update();
});
};

This happens because a single line has its limits rounded, so it actually look like this:
The rounded edge goes a little bit (depending on stroke width) out of the line boundary so it gets over the past line drawn. This line overlay causes your drawing to look like it has small circles, but it does not, and thats because you're using a semi transparent color on the stroke.
To solve the issue, make the stroke color opaque and add transparency to the whole drawing by using myDisplayObj.alpha = 0.5;
This way individual lines will be fully opaque in relation to each other but they will be semi transparent relative to other display objects in the scene.

Related

Camera position cause objects to disappear

I'm developing an app with blazor client-side and I need to render a 3D scene.
I have an issue and I guess it is material-related.
I have a composition of parallelepipeds where one of them is fully opaque and the others are transparent.
Depending on the camera angle, the transparent ones completely disappear:
Example where everything is visible:
Example with 2 missing:
Example with all missing:
Code for transparent parallelepipeds
var geometry = new THREE.CubeGeometry(item.xDimension * _scene.normalizer, item.yDimension * _scene.normalizer, item.zDimension * _scene.normalizer);
var material = new THREE.MeshBasicMaterial();
var box = new THREE.Mesh(geometry, material);
box.material.color = new THREE.Color("gray");
box.material.opacity = 0.8;
box.material.transparent = true;
Code for the camera:
var camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 100);
camera.position.set(1.3, 1.3, 1.3);
camera.lookAt(0, 0, 0);
I'm using OrbitControls and every object size is between 0 an 1 (_scene.normalizer is for that purpose)
Do you know why this is happening?
Edit:
I found it being a material depth function issue. Do you know which should I use?
Thanks,
Transparency is tricky with WebGL because a transparent object writes to the depthmap, and then the renderer assumes that subsequent objects behind it are occluded so it skips drawing them. You could avoid this by playing with the material's .depthTest and .depthWrite attributes (see the docs):
box.material.color = new THREE.Color("gray");
box.material.opacity = 0.8;
box.material.transparent = true;
box.material.depthWrite = false;

flash cc createjs hittest works without hit

the rect should be alpha=0.1 once the circle touches the rect . but if statement not working . it becomes 0.1 opacity without hitting
/* js
var circle = new lib.mycircle();
stage.addChild(circle);
var rect = new lib.myrect();
stage.addChild(rect);
rect.x=200;
rect.y=300;
circle.addEventListener('mousedown', downF);
function downF(e) {
stage.addEventListener('stagemousemove', moveF);
stage.addEventListener('stagemouseup', upF);
};
function upF(e) {
stage.removeAllEventListeners();
}
function moveF(e) {
circle.x = stage.mouseX;
circle.y = stage.mouseY;
}
if(circle.hitTest(rect))
{
rect.alpha = 0.1;
}
stage.update();
*/
The way you have used hitTest is incorrect. The hitTest method does not check object to object. It takes an x and y coordinate, and determines if that point in its own coordinate system has a filled pixel.
I modified your example to make it more correct, though it doesn't actually do what you are expecting:
circle.addEventListener('pressmove', moveF);
function moveF(e) {
circle.x = stage.mouseX;
circle.y = stage.mouseY;
if (rect.hitTest(circle.x, circle.y)) {
rect.alpha = 0.1;
} else {
rect.alpha = 1;
}
stage.update();
}
Key points:
Reintroduced the pressmove. It works fine.
Moved the circle update above the hitTest check. Otherwise you are checking where it was last time
Moved the stage update to last. It should be the last thing you update. Note however that you can remove it completely, because you have a Ticker listener on the stage in your HTML file, which constantly updates the stage.
Added the else statement to turn the alpha back to 1 if the hitTest fails.
Then, the most important point is that I changed the hitTest to be on the rectangle instead. This essentially says: "Is there a filled pixel at the supplied x and y position inside the rectangle?" Since the rectangle bounds are -49.4, -37.9, 99, 76, this will be true when the circle's coordinates are within those ranges - which is just when it is at the top left of the canvas. If you replace your code with mine, you can see this behaviour.
So, to get it working more like you want, you can do a few things.
Transform your coordinates. Use localToGlobal, or just cheat and use localToLocal. This takes [0,0] in the circle, and converts that coordinate to the rectangle's coordinate space.
Example:
var p = rect.localToLocal(0, 0, circle);
if (rect.hitTest(p.x, p.y)) {
rect.alpha = 0.1;
} else {
rect.alpha = 1;
}
Don't use hitTest. Use getObjectsUnderPoint, pass the circle's x/y coordinate, and check if the rectangle is in the returned list.
Hope that helps. As I mentioned in a comment above, you can not do full shape collision, just point collision (a single point on an object).

CreateJs Drawing with alpha

I implemented a little drawing function into my app with CreateJS like so:
var currentPosition = this.posOnStage(event);
var drawing = container.getChildByName('drawing');
drawing.graphics.ss(this.brushSize, "round").s(this.brushColor);
drawing.graphics.mt(this._lastMousePosition.x, this._lastMousePosition.y);
drawing.graphics.lt(currentPosition.x, currentPosition.y);
drawing.alpha = this.brushAlpha;
container.updateCache(this.enableErasing ? "destination-out" : "source-over");
drawing.graphics.clear();
this._lastMousePosition = this.posOnStage(event);
As you can see, the alpha value of this drawing can change. Sadly you can draw over a point you once did draw, so when you draw over a point multiple times the alpha effect will go away. Any idea how to solve this ?
Thanks :)
EDIT:
I tried it like gskinner and Lanny 7 proposed, but it didn't work. I attached a image so you can see the problem.
As suggested by Lanny, apply the alpha to the actual stroke, not to the Shape. You can use Graphics methods to help with this.
For example:
// set the brush color to red with the current brush alpha:
this.brushColor = createjs.Graphics.getRGB(255, 0, 0, this.brushAlpha);

Adding Image to Xaml not rendering with given margin

for (int i = 0; i < length; i++)
{
Image img1 ;
img1 = null;
img1= new Image();
img1.Height = snhei;
img1.Width = snwid;
BitmapImage BitImg = new BitmapImage(new Uri("/Assets/midtail.png", UriKind.Relative));`
img1.VerticalAlignment = VerticalAlignment.Top;
img1.HorizontalAlignment = HorizontalAlignment.Left;
img1.Source = BitImg;
img1.Stretch = Stretch.Fill;
img1.Name = "mid" + i.ToString() ;
img1.Margin = new Thickness(image_width*i, 0, 0, 0);
stackp.Children.Add(img1);
}
after running i get first image at 0,0
then it is render the one image_width below
The problem is your container. The StackPanel will, as it name indicates, try to stack the images. Then you apply the margin, moving the picture farther away.
You have two solutions, depending on what you want:
If you just want the images to be displayed side by side, set the Orientation property of your StackPanel to Horizontal. Then, remove your line of code that sets the margin, since the positioning is automatically handled by the StackPanel
If you still want to position the pictures manually, then you have to use another type of container. Replace your StackPanel by a Canvas or a Grid.

DoubleAnimation of Width does not shrink

I am doing DoubleAnimation of the Width property of a Canvas. I want to shrink the canvas to 1/5 th of the size.
var widthAnimation = new DoubleAnimation();
widthAnimation.Duration = new TimeSpan(0,0,1);
StoryBoard.SetTarget(widthAnimation, Canvas1);
StoryBoard.SetTargetProperty(widthAnimation, new PropertyPath("Width"));
widthAnimation.From = Canvas1.Width;
widthAnimation.To = Canvas1.Width * .2;
StoryBoard stb = new StoryBoard();
stb.Children.Add(widthAnimation);
stb.Begin();
Somehow, the above animation does not shrink the size to 1/5th. Instead, it enlarges the canvas. Any clues why the animation is doing something funny?
The canvas was wrapped in a viewbox. The Viewbox size was fixed, while the canvas within it shrinked. The text expanded. Not sure why. But, I fixed the problem by applying the animation to the Viewbox rather than the Canvas. And it works all fine now.