In famo.us, rotating an ImageSurface is causing flickering - rotation

I'm trying to rotate an image along it's Y axis, with the origin set to center of the image. But, the rotate animation is resulting in flickering. I tried to do the same in famo.us tutorials and could see the same there as well. Following is the modified code in the tutorial.
The tutorial link: http://famo.us/university/famous-101/animating/2/
Visit this page and replace the code in it with the following one.
The change in brief is, I'm using ImageSurface instead of Surface and applied rotateY.
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var ImageSurface = require('famous/surfaces/ImageSurface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var mainContext = Engine.createContext();
var imgSurface = new ImageSurface({
content: 'http://www.wpclipart.com/recreation/games/card_deck/cards_symbols/playing_card_symbols.png',
size: [200, 200]
});
var surface = new Surface({
size: [100, 100],
properties: {
color: 'white',
textAlign: 'center',
backgroundColor: '#FA5C4F'
}
});
var stateModifier = new StateModifier({origin: [0.5, 0.5]});
mainContext.add(stateModifier).add(imgSurface);
// stateModifier.setTransform(
// Transform.translate(50, 10, 0),
// { duration : 1000, curve: 'easeInOut' }
// );
stateModifier.setTransform(
Transform.rotateY(-Math.PI/4),
{ duration : 5000, curve: 'easeInOut' }
);
Any help would be appreciated.

Do you mean the flickering of the lines at the left and right?
This has to do with how the browser/GPU applies the 3d perspective transform on the image, but has nothing to do with famo.us really.
The image that you are using has a size of 505 x 499 pixels. Try resizing it using a graphics program to 200x200 and see whether you get better results.

The problem is that the rotating element is too close to the background and intersects it. If you position the rotating surface far enough in the z axis, the flickering, surely disappear.
Try something like this:
mainContext.add(new Modifier({transform: Transform.translate(0,0,100)})).add(stateModifier).add(imgSurface);
P.D: Sorry for my bad English...

Related

Open Layers: How to display svg icon for a feature with certain offset from the center

I have to display multiple features on the map using OpenLayers. Each feature must be represented by 2 images (2 SVG icons). One of this icons must be anchored at the features coordinates but the second must be shifted with a fixed amount of pixels. The additional problem is that shifted one must be also rotated and the center of rotation must be the center of icon and not a center of feature.
As an example I can say: there is an Icon of vehicle that is always oriented to the nord and there is another which shows direction that is rotated. The direction one must be always shown at the top of vehicle
I've tried to use various offsets and anchors but I was not able to precisely position the second icon
The code is done with ExtJS but I hope is readable:
So I'm using function fot set a style for a ImageVector:
me.imageVectorSource = new ol.source.ImageVector({
source: new ol.source.Vector({
features: me.features
}),
style: Ext.bind(me.pointStyleFunction,me)
});
And the function looks like:
pointStyleFunction: function(feature, resolution) {
var currentStyles =
[
new ol.style.Style({
//first icon
image: new ol.style.Icon({
src: 'resources/img/vehicle.test.svg',
scale: sc,
}),
//text shown below
text: new ol.style.Text({
text: textToShow,
scale:sc
fill: new ol.style.Fill({
color: 'yellow'
}),
offsetY: textOffset,
stroke: new ol.style.Stroke({
color: 'black',
width: 4
}),
})
}),
//second icon that should be rotated
var rpIconStyle = new ol.style.Style({
image: new ol.style.Icon({
src: 'resources/img/rp.svg',
scale: sc,
rotation: rot
}),
});
];
}
Now if second icon is rotated it is rotated around the center of the feature and not at the center of itself. I thought about adding new geometry to the second style (Point) but in such case I cannot specify offset (in pixels) of the geometry from the original feature's center. I can only use coordinates but have no idea if it is possible to convert them to pixels. In fact the expected solution would be something like in case of text property of style where offsetX and offsetY can be specified.
Could you please suggest me some solution?
You could use anchor but you would need to know the size of the scaled image. Using a second geometry as you suggested is easy, resolution is the meters per pixel, just multiply it by the number of pixels you want to offset by.
if (feature.getGeometry().getType() == 'Point') {
var coordinate = feature.getGeometry().getCoordinates();
var rpIconStyle = new ol.style.Style({
geometry: new ol.geom.Point([coordinate[0] + 50*resolution, coordinate[1] + 50*resolution]),
image: new ol.style.Icon({
src: 'resources/img/rp.svg',
scale: sc,
rotation: rot
}),
});
}

Change Extrude Amount textGeometry Three.js

I've added text to my scene using the code from https://threejs.org/docs/#api/geometries/TextGeometry
I cannot figure out how to change the extrude depth, which is much "thicker" than I would like. Here is the exact code I am using:
var loader = new THREE.FontLoader();
loader.load( 'fonts/font.json', function ( font ) {
var textGeometry = new THREE.TextGeometry( 'WELCOME', {
font: font,
size: 4,
height: 8,
amount: 8,//attempt to change the depth but doesn't work
} );
Is it possible to change the extrude amount for a text geometry?
Applying height and amount at the same time does not work. amount is an option for ExtrudeGeometry whereas height is intended for TextGeometry.
TextGeometry uses internally ExtrudeGeometry for geometry generation. In this context, height is mapped to amount.
three.js R92

Animate point with paper.js

I’d like to rebuild this animation http://imgur.com/l5Vhswe in paper.js.
I already tried SVG animations (http://codepen.io/magglomag/pen/jrVwzy) but despite from the fact that they’ll be deprecated soon I was not able to move the two points asynchronously.
What I have so far is the shape and I know that I can animate with the onFrame event handler. But I have no clue how to say that the point should animate between the coordinates [43,168.7] and [43,35.3].
http://codepen.io/magglomag/pen/yaVXrr
var firstSegment = new Segment({
point: [109,3.7]
});
var secondSegment = new Segment({
point: [43,168.7]
});
var thirdSegment = new Segment({
point: [109,202.2]
});
var path = new Path({
segments: [firstSegment, secondSegment, thirdSegment],
fillColor: '#2dfd9a',
closed: true
});
secondSegment.onFrame = function(event) {
this.point = [43,35.3]
}
The error you are making is that you are trying to bind an handler to segment.onFrame event.
But only item.onFrame and view.onFrame are available.
In PaperScript context, you can even use a global onframe named function as a convenient way to animate things.
Here is a simple example demonstrating how a path segment can be animated.
// create a triangle
var triangle = new Path.RegularPolygon({
center: view.center,
sides: 3,
radius: 50,
fillColor: 'orange'
});
// store initial first point position
var initialPoint = triangle.firstSegment.point.clone();
// on frame
function onFrame(event) {
// use sine function as a convenient way to demonstrate animation
var newPoint = initialPoint + Math.sin(event.count * 0.05) * 30;
// update first point
triangle.firstSegment.point = newPoint;
}

KineticJS rotating/animating text

I have this fiddle where I have text arranged in a circle, I would like now to animate it and rotate the text in a clockwise/counter clockwise motion.
Every animation demo I have seen uses a container as the starting point however all the examples i could find about manipulating text in a circular arrangement have all started with the element. I have tried 100's of variations trying to get this working but I am either missing something or it's not possible with the construction i have used thus far.
Here is the fiddle for the circular text I have so far:
http://jsfiddle.net/jamesburt/Sa2G8/
<canvas id="canvas1" width="500" height="500"></canvas>
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
Where as the animation examples start off with:
<div id="container"></div>
var stage = new Kinetic.Stage({container: 'container'});
I'm open to any ideas / rewrites needed as ultimately my goal is an animated text circle.
Also if this is easily accomplished in an alternative to KineticJS I'd be interested in trying that out.
Here is a demo I made using KineticJS: http://jsfiddle.net/Moonseeker/Xf7hp/
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 500
});
var layer = new Kinetic.Layer();
var myText = "My text in a circle. ";
var centerCoords = {x:250, y:250};
for(var i=0;i<myText.length;i++){
var rotation = i*360/myText.length;
var oneChar = new Kinetic.Text({
x: centerCoords.x,
y: centerCoords.y,
text: myText[i],
fontSize: 30,
fontFamily: 'Calibri',
fill: 'green',
offset: {x:0, y:100},
rotationDeg: rotation
});
layer.add(oneChar);
}
// add the layer to the stage
stage.add(layer);
var angularSpeed = Math.PI / 2;
var anim = new Kinetic.Animation(function(frame){
var angleDiff = frame.timeDiff * angularSpeed / 1000;
for(var i=0;i<layer.children.length;i++){
layer.children[i].rotate(angleDiff);
};
}, layer);
anim.start();
You can rotate at every direction or speed you wish, you can change the style of the circle.
You should be able to use layer.find('Text').each() instead of the for-loop for looping through the text to rotate but the KineticJS library at jsfiddle seems outdated as it doesn't know the find method.
One efficient way:
Render your text-around-a-circle on an offscreen canvas.
Save that offscreen canvas as an image using .toDataURL
Create a Kinetic.Image from that offscreen image.
You can then efficiently rotate/animate the Kinetic.Image as you need.

Fixed floating shape on kinetic.js stage

I have tried to find a solution on how to implement fixed score table to visible stage (canvas) area by using kineticjs library layers and stages. The basic idea is that shape layer can be scrolled and stage is wider than the visible browser area but the score table should be all the time fixed to certain position on the visible area like in many casual games.
What would be the best approach on creating this kind of fixed always visible shapes to stage/canvas? Is there a way to refer to visible area xy position?
Your best bet for making a fixed position group is either to use a second layer on the stage or to create two groups for your objects - one that remains in place and another that can be moved. I'd go with the dual-layer approach as this allows you to redraw the layers separately so that when one has updated information, you don't need to redraw the other.
cvsObj.page = new Kinetic.Layer();
cvsObj.dynamic = new Kinetic.Layer();
cvsObj.stage.add(cvsObj.page);
cvsObj.stage.add(cvsObj.dynamic);
I took the two layer approach but actually my challenge was how to implement 'page' static behavior. I figured out that as it seems that Kinetic layers/stages do not offer methods for this I need to use other means to make 'page' layer on top of viewable area. I used jquery scrollTop() and scrollLeft()functions for this. And layer method .setAbsolutePosition() is used to update position for whole layer. Here pageLayer position is updated and dynamicLayer not so naming might be bit confusing but reflects what you see on browser.
Here is a simple example what does what I was looking for. Now the green rectangle moves when you scroll stage and the red rectangle and the x/y position counter stay on visible area. I attach this solution here with tutorial type of content as it might be useful.
<script>
window.onload = function() {
var stage = new Kinetic.Stage({
container: 'container',
width: 1600, height: 1600
});
var layerDynamic = new Kinetic.Layer();
var layerPage = new Kinetic.Layer();
var rectGreen = new Kinetic.Rect({
x: 239, y: 75, width: 100, height: 50, fill: 'green'
});
var rectRed = new Kinetic.Rect({
x: 100, y: 75, width: 100, height: 50, fill: 'red'
});
var simpleText = new Kinetic.Text({
x: 1, y: 1, text: "Init", textFill: "black"
});
layerDynamic.add(rectGreen);
layerPage.add(rectRed);
layerPage.add(simpleText);
$(document).scroll(function(e) {
var visibleXTop = $(this).scrollTop();
var visibleYTop = $(this).scrollLeft();
simpleText.setAttrs({text: visibleXTop + ' ' + visibleYTop});
layerPage.setAbsolutePosition(visibleYTop , visibleXTop);
layerPage.draw();
});
stage.add(layerDynamic);
stage.add(layerPage);
};
</script>

Resources