I find this website -> http://bit.ly/1FCtQSQ and he has this animation scroll, which I am not interested, however in the middle of the scroll animation, a text snake animation appears. I want very badly to know how I can do this, just to learn.
I researched all plugins that curve texts, such as:
Arctext.js
CircleType
This one
Also, i tried 'still' the code from http://bit.ly/1FCtQSQ, but is minified, i know this guys are using the timelinemax, which uses the canvas, i tried to copy the code, but didn't work, as you can see here in the bottom of this question.
So i came here as the last resource.
Could someone give me an explanation with a working example, or maybe a plugin which i can study the code?
I know this is not the best way to find a answer to my question, but i don't have money to pay for codementor, hackhands, airpair or something like this.
Thanks!
Pen: http://codepen.io/anon/pen/GJjjxG
Code that i copy:
<h1 class="snake">Animate this like a snake!</h1>
var animation = new TimelineMax({
paused: !0,
ease: Linear.easeNone
});
var T = 0;
var f = 30;
animation.add(
TweenMax.to(e(".snake").parent(), f, {
left: -5e3
}), T);
Thanks.
The KonvaJS (formerly KineticJS) canvas library has some nice text-along-path code with a liberal MIT license:
https://github.com/konvajs/konva/blob/f6e2cf19a30dec2f94f50152f20c35988b1bf99e/src/plugins/TextPath.js
The KonvaJS TextPath code works like this:
Start with a path made up of curves and lines defined using the same syntax that SVG uses to define path.
Calculate waypoints along that path.
Fit characters one-by-one along the path using the calculated waypoints.
Use transformations to position the characters properly. (using context.translate & context.rotate to match the letter to the angle of the path / curve.)
You can cause the text to animate along the curve by beginning the text further & further beyond the first waypoint on the curve.
Example code using the KonvaJS libarary:
var stage = new Konva.Stage({
container: 'container',
width: 1000,
height: 1000
});
var layer = new Konva.Layer();
// add the layer to the stage
stage.add(layer);
var textpath = new Konva.TextPath({
x: 0,
y: 50,
fill: '#333',
fontSize: 16,
fontFamily: 'Arial',
text: 'Now is the time for all good men to come to the aid of their party -- An phrase from an old touch-typing test.',
data: 'M 100 200 C 200 100 300 0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100'
});
layer.add(textpath);
layer.draw();
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
<script src="https://cdn.rawgit.com/konvajs/konva/0.9.0/konva.min.js"></script>
<div id="container"></div>
Related
Is there any way I can add a background to my text in Pixi.js? I'm looking for an effect like this:
Creating a background sprite, and giving it the same position and dimensions as the text object does not work here, as that would always give me a rectangle which is not what I want. I guess I could make on text object per line and use that approach, but since the text is arbitrarily set by the user I would have to work out my own linebreaking algorithm to be able to do that. That seems overly complicated.
Here is my code without any background (fiddle):
var app = new PIXI.Application({
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x2c3e50
});
document.body.appendChild(app.view);
var text = new PIXI.Text("HELLO\nWORLD!", {
align: "center"
})
text.anchor.set(0.5);
text.x = app.renderer.width / 2;
text.y = app.renderer.height / 2;
app.stage.addChild(text);
Consider having a large (2000x1000) stage with some text in it. The stage gets downscaled to 1000x500 making the text unreadable. Then we try to enlarge the text by zooming it in.
Expected: the text should become readable again at some point.
Actual: the text remains unreadable (blurred) no matter how much we zoom in.
Try zooming the page in (with native browser zoom on desktop) after running the snippet:
const stage = new Konva.Stage({
container: 'container',
width: 2000,
height: 1000,
});
const layer = new Konva.Layer();
stage.add(layer);
const rect = new Konva.Text({
x : 50, y : 50, width: 100, height: 100,
fontSize: 12,
text: "This text should be readable when the viewport gets downscaled"
});
layer.add(rect).draw();
stage.scale({x: 0.5, y: 0.5});
stage.setAttrs({width: 1000, height: 500});
stage.draw();
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.6.0/konva.js"></script>
<div id="container"></div>
The quality loss can be avoided by downscaling with CSS only, like this:
const stage = new Konva.Stage({
container: 'container',
width: 2000,
height: 1000,
});
const layer = new Konva.Layer();
stage.add(layer);
const rect = new Konva.Text({
x : 50, y : 50, width: 100, height: 100,
fontSize: 12,
text: "This text should be readable when the viewport gets downscaled"
});
layer.add(rect).draw();
stage.getChildren().forEach(function(layer) {
layer.canvas._canvas.style.width = "1000px";
layer.canvas._canvas.style.height = "500px";
layer.hitCanvas.setSize(1000, 500);
layer.hitCanvas.context.scale(0.5, 0.5);
});
stage.draw();
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.6.0/konva.js"></script>
<div id="container"></div>
Note how text becomes readable at a certain level of zooming.
The workaround breaks Konvajs abstraction. What problems it can potentially cause? Is there a better way, which uses only public methods exposed by Konvajs?
In fabric.js it can be done like this (complete example here):
canvas.setDimensions({width: '1000px', height: '500px'}, {cssOnly: true});
Konva is a canvas framework. Canvas is a bitmap image unlike vector elements like SVG. So that "blur" should be expected. Technically to fix the issue you can redraw stage with higher pixelRatio on zoom event:
Konva.pixelRatio = 4
stage.draw();
That code will generate more pixels for canvas element. But the page may be very heavy in RAM in this case because Konva will have to produce very large canvas. In most of the mobile apps, you don't need native zooming and you can use responsive design. For zooming the stage, you can use Konva methods.
Does anyone know how to implement linear animation, for example like in progress bars, where few of lines moving infinite in the bar from left to right or any other way? I'm going to use only QtQuick2 primitives and without any additional C++ components, glad to see any answers that can fit this requirements. Also, I know how to set infinite loop for animation, but actual question is to how moves row of rectangles/lines from letf to right in infinity loop, I just can't imagine approach for that.
Something like that?
Rectangle {
width: 400
height: 30
anchors.centerIn: parent
border.color: "grey"
border.width: 1
clip: true
Rectangle {
id: runner
property double percent: 0.2
width: parent.width * percent
height: parent.height
color: "orange"
NumberAnimation on x { from: runner.width * (-1); to: 400; duration: 2000; loops: Animation.Infinite }
}
}
I need a better understanding of kinetic.js animation. I was using the tutorial found http://www.html5canvastutorials.com/kineticjs/html5-canvas-stop-animation-with-kineticjs/ . I played with the code and made my animation set my rectangle at x position 100. My question is how do I the movement of the rectangle to have a smooth transition. I was unable to get my head wrapped around the explanation of kinetic.js animations off the html5canvastutorials.com. here is my code.
var stage = new Kinetic.Stage({
container: 'container',
width: 960,
height: 480
});
var layer = new Kinetic.Layer();
var block = new Kinetic.Rect({
x: 100,
y: 465,
width: 14,
height: 14,
stroke: 'black',
strokeWidth: 1
});
layer.add(block);
stage.add(layer);
var moveLeft = new Kinetic.Animation(function(frame) {
block.setX(1);
}, layer);
var moveRight = new Kinetic.Animation(function(frame) {
block.setX(100);
}, layer);
document.addEventListener('keydown', function(e){
switch(e.keyCode) {
case 37:
moveLeft.start();
break;
case 39:
moveRight.start();
break;
default:
moveLeft.stop();
moveRight.stop();
break;
}
});
Can someone please give me an example of how to create smooth animations and a great explanation of how to repeat the process. Not sure how frame timing works either.
I think you should look at this change:
API Changes
new Tween class. The old Transition class has been retired. For advanced tweens, such as tweening things along curves, or constructing timelines, KineticJS recommends the GreenSock Animation Platform which integrates seamlessly.
For simple tweens, you can use the built in Tween class. Here's an example:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-linear-transition-tutorial-with-kineticjs/
There are many examples of SVG path animation, both natively
http://jsfiddle.net/FVqDq/
and with Raphael.js
http://jsfiddle.net/d7d3Z/1/
p.animate({path:"M140 100 L190 60"}, 2000, function() {
r.animate({path:"M190 60 L 210 90"}, 2000);
});
How is this possible with the svg.js library?
No, this is not yet possible with svg.js. I have been looking into it and it will be a rather large implementation. As I try to keep the library small it will never be part of the library itself, but I might write a plugin. Although at the moment I do not have much time on my hands so all help will be appreciated.
UPDATE:
This is now possible with SVG.js out of the box if you use paths with equal commands but different values.
But we also have a path morphing plugin for SVG.js which is probably the thing you are looking for.
There is a quick and dirty way to animate a line with svg.js:
http://jsfiddle.net/c4FSF/1/
draw
.line(0, 0, 0, 0)
.stroke({color: '#000', width: 2})
.animate(1000, SVG.easing.bounce) // Using svg.easing.js plugin(not required)
.during(function(t, morph) {
this.attr({x2:morph(0, 100), y2: morph(0, 100)})
})
Animating complex SVG paths as wout said will require a plugin.
Unfortunately I don't (yet) know enough about SVG, but I'm thinking of writing a plugin which would use the SMIL animation tag. Which is what is used in the first link of the question.
We can make path animation by finding the bounding box of your path and the do like this.
if your path having some clipping -rectangle means like that below
<g id="container_svg_SeriesGroup_0" transform="translate(128.8,435)" clip-path="url(#container_svg_SeriesGroup_0_ClipRect)"><path id="container_svg_John_0" fill="none" stroke-dasharray="5,5" stroke-width="3" stroke="url(#container_svg_John0Gradient)" stroke-linecap="butt" stroke-linejoin="round" d="M 0 -17.25 L 21.7 -112.12499999999999 M 21.7 -112.12499999999999 L 43.4 -51.75 M 43.4 -51.75 L 86.8 -25.875 M 86.8 -25.875 L 108.5 -155.25 "/><defs><clipPath id="container_svg_SeriesGroup_0_ClipRect"><rect id="container_svg_SeriesGroup_0_ClipRect" x="0" y="-155.25" width="118.5" height="148" fill="white" stroke-width="1" stroke="transparent" style="display: inline-block; width: 118.5px;"/></clipPath></defs></g>
var box = $("#"+ path.id")[0].getBBox();
create the rectangle based on the box and the set this rectangle as your clip-path in path.
then increase the width of the rectangle step by step in jquery.animate.
doAnimation: function () {
//cliprect is your clipped rectangle path.
$(clipRect).animate(
{ width: 1000},
{
duration: 2000,
step: function (now, fx) {
$(clipRect).attr("width", now);
}
});
},
jquery.animate step function is used to increase the width of your clip-rect step by step.
You can animate paths using the svg.path.js plugin.
See the first examples (using the .drawAnimated method).
Another option, which we've resorted to, is to use textPath and then use a character.
In our case we're using the • entity, but I'm thinking if you create your own typography in .svg, .woff etc, you can have flat shapes of any kind.
So you would use your character as in here:
http://jsfiddle.net/wbx8J/3/
/* create canvas */
var draw = SVG('canvas').size(400,400).viewbox(0, 0, 1000, 1000)
/* create text */
var text = draw.text(function(add) {
add.tspan('•').dy(27)
})
text.font({ size: 80, family: 'Verdana' })
/* add path to text */
text.path('M 100 400 C 200 300 300 200 400 300 C 500 400 600 500 700 400 C 800 300 900 300 900 300')
/* visualise track */
draw.use(text.track).attr({ fill: 'none'/*, 'stroke-width': 1, stroke: '#f09'*/ })
/* move text to the end of the path */
function up() {
text.textPath.animate(3000).attr('startOffset', '100%').after(down)
}
/* move text to the beginning of the path */
function down() {
text.textPath.animate(3000).attr('startOffset', '0%').after(up)
}
/* start animation */
up()