Fabricjs matrix multiply not working when using `.rotate` - javascript

Following the docs around matrix transformations here: http://fabricjs.com/using-transformations
I replicated their demo at the bottom but instead of the new matrix being set to the minions on an event I am programmatically calling .rotate
The minion rotates correctly but it's position is off by a bit even with calling setCoords
What I expect to happen is that the blue minion stays in the same position relative to the red boss as it rotates but instead it moves as it rotates
Codesandbox: https://codesandbox.io/s/sharp-brook-st24pb?file=/src/index.js:812-820

Related

Why is this.stop() changing the z-index I set with setChildIndex() in Adobe Animate?

I've been having difficulty getting the expected results with setChildIndex().
In this example I have 2 MovieClip instances named redDot and yellowDot, and a black square Shape. I would expect it to place yellowDot on bottom, then square, then redDot.
//make black rectangle shape
var square = new createjs.Shape(new createjs.Graphics().f("#000000").dr(100,100,100,100));
this.addChild(square);
this.setChildIndex(this.yellowDot, 0); //set z-index towards background
this.setChildIndex(square,1);
this.setChildIndex(this.redDot, 2);//towards foreground
Instead I get redDot, yellowDot, then square. Adding this.stop() to the end seems to change it back to the expected order. It's not clear to me what is causing this discrepancy. Looping is disabled in the publish settings. Am I misunderstanding how this function and the Animate timeline work?
I wonder if the stage is not being updated? What happens if you use stage.update() at the end of your code. (or however you update the stage in an animate script).
I believe calling this.stop() is re-rendering the initial state of the clip, which uses the original z-index definition. Probably makes sense to call it before you change the contents programmatically.

How to make canvas invisible to eye but not to mousemove event?

I have some colored lines in a canvas which I scan using a mousemove event, which returns the line's hex color code.
Is there anyway I could make this canvas invisible to the eye, but when the pointer goes over the canvas, still returns the correct color code?
I've tried setting the context's globalAlpha to transparent or near transparent (0, 0.1...) with mixed results in the following fiddle:
In Firefox, the collected hex returns an altered color due to transparency,
In Chrome, it returns the correct color regardless of transparency (this is actually the behavior I want).
And oddly, in my original code, even in Chrome, canvas lines with globalAlpha=0 no longer return their original color.
Can someone kindly explain what the expected behavior for globalAlpha is? More importantly, is there another way to make a canvas invisible to the eye but which still allows collecting the colors with a mouse event? Any help appreciated!
Set CSS property opacity to 0.
When you apply the property to your canvas like
#examplecanvas {
opacity: 0;
}
It will vanish from the screen but still detect color when you mouse over it (or click it).

Trailing fade to complete black with PIXI.js and WebGLRenderer

I have application made using PIXI.js and it uses a WebGLRenderer.
I'm preserving the drawing buffer and not clearing before render:
{ preserveDrawingBuffer: true, clearBeforeRender: false }
This allows me to create trails as objects move around.
I want the trails to fade out over time, so I apply a transparent black rectangle on top over every rendering. This works, but the fade out eventually rounds off to gray. I want a complete fade to black.
I've tried using a ColorMatrixFilter filter with a lowered brightness on my root container, hoping it would cause a fade effect. It didn't cause any fade effect, instead just causing everything to be slightly darker. If that had worked, then a custom filter could help to do the job.
How can I get a slow gradual fade to complete black for the trails of my rendered objects?
EDIT: Here are a few examples of what I've tried:
// `this` being my app object.
this.fadeGraphics = new PIXI.Graphics()
this.root.addChild(this.fadeGraphics)
// Blend Mode
this.fadeGraphics.blendMode = PIXI.BLEND_MODES.MULTIPLY
this.fadeGraphics.beginFill(0xf0f0f0)
this.fadeGraphics.drawRect(0, 0, this.screenWidth, this.screenHeight)
this.fadeGraphics.endFill()
// Transparent black rectangle.
this.fadeGraphics.beginFill(0x000000, .05)
this.fadeGraphics.drawRect(0, 0, this.screenWidth, this.screenHeight)
this.fadeGraphics.endFill()
Both these methods leave me with a gray trail, the trail goes away if my values are strong enough. Though, I want a very long-term trail so I have to use small values, and possibly also apply them every nth frame.
I think a SUBTRACT blend mode might be able to do what I need.
Unfortunately it doesn't seem available in Pixi.js.
I eventually figured out that fading to white works wonderfully.
Thus, one solution is to fade to white, then invert color, and rotate hue 180 degrees.
You can do this with a CSS filter on your canvas, though it doesn't work in all browsers, has a performance hit, and all your color intensities get inverted.

