Is it possible to animate filter in Fabric.js? - fabricjs

Is it possible to animate the images filter in Fabric.js? Such as a "pixelate" filter.

I solved it in the same way like the demo.
Unfortunately filters aren't able to be animated - they need too much processing time.
Here's my Code:
image = ... //Image, where the filter should be applied
var filter = new fabric.Image.filters.RemoveWhite({
threshold: 0,
distance: 140
});
image.filters.push(filter);
image.applyFilters(canvas.renderAll.bind(canvas));
animate(image,1, 400); //Start the Animation
function animate(image,value, stop){
value += ((stop-value)*0.02); //Change the threshold-value
if (image.filters[0]) {
image.filters[0]['threshold'] = value;
console.log(value);
image.applyFilters(canvas.renderAll.bind(canvas)); //Start creating the new image
if(value<stop-100){
setTimeout(function(){act(image,value,stop);},1);
}
}
}
I know the code isn't the most efficient one, but it works. And you can see that Animating filters consumes too much time.
(I tested it with a 1920x1080px image, maybe you can use it with smaller images)

Here is a updated version for the brightness filter
var brightnessValue = 0.9;
var brightnessFilter = new fabric.Image.filters.Brightness({
brightness: brightnessValue
});
fabricImage.filters.push(brightnessFilter);
fabric.util.requestAnimFrame(function brightnessFilterAnimation() {
brightnessValue = brightnessValue - 0.04;
brightnessFilter.brightness = brightnessValue;
fabricImage.applyFilters();
if (brightnessValue > 0) {
fabric.util.requestAnimFrame(brightnessFilterAnimation);
}
});

Related

phaser.io how to draw over a path

I need to write a game like: https://robowhale.com/html5/drawing-letters/ with phaser.io library. I mean user must follow a path and draw for example letter "A".
basically, need to draw over a path, I checked almost all examples and tutorials, But couldn't find any proper tutorial or algorithm.
any help, link, source code or tutorial can helps me to figure out algorithm and start project.
Usually you will never find the full solution, you will have to merge multiple.
Here ist how I would approach this task (a quick and dirty solution):
Step 1)
Find an Example that solves a part of the problem and work from there
(Based on the example Quadratic Bezier Curve)
Then I :...
I removed the tween
added Mouse Input
split the path in segments
calculate until where the path should be draw
draw path segments
... And slowly adding missing features:
just update path when close enough
just allow move forwards
...
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: {
create: create,
update: update
}
};
var path;
var curve;
var graphics;
var game = new Phaser.Game(config);
var _myMaxPointIndex = 6;
function create() {
graphics = this.add.graphics();
path = { t: 0, vec: new Phaser.Math.Vector2() };
var startPoint = new Phaser.Math.Vector2(100, 500);
var controlPoint1 = new Phaser.Math.Vector2(50, 100);
var endPoint = new Phaser.Math.Vector2(700, 500);
curve = new Phaser.Curves.QuadraticBezier(startPoint, controlPoint1, endPoint);
}
function _myDrawPath(g, points) {
let startPoint = points.shift();
graphics.lineStyle(30, 0x0000ff, 1);
g.beginPath();
g.moveTo(startPoint.x, startPoint.y);
let maxPointsToDraw = _myMaxPointIndex == -1 ? points.length : _myMaxPointIndex + 1;
for (let index = 0; index < maxPointsToDraw; index++) {
const point = points[index];
g.lineTo(point.x, point.y);
}
g.strokePath();
}
function update() {
graphics.clear();
graphics.lineStyle(2, 0x00ff00, 1);
curve.draw(graphics);
// get 20 Point from the Curve (can be more if to jaggy)
let _myPoints = curve.getPoints(20);
_myDrawPath(graphics, _myPoints)
if (this.input.activePointer.isDown) {
// Here I update the Max point that should be draw
let _myMouse = this.input.activePointer.position;
let _myNearestPoint = _myPoints.reduce((p, c, i) => {
let distance = Phaser.Math.Distance.BetweenPoints(_myMouse, c)
if (p.distance == -1 || p.distance > distance) {
p.distance = distance
p.idx = i
}
return p
}, { distance: -1 })
_myMaxPointIndex = _myNearestPoint.idx
}
}
h1 {
font-family:arial
}
#phaser-example{
transform: translate(-20%, -20%) scale(.5);
}
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.min.js"></script>
<h1>Click to calculate path</H1>
<div id="phaser-example"></div>
And with a bit of luck:
While building this solution, I had to "google" for some documentation details, and found this in a Phaser forum, that points to a interesting solution with a working CodePen, with a more complex full working example (Just adding the codepen link if the forum entry gets deleted).

PhaserJS: After Rotation of camera dragging a Sprite gives strange coords

