uxebu / bonsai Goto Github PK
View Code? Open in Web Editor NEWBonsaiJS is a graphics library and renderer
Home Page: http://bonsaijs.org
License: Other
BonsaiJS is a graphics library and renderer
Home Page: http://bonsaijs.org
License: Other
After drag events it'd be helpful if the event object would contain the diffX
and diffY
properties that you get while dragging.
If you didn't drag, diffX
and diffY
would simply be 0
.
I suppose the same goes for click
and the like (I mean, not just for up
).
Unless that's the metaKey
value, in which case it doesn't seem to work.
I see none of the values set to true
when pressing the shift key itself, or when pressing a letter while holding shift. Neither on keydown
nor keyup
.
I notice that over time, animate becomes slower and laggier. At the same time, the tick
callback remains stable. This problem is stronger and appears faster on the ipad. I'm not sure what the problem is, but you can check out my game if you want a real world case.
This will need to be resolved. I hope it's not my own fault... :/
This is probably a feature request, but how should I go about rotating an object in it's center while growing it?
Basically what I want to do is this:
new Bitmap(<url>)
.attr({x:0,y:0,width:0,height:0,origin:new Point(0,0),rotation:-Math.PI/2})
.animate({x:100, y:100, width: 350, height: 200, rotation: 3*Math.PI});
And I would like to rotate the bitmap in it's center during the animation.
Or I'm just blind. How do you remove a filter once you set it through .attr({filters: new filter.DropShadow(1, 1, 2, 0x000000FF)})
?
Tried null
,"none"
,[]
. None worked. Strings throw errors.
-- edit: tobi said there's a bug so I'm keeping this ticket
When I do new Circle(x,y,50).attr({x:a,y:b})
the values x
and y
(the parameters for Circle
) will be ignored. I would expect those to be coordinates relative to the position of the circle, much like a .moveTo
before actually drawing the circle.
Why is it .animate('3s', opt)
and .morph(opt, '3s')
?
The sprite-properties demo (under header "flash stuff") throws an error, probably related to depricated or bad api call.
Uncaught TypeError: Object [object Object] has no method 'rect'
I know, so is the title of this issue.
For instance, check http://docs.bonsaijs.org/module-filter.filter.DropShadow.html
It starts talking about parameter, but doesn't show the finter print of the function at all.
Add a possibly property to attr
called mirror
(or flip
?) that has four properties; horizontal
, vertical
, both
, and none
. This should apply a transformation matrix that does just that; mirror or flip the image. Note that this is not the same as rotating the image for 90, 180, or 270 degrees.
Note, it's also the same as scaleX
/scaleY
set to -1
.
Of course the trick to this is that this is done without affecting anything else. So x
,y
,matrix
,scale
should all still function, even with this applied. I know right.
in svg.js
line 390
parent.insertBefore(element, svg[message.next]);
should be changed to something like
parent.insertBefore(element, svg[message.next] || null);
The main issue is IE 10 follows spec and will error when passed undefined
instead of null
as the second argument to parent.insertBefore
.
Currently with multi touch events you get a touchId which is something like 3326568163 in my example. How can I tell whether this is the first or second finger? Or ninth?
.animate('3s', {opacity:100})
doesn't animate the object (with opacity
set to 0
) but immediately show it. The animation works when I explicitly define the easing function to use. I believe a default easing function is missing.
The (currently private) demo pages are missing the html
and head
tags. I know they can be omitted but think we should give a correct and complete example and write proper and complete code. That includes html.
Feel free to reject this. While implementing drag and drop I found it quite hard to implement the drop target behavior. I would register a pointerdown
event. Add a temporary object that serves as the visual thing actually being dragged and hope to drag that object to one of a few drop targets. The problem is, of course, that I can't find the proper event to register (if any) to get this drop event.
The pointerup
won't fire because even if it would after a dragstart
on another object, it would still be blocked by my temporary "dragging" object. drop
doesn't fire because, well, that doesn't quite work this way. So my only option left now is to check all my dropzone objects and see whether my release was inside one of them. Something that could be sugared by bonsai.
Although it might be a specific use case every time, bonsai could at least expose a droppable
attribute which registers the element as a drop target in this bonsai instance. Then, whenever the pointer was released after a drag, bonsai could check each registered element and fire drop
events on any that were directly under the pointer at release time.
That's what I'll be implementing anyways, just without the sugar.
I registered a click event to an element and it seems to fire twice when tapped on the ipad.
One of the reasons the Xero demo fails is because bootstrap is trying to set Infinity
on the iframe global. Since Infinity
is a read-only property (not Writable nor Configurable), this fails hard.
Since Infinity is a number value, are there cross frame problems for not setting it explicitly? Else it should probably be purged in bootstrap.js:88, just like stage
is deleted.
It should probably not be added in the first place, for reasons above.
.arcTo(30, 30, 0, Math.PI, 0, 64, 86)
Math.PI is wrong there (don't know why right now) but that's causing an svg path error.
this.bg.animate('10s', {opacity: 100}, {easing: 'cubicInOut'});
The actual animation takes about one second, not ten. Fwiw, the onEnd
callback does wait about ten seconds to fire.
shape.attr({rotate:Math.PI / 2}).animate({rotate:-Math.PI})
goes counter-clock wise, always. This makes sense from a range point of view, but when animating in a circle, it could be very desirable to be able to tell the animator which direction to rotate into.
(Docs didn't mention anything related to setting this)
Very much missing are the event docs. Add all the events that might be registered in bonsai (keep in mind a future canvas renderer, so don't go easy and say "any DOM event", that won't suffice).
And obviously list the various ways to register or deregister events.
Add a “visible” or “interactive” attribute to display object, where setting “visible” to false would work like setting visibility: hidden;
in CSS and “interactive” would work like pointer-events: none;
Animating fillGradient
doesn't have any effect when fillColor
was previously set.
var s = new Rect(0, 0, 200, 100).fill('blue');
s.addTo(stage);
s.animate('1s', {
fillGradient: gradient.linear('top right', ['red', ['yellow', 80], 'blue'])
});
I was expecting that we internally convert the plain color to a gradient, like:
var s = new Rect(0, 0, 200, 100).fill( gradient.linear('top right', ['blue', 'blue']));
s.addTo(stage);
s.animate('1s', {
fillGradient: gradient.linear('top right', ['red', ['yellow', 80], 'blue'])
});
To me it looks like a good idea to encapsulate common "asset" functionality in a separate class and let Bitmap/Video/Audio/FontFamily(/Movie?) inherit from it. Also since the AssetLoader is assigned to _loader
we could try to get rid of as much EventEmitter stuff as possible and instead call instance methods directly. The only callback that is allowed should be the "user" callback (3rd parameter).
function AssetDisplayObject(sharedLoader, resource, callback) {
// was previously `_loader`
this._sharedLoader = sharedLoader;
DisplayObject.call(this);
if (callback) {
this.bindAssetCallback(callback);
}
this.type = 'AssetDisplayObject';
}
AssetDisplayObject.prototype.request = function() {…}
If you keep creating a new Bitmap
(like in a setInterval
loop) you'll see memory accumulate, even if you don't assign the result of the new Bitmap
call. This seems to be the root of at least one memory leak that's causing performance problems for our movies. Especially over time.
If unsure, ask @basecode :)
var bs = new bonsai.Bitmap('assets/redpanda.jpg').addTo(stage);
stage.frames({
0: function() {
bs.attr({
origin: new Point(0,0),
rotation:0.1
});
},
'1s': function() {
bs.attr({
origin: new Point(128, 128),
rotation:0.1
});
}
});
Since the new "Simple Path API" is rolled out with a default transform-origin of "center center" I would suggest to change the default value for most of the other DisplayObects accordingly, as long as we are able to compute a correct bounding-box of course. That would at least include the Bitmap and Video API for now.
The docs of Text say that the line
property will change the line color (which is the text color?). But setting bs.attr({line:'white'})
does not change the color. Neither does textColor
, fontColor
, or color
. Running out of options here...
The following always alerts '100' no matter what value the lineWidth
has
var s = Shape.rect(100,100,100,100)
.addTo(stage)
.attr({fillColor:'red', lineWidth:10, lineColor: 'green'});
alert(s.getComputed('width'))
This may be intentional.
Setting stage.framerate
doesn't affect the rate at which the tick event is called. It does affect the speed of .animate
though. Either it should do both or neither. I think it'd be nice if it would do both but could understand if it was a read-only property.
I'm pretty sure sugared api calls should not be able to cause this, so:
new .Path()
.moveTo(0,0)
.arcBy(10,10,20,1,Math.PI)
.lineTo(0,0)
.stroke('red',2)
.addTo(stage);
causes
Error: Problem parsing d="M 0 0 a 10 10 20 1 3.141592653589793 L 0 0"
obj.animate(t, {x:y}, {onEnd:undefined})
throws an error because undefined
is not a function. Imo, the callback should be at least checked to be non-falsy. And only throw warnings if it is a non-falsy non-function.
new Text(15)
new Text('0')
new Text(0)
bsText.attr({text:15})
bsText.attr({text:'0'})
bsText.attr({text:0})
in short; the text args need to be checked for the number zero. It seems you've fallen for the falsy trap :)
It might be an interesting approach to allow to mimic multi touch by holding modifier keys. It wouldn't be the same, of course, but it would at least be something... Whether that'd be configurable by the user, or hardcoded by bonsai, is another question.
We need to spec-out a simple API for passing arbitrary data (in the form of triggering events) from the parent page to the runner context and vice versa.
E.g.
Using a worker-esque postMessage
API:
// -- Parent page --
var myMovieController = bonsai.run(element, 'path/to/movie.js', {...});
myMovieController.postMessage({ someData: 123, foo: 'bar' });
// -- Movie --
stage.on('message', function(e) {
// access e.data for data
});
Or, perhaps, providing a way to trigger events directly on the stage within the movie:
// -- Parent page --
var myMovieController = bonsai.run(element, 'path/to/movie.js', {...});
myMovieController.triggerStageEvent('foo', 'event data .....');
// -- Movie --
stage.on('foo', function(e) {
// access e.data for data
});
I'm not sure if this is supposed to happen, but I'm sure I'm not expecting this to happen. Observe the difference between:
new Path()
.attr({x:200, y:200})
.moveTo(0,0)
.arc(50, 50, 50, 1.25 * Math.PI, 1.75 * Math.PI)
.stroke('red', 1)
.addTo(stage);
and
new Path()
.attr({x:200, y:200})
.arc(50, 50, 50, 1.25 * Math.PI, 1.75 * Math.PI)
.stroke('red', 1)
.addTo(stage);
There's an extra line that appears when you moveTo
. I would not expect a moveTo
to cause that line, even if it might be the arc
doing it.
I've got a movie where I have a group of an image and some rects. The group is placed entirely beyond the right edge of the viewport. A transformation matrix is applied to mirror the group visually. When I animate it from right to left, it appears as if there's a masking effect going on. The image is static and you get to see more of it. I'd expect the image to gradually move from right-to-left too, like the rest of the group, but that doesn't happen.
When moving the group way to the left (so that the right side of the group is not sticking or beyond the right edge of the viewport) the image suddenly does move. As soon as the group breaks with the right side of the viewport, of course.
This leads me to believe that Bitmaps have an issue with being placed beyond the right side of the screen, probably in conjunction when a transformation matrix is applied to them.
options.delay
is not supportedvar rect = new Rect(0, 0, 200, 200).fill('green').addTo(stage);
var anim = new KeyframeAnimation('1s', {
'5s': { x: 500 }
});
rect.animate(anim);
The computedWIdth() of images currently reports 0, see example below
new bonsai.Bitmap('http://uxebu.com/media/img/team/padolsey.jpg', function() {
stage.addChild(this);
alert(this.getComputed('width') +' ; '+ this.getComputed('height'));
}
);
Any callback, especially event driven, should return an event argument. In particular, it appears that the onEnd
event for animations only expose the animation object through this
. But what if I want to .bind
my callback? This is highly likely, especially in an OO env:
...
start: function(){
this.circle.animate('3s',{x:15}, {onEnd: function(){ this.doStuff(); }.bind(this); })
},
...
Now it's impossible to get to the animation object unless you go out of your way to declare it explicitly and save it in a variable or whatever this
is.
See filter page, link at the bottom See the filter module »
points to localhost:4000. Oops!
My second finger gives me the same id as the first finger. So it's currently impossible to detect one finger events from the second.
Using three larges images, or even just two images:
var bs = new Bitmap(<url>).attr({x:0,y:0,width:10,height:10}).addTo(stage);
setTimeout(function(){
bs.attr({source:<url2>});
setTimeout(function(){
bs.attr({source:<url3>,width:10,height:10});
}, 500);
}, 500);
Because they don't...
//new Circle(100, 100, 50).stroke('red', 1).addTo(stage);
new Path()
.attr({x:30, y:50})
.moveBy(50+Math.cos(Math.PI*-0.5) * 50, 50+Math.sin(Math.PI*-0.5) * 50)
.arcBy(
50, 50,
0, 0, 0,
50+Math.cos(Math.PI*+0.5) * 50, 50+Math.sin(Math.PI*+0.5) * 50)
.stroke('red', 1)
.addTo(stage);
new Path()
.attr({x:50, y:50})
.moveBy(50+Math.cos(Math.PI*-0.7) * 50, 50+Math.sin(Math.PI*-0.7) * 50)
.arcBy(
50, 50,
0, 0, 0,
50+Math.cos(Math.PI*+0.7) * 50, 50+Math.sin(Math.PI*+0.7) * 50)
.stroke('green', 1)
.addTo(stage);
new Path()
.attr({x:58, y:35})
.moveBy(50+Math.cos(Math.PI*-0.9) * 50, 50+Math.sin(Math.PI*-0.9) * 50)
.arcBy(
50, 50,
0, 0, 0,
50+Math.cos(Math.PI*+0.9) * 50, 50+Math.sin(Math.PI*+0.9) * 50)
.stroke('blue', 1)
.addTo(stage);
Animating x
and rotation
moves the Rect
instance too far. Seems it varies depending on the duration of the Animation. Using a Path instance instead works as expected (of course, the transform-origin is different).
var square = new Rect(0, 0, 100, 100);
// compared to a Path instance
//square = new Path('v100h100v-100');
square.addTo(stage);
square.fill('red');
square.animate('1s', {
x: 300,
rotation: Math.PI*2,
fillColor: 'green'
});
// line
new Path('M0,120h300v10h1v-20h-1v9h-300').fill('black').addTo(stage);
Please discuss this with some people, but I think it's nice to have simple sugar to remove an element after an animation ends (especially when fading out). Something like
bs.animate('3s', {opacity:0}, {onEnd:'remove'})
where remove
is indeed just a string, which would be substituted by a function that removes the animated objects when the animation ends.
Same for destroy
, since I guess those are the two most common things. Although there might be more...?
If a fillGradient
and fillColor
are applied to shape x
and then x
is resized, the size of the gradient will not increase to fit. This is because, when applying a fillGradient and fillColor to the same path, we use <pattern>
and size the pattern <rect>
objects according to the current bounding-box of the shape. We don't update it though. Either we should update it or we should use objectBoundingBox
for the patternContentUnits
instead of userSpaceOnUse
(this would need review in regard to how we handle fillImage
though).
It might be nice to reference the article about the art of bonsai somewhere:
http://whatijustlearned.wordpress.com/2011/04/22/bonsai-heaven-and-earth-in-one-container/
maybe in the readme? or the website?
I want to add a temporary object that should disappear after five seconds, so i dont need a handle.
new Rect(0,0,10,10).animate('3s',{x:20},{onEnd:function(e){ e.target.remove(); });
It seems that's currently not possible? Only through the ("private"?) api of subjects.
I'm not sure if it's too much trouble to do this. So if that's the case, I don't think it's worth it. But have a look at passing on the state of shift/ctrl/alt(/special?) with pointer/mouse events as well. Just as they are for key events.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.