I am trying to convert an old simulation from Flash to createjs with animate cc. The only code you have is to rotate a piece but I can not get it to work. This code not work:
function spinit()
{
var ang = myangle * Math.PI / 180;
this.pin1.x = disk1.x + R * Math.cos(ang);
this.pin1.y = disk1.y + R * Math.sin(ang);
this.yoke1.x = pin1.x;
this.disk1.rotate = myangle;
this.myangle = myangle + 1;
if (myangle > 360)
{
myangle = 0;
}
}
var myangle = 0;
var R = 90;
setInterval(spinit, 5);
Chances are good this is a scope issue. Your spinit method is being called anonymously, so it won't have access to any of your frame content referenced with this. You can get around this by scoping your method, and binding your setInterval call.
this.spinit = function() // 1. scope the function
{
var ang = myangle * Math.PI / 180;
this.pin1.x = disk1.x + R * Math.cos(ang);
// etc
setInterval(spinit.bind(this), 5); // 2. bind this so it calls in the right scope.
}
Make sure to call this.spinit().
Hope that helps!
Related
The issue happened here while using canvas property.
I tried to create roulette in react native using canvas property. I successfully used canvas, except I cannot use ctx.drawImage methods. When I tried to use them I got an error like
JSON.Stringify cannot serialize cyclic structures
Here is a code snipet
componentDidMount(){
wheelCanvas = this.updateCanvas();
}
// This is in error while rendering :
ctx.drawImage(wheelCanvas, wheelCanvas.width / 2, wheelCanvas.height / 2);
updateCanvas() {
var outsideRadius = 120;
var textRadius = 100;
var insideRadius = 30;
var canvas = this.refs.canvasRoulette;
let ctx = canvas.getContext("2d");
canvas.width = canvas.height = outsideRadius * 2 + 6;
var x = outsideRadius + 3;
var y = outsideRadius + 3;
ctx.font = "bold 18px Helvetica, Arial";
for (var i = 0; i < rouletteSize; i++) {
var angle = i * arc;
ctx.fillStyle = colors[i];
ctx.beginPath();
ctx.arc(x, y, outsideRadius, angle, angle + arc, false);
ctx.arc(x, y, insideRadius, angle + arc, angle, true);
ctx.strokeStyle = "#fff";
ctx.lineWidth = 1;
ctx.stroke();
ctx.fill();
ctx.save();
ctx.shadowOffsetX = -1;
ctx.shadowOffsetY = -1;
ctx.shadowBlur = 0;
ctx.shadowColor = "rgb(220,220,220)";
ctx.fillStyle = "#fff";
ctx.translate(
x + Math.cos(angle + arc / 2) * textRadius,
y + Math.sin(angle + arc / 2) * textRadius
);
ctx.rotate(angle + arc / 2 + Math.PI);
var text = numbers[i];
ctx.fillText(text, -ctx.measureText(text).width / 2, 5);
ctx.restore();
}
return canvas;
}
I want to drag a view verticaly inside my app, below is my code.
I have a window with id="win" and a square view (100x100).
var window = $.win;
var lastTouchPosition = 0;
$.demo.addEventListener("touchstart", function(e){
var touchPos = {x:e.x, y:e.y};
lastTouchPosition = $.demo.convertPointToView(touchPos, window);
});
$.demo.addEventListener("touchmove", function(e){
var touchPos = {x:e.x, y:e.y};
var newTouchPosition = $.demo.convertPointToView(touchPos, window);
$.demo.top += Number(newTouchPosition.y) - Number(lastTouchPosition.y);
$.demo.left += Number(newTouchPosition.x) - Number(lastTouchPosition.y);
//lastTouchPosition = newTouchPosition;
});
When i start drag the view i get following WARN : [WARN] : Invalid dimension value (nan) requested. Making the dimension undefined instead.
and my view is not moving.
Could you give me an idea please how i can start drag a view and stop to drag it when i reach a specific vertical position value (eg: the bottom of the viewport)
Thank you for your help.
I would add the touch events to the window/container-view instead like this:
var WIDTH = (OS_ANDROID) ? Ti.Platform.displayCaps.platformWidth / dpi : Ti.Platform.displayCaps.platformWidth;
var HEIGHT = (OS_ANDROID) ? Ti.Platform.displayCaps.platformHeight / dpi : Ti.Platform.displayCaps.platformHeight;
var sx = 0;
var sy = 0;
var cx = 0;
var cy = 0;
var xDistance = 0;
function onTouchStart(e) {
// start movement
sx = e.x;
sy = e.y;
cx = e.x;
cy = e.y;
}
function onTouchMove(e) {
xDistance = cx - sx;
var yDistance = cy - sy;
var rotationStrength = Math.min(xDistance / (WIDTH), 1);
var rotationStrengthY = Math.min(yDistance / (HEIGHT), 1);
var rotationAngel = (2 * Math.PI * rotationStrength / 16);
var scaleStrength = 1 - Math.abs(rotationStrength) / 16;
var scaleStrengthY = 1 - Math.abs(rotationStrengthY) / 16;
var scaleMax = Math.min(scaleStrength, scaleStrengthY);
var scale = Math.max(scaleMax, 0.93);
$.view_card_front.rotation = rotationAngel * 20;
$.view_card_front.translationX = xDistance;
$.view_card_front.setTranslationY(yDistance);
$.view_card_front.scaleX = scale;
$.view_card_front.scaleY = scale;
cx = e.x;
cy = e.y;
}
function onTouchEnd(e) {
// check xDistance
}
$.index.addEventListener("touchmove", onTouchMove);
$.index.addEventListener("touchstart", onTouchStart);
$.index.addEventListener("touchend", onTouchEnd);
in the XML there is a <View id="view_card_front"/> with touchEnabled:false
This will give you a nice smooth movent (and a rotation in this example)
I want to remove the listener for individual objects that are animating. I want to remove the ticker for individual objects because they will stop at different times when they reach 200px in y. This code is one frame in Adobe Animate. So this code is not working:
this.stop();
that= this;
var aParticle;
var mySpeed = 12;
var myRotation = 4;
var totalParticles = 5;
var stopParticles = false;
var particleHolder = new createjs.Container();
var count = 0;
var collission_ar = [this.parent.mc_coll0, this.parent.mc_coll1, `this.parent.mc_coll2, this.parent.mc_coll3, this.parent.mc_coll4, this.parent.mc_coll5, this.parent.mc_coll6, this.parent.mc_coll7, this.parent.mc_coll8, this.parent.mc_coll9, this.parent.mc_coll10, this.parent.mc_coll11, this.parent.mc_coll12, this.parent.mc_coll13, this.parent.mc_coll14];`
var totalCollisions = collission_ar.length;
this.addChild(particleHolder);
//stage.update();
var xRange = width;
var yRange = height;
var scaleNum = 1;
//var collisionMethod = ndgmr.checkPixelCollision;
this.scaleX = 1;
this.scaleY = 1;
createParticles()
setTimeout(function(){
removeTimer();
}, 5000)
function createParticles(){
var particle_ar = [];
var randNum = Math.ceil(Math.random() * totalParticles);
aParticle = new lib['MC_leaf'+randNum]();
aParticle.name = 'MC_leaf'+count;
aParticle.x = Math.random() * xRange;
aParticle.y = -Math.random() * 15;
theNum = Math.random() * scaleNum;
aParticle.scaleX = theNum
aParticle.scaleY = theNum
aParticle.alpha = 1;
aParticle.collision = Math.floor(Math.random() * 2);
particleHolder.addChild(aParticle);
aParticle.addEventListener("tick", animateParticle.bind(that));
if(!stopParticles){
timer = setTimeout(function() { createParticles() }, 100);
}
count++;
}
function animateParticle (event){
var part = event.currentTarget;
event.currentTarget.y += mySpeed
event.currentTarget.x += Math.random()/10
event.currentTarget.rotation += myRotation;
if (part.y > 200) {
if(part.name == 'MC_leaf0') console.log('part0 y '+part.y);
part.removeEventListener("tick", animateParticle.bind(that));
}
}
function removeTimer() {
stopParticles = true;
timer = clearInterval();
}
var timer = setTimeout(function() { createParticles() }, 100, that);
So this code is just ignored:
part.removeEventListener("tick", animateParticle.bind(that));
You must pass a reference to the same method in removeEventListener that you used with addEventListener. When you use bind, it generates a wrapper function each time.
// This won't work.
part.removeEventListener("tick", animateParticle.bind(that));
A simple workaround is to store a reference to the bound function, and use that.
aParticle.tickHandler = animateParticle.bind(that);
aParticle.addEventListener("tick", aParticle.tickHandler);
Then use it when removing the listener
part.removeEventListener("tick", part.tickHandler);
There is a better way to handle this though. If you use the utility on() method instead of addEventListener, you can easily remove the method inside the handler.
aParticle.on("tick", animateParticle, that);
// Then when removing:
function animateParticle(event) {
if (conditions) {
event.remove();
}
}
The on() method also has a scope parameter, so you can skip the function binding. It is important to note though that the on() method does its own internal binding, so to remove a listener the usual way, you have to store a reference to it as well.
var listener = target.on("tick", handler, this);
listener.off("tick", listener);
Hope that helps!
I have a graphic in an animation playing within a movieclip
What I want to do is get the x and y position of the graphic inside of that movieclip as it animates.
but I'm finding that the x an y don't update, even though at the moment, I'm checking within the tick function, I'm using globalToLocal
function tickHandler(event) {
//get the x and y of this mc using globalToLocal
console.log(exportRoot.game_anim.meterMC.awd.globalToLocal(exportRoot.game_anim.meterMC.awd.x, exportRoot.game_anim.meterMC.awd.y))
stage.update();
}
exportRoot.gotoAndStop("game")
exportRoot.game_anim.meterMC.arrowYou.addEventListener("mousedown",function (evt) {
var _this = evt.target
var mouseRight = 0;
var mouseLeft = 180;
var offset = {x: _this.x - evt.stageX, y: _this.y - evt.stageY};
evt.addEventListener("mousemove" , function(ev){
// )
var pt = exportRoot.game_anim.meterMC.globalToLocal(stage.mouseX, stage.mouseY)
if ( pt.y > mouseLeft){
percent = 100;
} else if (pt.y < mouseRight){
percent = 0;
} else {
percent = Math.round(((pt.y - mouseRight) / (mouseLeft - mouseRight)*100));
_this.y = pt.y;
}
if ( pt.y > mouseLeft){
}
;
})
});
Try using localToGlobal with a static point in your target clip. For example:
var pt = myMC.subMC.localToGlobal(0,0);
console.log(pt.x, pt.y);
I know this subject has been discussed before but still have problem with refresh my list with refresh button after update the StoreList...
Here is my handler:
function clac_distance() {
for (var i=0;i<mydata.length;i++)
{
//alert((coor[1].lat-lat)*(Math.PI/180));
var R = 6371; // km
var dLat = (coor[i].lat-lat)*(Math.PI/180);
var dLon = (coor[i].lng-lng)*(Math.PI/180);
var lat1 = lat*(Math.PI/180);
var lat2 = coor[i].lat*(Math.PI/180);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
mydata[i].distance = (R * c).toFixed(2);
//alert(mydata[i].distance);
}
Toolbar.views.listPanel.update();
Toolbar.views.listPanel.bindStore(ListStore);
}
Ext.List listens to the datachanged event of the store it binds to, which means that the list component will update itself according to change in the store automatically. So the right approach is to change the model instance in the store properly:
ListStore.getById(id).set(key, value);
And good things will happen :)