Basically the problem is that after you rotate the camera, the points that are given as arguments in the callback for dragging are not what I expected. I'm guessing I have to Rotate the given points also but I just couldn't.
Can Someone explain what is going on, is this some kind of bug or what should I do in order the sprite to follow the mouse cursor?
Easiest way to explain the problem is to reproduce it:
1) Go to Phaser Example Runner
2) Copy- Paste this code:
var config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
scene: {
preload: preload,
create: create
}
};
var game = new Phaser.Game(config);
function preload ()
{
this.load.image('eye', 'assets/pics/lance-overdose-loader-eye.png');
}
function create ()
{
var image = this.add.sprite(200, 300, 'eye').setInteractive();
this.cameras.main.setRotation(Math.PI);
image.on('pointerover', function () {
this.setTint(0x00ff00);
});
image.on('pointerout', function () {
this.clearTint();
});
this.input.setDraggable(image);
this.input.on('dragstart', function (pointer, gameObject) {
gameObject.setTint(0xff0000);
});
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
console.log(`x: ${dragX}, y: ${dragY}`);
gameObject.x = dragX;
gameObject.y = dragY;
});
this.input.on('dragend', function (pointer, gameObject) {
gameObject.clearTint();
});
}
3) Open the console, drag around the Eye and look at what coordinates are given.
4) If you remove line 24 (the rotation of the camera) Everything works as expected.
(The example is taken from Phaser 3 Official examples and a bit changed for the bug)
According to Phaser's API Documentation on the setRotation() method, the rotation given in radians applies to everything rendered by the camera. Unfortunately, your pointer isn't rendered by the camera so it doesn't get the same rotated coordinates. Not sure if this is a bug with the library or just a poorly documented exception, but I believe there is a workaround.
Create 2 variables to hold an initial position and a final position:
var image = this.add.sprite(200, 300, 'eye').setInteractive();
var initial = [];
var final = [];
Populate the initial position in your .on('dragstart') method:
this.input.on('dragstart', function (pointer, gameObject) {
initial = [
gameObject.x,
gameObject.y,
pointer.x,
pointer.y
];
gameObject.setTint(0xff0000);
});
Then, populate the final variable in your .on('drag') method:
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
final = [
gameObject.x, // not necessary but keeping for variable shape consistency
gameObject.y, // not necessary but keeping for variable shape consistency
pointer.x,
pointer.y
];
gameObject.x = initial[0] + (initial[2] - final[2]);
gameObject.y = initial[1] + (initial[3] - final[3]);
});
All we're doing here is keeping track of the change in pointer position and mimicking that change in our gameObject.

Draw Threejs TextGeometry along the path

I have some model and want cover it with text.
I've rendered and bended TextGeometry but it is difficult to combine these two meshes.
(Аnd yes, I've tried the dynamic textures, this way prohibits the use of own fonts)
scrinshot of existing model
Perhaps there is another way to draw the text along the path?
As you want to cover it with text, why not to use textures.
You can set it from a picture with THREE.TextureLoader() or you can draw your own on a canvas and apply it to a texture with var texture = new THREE.Texture(canvas);
For exmaple:
var texture = new THREE.Texture(canvas);
texture.repeat.set(5, 1);
texture.needsUpdate = true;
See the jsfiddle example.
There you can uncomment those lines
//texture.wrapS = THREE.RepeatWrapping;
//texture.wrapT = THREE.RepeatWrapping;
and see, how the result will change.
UPD. I've updated the fiddle. Used the trick with WebFontLoader (from this SO)
WebFontConfig = {
google: {families: ['Monoton']},
active: function() {
init();
animate();
},
};
(function(){
var wf = document.createElement("script");
wf.src = 'https://cdnjs.cloudflare.com/ajax/libs/webfont/1.6.26/webfontloader.js';
wf.async = 'true';
document.head.appendChild(wf);
})();

corrective scaling using Raphael free transform plugin

I'm using Raphael Free Transform plugin to enable scaling, dragging and rotating.
In this particular scenario I want to devote one handle for resizing and another one for rotating, hence scale option is set only on axis x. I want to compensate scaling on y axis by correcting it on function callback to avoid 'image' distortions.
I would like to enable user to re-size raphael set using one handle and rotate raphael set using another one. Also, I would like to persist all transformation caused by scaling so it is not lost once user attempt o drag the objects.
var ft = paper.freeTransform(tmp, { scale: ['axisX'], rotate: ['axisY'] }, cbFreeTransform);
function cbFreeTransform(s, e) {
if (e.toString() == 'scale end') {
for (var i = 0, l = tmp.length; i < l; i++) {
var itm = tmp[i];
itm.scale(1, s.attrs.scale.x);
}
}
}
Here is fiddle: jsFiddle
Any help appreciated .
Found the solution in doing following:
On 'Scale End' event I've assigned x scale factor to y scale factor and call free transform apply method. That seems to work.
var ft = paper.freeTransform(tmp, { scale: ['axisX'], rotate: ['axisY'] }, cbFreeTransform);
function cbFreeTransform(s, e) {
if (e.toString() == 'scale end') {
ft.attrs.scale.y = s.attrs.scale.x;
ft.apply();
}
}

RaphaelJS scale issue

Can someone help me on this? I tried to shrink the size of the svg to half of its original size.
Here is the JSfiddle link
http://jsfiddle.net/wildleaf/ntzf3/
It runs fine with the original but if I uncomment the last line, the size is reduced to half but shape is changed.
You need to add transformation, not overwrite it.
See updated fiddle http://jsfiddle.net/ntzf3/1/
Code
...
var rsr = Raphael("canvas", 800, 400);
var elements = rsr.set();
for (var room in floorData) {
var r = floorData[room];
var ele = rsr.add([r]);
elements.push(ele);
if (r.data) {
ele.data('room', r.data['room']);
}
}
elements.forEach(function (el) {
var e = el[0];
e.transform(e.transform() + "s0.5,0.5,0,0");
});
Figured it out. It is overwriting the transform information in the original graph. I changed the last line to elements.transform("...s0.5,0.5,0,0") then everything works.

Resources