Getting CSS left and top when div is rotated

I'm trying to get the style.left and style.top of a rectangular div, after it has been rotated using style.transform=rotate(90deg).
I understand how the div is being rotated, with it being rotated around a 'transform point'. And I also understand that a div could be rotated by 45 degrees, so giving the new top/left of that would be awkward (In effect giving the bounding box left/top).
But back to the original question, rotating the rectangular div by 90 degrees, is there a way to get the 'new' left/top?
The reason I need this, is for a project im working on to upload images, allow the user to zoom, rotate etc, but currently having to do it with PHP to keep all the dimensions correct for the final image (Which is obviously bad, because I'm having to keep loading a new image once PHP has done the rotating/zooming etc)
I've also made a little jsfiddle showing that the top/left position doesn't change when it is rotated
Okay, thanks to the comment left above, I managed to throw together an answer.
Basically using:
newleft = parseInt(div.style.top) + Math.cos(90) * parseInt(div.style.height);
newtop = parseInt(div.style.left) + Math.sin(90) * parseInt(div.style.height);
after the div had been rotated.
I've updated my jsfiddle aswell, because the one in the comment above uses jQuery, but this way uses only javascript.

Spot the ball game, zooming problems, jQuery

I am trying to create a spot the ball game, so it will (eventually) be an image of a player kicking a ball but the ball has been removed and the player needs to click where the ball should be.
The first version went well and works.
http://enjoythespace.com/sites/game/test.html
But what I need to add is some sort of zooming so you can see more accurately where you are clicking. I been playing around and have come up with this
http://enjoythespace.com/sites/v2/demo.html
But once you click it looks great when zoomed in but when you go back to the image its way off.
I think its todo with how the image is setup, the #webpage is half the original size of the image and the #retina uses the full size of the image.
Any help?
The first problem is that you aren't setting the retina backgroundPosition correctly.
This code works (I added a zoom variable to make it clear how changing the zoom would change the calculation, but it would need other changes too):
/* Moving the retina div with the mouse
(and scrolling the background) */
zoom = 2.0;
retina.css({
left : left - sizes.retina.width/2,
top : top - sizes.retina.height/2,
backgroundPosition : ""+(-zoom*left+sizes.retina.width/2)+'px '+(-zoom*top+sizes.retina.height/2)+'px'
});
Test this by checking that all four corners are seen correctly in the retina, i.e. when you're over the corner of the main image, the corner should be in the center of the retina circle.
The second problem is if you resize the browser the position calculations are out because the offset variable isn't updated for the new size. A simple way to do this is to put this as the first line of webpage.mousemove() so the offsets are updated every time:
var offset = { left: webpage.offset().left, top: webpage.offset().top };
It looks like you are passing the top/left position click point of the zoomed image to highlight where you have clicked. What you will need to do is alter your top/left position based on whether the fisheye is over the image or not.
Does the un-zoomed image have to be part of the news page or can it be a standalone image?
If it can be standalone then the solution should be quite simple. If the zoomed in image is twice the size of the unzoomed one then you can just set the top/left values of the highlight to half the value of the zoomed, when looking at the unzoomed.
Jquery position will allow you to accurately get the position.
jQuery Position()

Categories

Resources