I have created a movieclip which have 120 frames.
Now i have used multiple instances of this movieclip on stage.
I want each movieclip to stop when it reaches a particular frame. (frame number is different for all instances)
i tried following code
if (char_1.currentFrame == 36) {char_1.stop();}
but it's not working. i tried to trace the current frame and it's always showing 1.
trace(char_1.currentFrame);
Any solution please?
try something like this:
// root
var allMCs:Dictionary = new Dictionary();
allMCs[char_1] = 32; // frame on which to stop char_1
allMCs[char_2] = 12; // frame on which to stop char_2
allMCs[char_3] = 47; // frame on which to stop char_3
// ... add more
// add ENTER_FRAME listener
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(evt:Event):void
{
// loop through all MCs and check their frame
for (var mc:MovieClip in allMCs)
{
trace(mc + " frame: " + mc.currentFrame);
if (mc.currentFrame == allMCs[mc])
{
mc.stop();
}
}
}
if the traces still state that the currentFrame is 1, make sure to do a play(); in every MC you use.
Related
I'm using AVPlayer to stream audio from a server and what I want to do now is to show a custom UISlider who shows the progress of the buffering.
Anyone come up with this? Please give me solution.
Now player load whole duration in once and show in UISlider.
you need to use preferredforwardbufferduration
This property defines the preferred forward buffer duration in seconds. If set to 0, the player will choose an appropriate level of buffering for most use cases. Setting this property to a low value will increase the chance that playback will stall and re-buffer, while setting it to a high value will increase demand on system resources.
also check here for detailed example of how to use : Is it possible to pause and resume buffering of AVPlayer?
inside your player you need to observe time range using below function
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
like this:
let timeRanges = change![NSKeyValueChangeKey.newKey] as? NSArray
if timeRanges != nil && timeRanges!.count != 0 {
DispatchQueue.main.async {
let cmTimeRange = (timeRanges![0] as AnyObject).timeRangeValue as CMTimeRange
self.playerView.timeSlider.bufferValue = Float(CMTimeGetSeconds(cmTimeRange.start) + CMTimeGetSeconds(cmTimeRange.duration))
}
}
I have a custom slider with a variable I defined as bufferValue you can override func draw(_ rect: CGRect)inside your slider and apply changes while buffer is progressing.
I get draw to call anytime bufferValue changes by calling self.setNeedsDisplay()inside didSet
#IBInspectable var bufferValue : Float = 0 {
didSet {
if(bufferValue < 0 ) {
bufferValue = 0
} else if (bufferValue > maximumValue) {
bufferValue = maximumValue
}
self.setNeedsDisplay()
}
}
I need make an App that has about 30k Objects, a user can Pan, Zoom or "Select on click" any of those objects.
Fabric.js Canvas is being used
I have done the same using SVG's and the svg-pan-zoom plugin (no Canvas Element) with better results
Problem: there is a significant Lag while Zooming, Panning or Object on Click
will removing Fabric.js improve performance?
will switching to WebGL improve performance?
Have tried Fabric specific options
fabric.Object.prototype.objectCaching = false;
fabric.Object.prototype.statefullCache = false;
fabric.Object.prototype.noScaleCache = true;
fabric.Object.prototype.needsItsOwnCache = false;
UPDATE
Heres the updated Fiddle
for reference :
canvas-vs-svg-vs-div Stackoverflow
Stackoverflow
Don't Render in IO EVENTS!
Though not a complete fix to the update speed this answer will about double the interaction speed.
A common, almost standard, mistake made with mouse and event interaction with the canvas (and DOM) is to delegate rendering to mouse/touch events. This is very bad practice as mouse events fire at much higher rates than the display can display. It becomes worse when your rendering time is high as you queue up mouse events (pseudo render events) and do a re render for every movement of the mouse
Note blocking code will stop mouse events but as soon as the engine is idle the mouse will start firing at full rate again.
Use the mouse events just to get the mouse state. Use an animation loop that is synced to the display to render only when needed and there is time available. Things like the wheel and mouse movement deltas should be recorded cumulatively.
mouse.dx += event.movementX;
mouse.dy += event.movementY;
mouse.wheel += event.wheelDelta;
And consume them in the main render loop...
function update(){
// ... code to use mouse
// consume deltas
mouse.x = mouse.y = mouse.wheel = 0;
...this ensures that the mouse state is accurately followed when you may have many mouse events between render updates.
Example, separating events from rendering.
Change you code in the fiddle you provided to the following, on my machine it about doubled the rendering speed (which is still very slow).
// from just after the function applyZoom replace all the code
var mouse = { // holds the mouse state
x : 0,
y : 0,
down : false,
w : 0,
delta : new fabric.Point(0,0),
}
// event just track mouse state
function zoom(e) {
if(e != null) { e.preventDefault() }
var evt=window.event || e;
mouse.x = e.offsetX;
mouse.y = e.offsetY;
mouse.w += evt.detail? evt.detail*(-120) : evt.wheelDelta;
return false;
}
canvas.on('mouse:up', function (e) { mouse.down = false });
canvas.on('mouse:out', function (e) { mouse.down = false });
canvas.on('mouse:down', function (e) { mouse.down = true });
canvas.on('mouse:move', function(e) {
if (e && e.e) {
mouse.delta.x += e.e.movementX;
mouse.delta.y += e.e.movementY;
}
});
// main animation loop
function update(){
if(mouse.w !== 0){ // if the wheel has moved do zoom
var curZoom = canvas.getZoom();
canvas.zoomToPoint(
{ x : mouse.x, y: mouse.y },
canvas.getZoom() + mouse.w / 4000
);
mouse.w = 0; // consume wheel delta
}else if(mouse.down) { // if mouse button down
canvas.relativePan(mouse.delta);
}
// consume mouse delta
mouse.delta.x = 0;
mouse.delta.y = 0;
requestAnimationFrame(update);
}
requestAnimationFrame(update);
I would like to put the title + artist name when the song is playing, but I don't know how to achieve this, because with almost 30-35 songs, it would be long and boring to create a specific text layer for each song.
If there is a trick to achieve this quickly.
You can achieve this via scripting.
I have these two scripts that should do what you want. I wrote them some time ago. Maybe you need to do some adjustments.
This one adds several text layers from a csv file.
https://github.com/fabiantheblind/after-effects-script-snippets/blob/master/comp_with_text.jsx
This one should add one text layer with the source text set to the content of a csv.
https://github.com/fabiantheblind/after-effects-script-snippets/blob/master/text_to_comp.jsx
This is a minimal example to add a text layer with sourceText
/**
* main function
*/
var main = function() {
var txt = ['Hello - World', 'dog -cat', 'foo - bah']; // the text to add
app.beginUndoGroup('add source text'); // open a undo group
var curComp = app.project.activeItem; // get the current comp
// check if the curent active item is a comp
if (!curComp || !(curComp instanceof CompItem)) {
alert('noComp');
return;
// end if no comp is active
}
var txtLayer = curComp.layers.addText('titles'); // add a text layer
var counter = 0; // the time to add a keyframe to (in seconds)
// loop the text
for (var i = 0; i < txt.length; i++) {
var curFrame = (counter / curComp.frameRate); // calc time for each frame
$.writeln(curFrame);
// add a keyframe with the text as value every frame
txtLayer.text.sourceText.setValueAtTime(curFrame, txt[i]);
counter++; // increase the time by one
}
app.endUndoGroup();
};
main();
At work we have a google script code that is run every 4 hours and check everyone's #folders for unread mail. If unread mail is found it is moved to INBOX and tagged with ##UNREAD.
What i need is a way for the script to check if it already has the ##UNREAD tag and in that case not move to inbox.
This is the code
function process_unread() {
//Define user label
var label = GmailApp.getUserLabelByName("#Josh");
//Define unread label
var unreadlabel = GmailApp.getUserLabelByName("##UNREAD");
if (label) {
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++) {
var thread = threads[i];
if (thread.isUnread()) {
//Remove label
thread.addLabel(unreadlabel);
thread.moveToInbox();
}
}
}
}
How can i only move emails if they do not have the ##UNREAD label?
Here is my attempt:
function process_unread() {
//Define user label
var label = GmailApp.getUserLabelByName("#Josh");
//Define unread label
var unreadlabel = GmailApp.getUserLabelByName("##UNREAD");
if (label) {
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++) {
var thread = threads[i];
var labels = thread.getLabels();
var doesThisThreadHaveTheLabel = false;
for (var i = 0; i < labels.length; i++) {
var thisParticularLabel = labels[i].getName();
Logger.log(labels[i].getName());
if (thisParticularLabel === "##UNREAD") {
var doesThisThreadHaveTheLabel = true;
};
}
if (thread.isUnread() && doesThisThreadHaveTheLabel === false) {
//Remove label
thread.addLabel(unreadlabel);
thread.moveToInbox();
}
}
}
}
Before you move the thread to the inbox, you want to make sure it does NOT have the label. So add another condition to the If check.
if (thread.isUnread() && doesThisThreadHaveTheLabel === false) {
I created a variable: doesThisThreadHaveTheLabel that will either have a true or false value. It's default gets set to false before every for loop.
var doesThisThreadHaveTheLabel = false;
for (var i = 0; i < labels.length; i++) {
You can debug the code to check it:
In the above picture, you see an icon of a bug in the menu. Before you click that, first click the drop down menu just to the right of the bug, and choose the name of the function to run. Also, add a breakpoint to the code. In that picture you'll see a red dot in the line numbers in the code editor. That's where the code will stop.
I added the label #josh to one of the emails in my account, so the variable label has an object in it. But, I don't have any emails with a label ##UNREAD , so you'll notice that in the list of variables, the variable unreadlabel has a value of null.
In that picture, the code is suspended on the line, 269. I can step in to the next line of code by clicking the step in icon. Hover over the icon to get a context help to pop up.
I stepped line by line further, and retrieved the label that was put into the variable "ThisParticularLabel". You can see in the window, that it has a value of #Josh.
I stepped through that code, and it ended after the main for loop had run once. I also ran that code by itself without debugging it, and it ran in:
Execution succeeded [0.246 seconds total runtime]
You need to debug your code, and see what it is doing on every line, and know what every single variable has for a value, and how the conditional statements are working.
Script will not finish with two for loops both using variable i as i will be set to 0 continually by the inner for loop and will not increment. Switch inner loop to j variable and script will finish.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Cross-browser way to get automatically repeating keydown events when key is held down
I'm trying to create a simple game in JavaScript/CSS/HTML, and I am using jQuery (and a little bit of Underscore) to handle key presses. The player controls a block using arrow keys. I've run into a problem with handling multiple keypresses at the same time. I have a system in place where a closure keeps track of all arrow keys that are pressed. This works well if the player presses keys in the following sequence:
Player presses Down (block moves down)
Player presses Left (block moves diagonally down-left)
Player releases Down (block moves left)
Player releases Left (block stops
However, the block stops if steps 3 and 4 are reversed. Here is what actually happens in that case:
Player presses Down (block moves down)
Player presses Left (block moves diagonally down-left)
Player releases Left (block stops)
The expected behavior is that on step 3, the block would continue to move down, rather than stopping completely.
From traces I have put in the code, it appears that a keyup event actually stops the propagation of further keydown events, even when my finger is still holding down one of the arrow keys.
Here is a snippet of relevant code. Can anyone tell me where the problem might be?
// Creates an animation handler for a specific element.
// Animation reacts to any changes as they are submitted
var getMovementAnimator = function(element) {
var params = {},
$element = $(element);
return function(changes) {
_.each(changes, function(val, key) {
// Remove null or zeroish keys from animation params
if ( (val == 0 || !val) && _.has(params, key)) {
delete params[key];
} else {
params[key] = '+=' + val + 'px';
}
});
$element.animate(params, {duration: 0, queue: false});
console.log(params);
};
};
// Determines direction and speed of movement for an element
// after a keypress event
var getMovementChange = function(keyEvent, keydown) {
var isMoving = !!keydown,
params = {},
dir = '',
speed = keydown ? 5 : 0,
arrows = {left: 37, up: 38, right: 39, down: 40};
switch (keyEvent.which) {
case arrows.left:
dir = 'left';
speed = -speed;
break;
case arrows.up:
dir = 'top';
speed = -speed;
break;
case arrows.right:
dir = 'left';
break;
case arrows.down:
dir = 'top';
break;
}
// If key hit not one of above, do nothing
if (!dir) {
return false;
}
if (!speed) {
console.log('key up: ', dir);
}
params[dir] = speed;
return params;
}
// Sets up key handlers
$(document).ready(function() {
var board = $('#board'),
animatePlayer = getMovementAnimator('.player');
$(document).keydown(function(e) {
e.preventDefault();
var changes = getMovementChange(e, true);
animatePlayer(changes);
}).keyup(function(e) {
e.preventDefault();
var changes = getMovementChange(e, false);
animatePlayer(changes);
});
});
Further search on Stack Overflow (using the right keywords) showed me that the issue I am seeing is not actually a bug in my code. Rather, this is expected behavior for the operating system.
However, I found a workaround which I believe will resolve the issue.