I want to have my "definitionContainer"s Y position to be at the same Y position of the "questionMarkContainer".
Im not sure how to save the Y position of the questionMarkContainer and apply it to "definitionContainer" Y position when the questionMarkContaineris clicked.
I tried
definitionContainer.myNewCords = xOffsetNumberContainer;
definitionContainer.y = definitionContainer.myNewCords;
How can i accomplish the task.
function writeOutDefinitionsQuestionMarksOnRight() {
var yOffsetNumberContainer = 102;
for (var c = 0; c < randomTermsForUserSorting.length; c++) {
var questionMarkContainer = new createjs.Container();
var Highlight = new createjs.Shape();
Highlight.graphics.beginFill("hotPink").drawRoundRect(0, 0, 30, 25, 5);
var HighLightlabel = new createjs.Text("?", "10pt arial bold", "white");
HighLightlabel.textAlign = "center";
HighLightlabel.x = 15
HighLightlabel.y = 5
questionMarkContainer.addChild(Highlight, HighLightlabel);
self.stage.addChild(questionMarkContainer);
questionMarkContainer.x = 720;
questionMarkContainer.y = yOffsetNumberContainer;
questionMarkContainer.termIndex = c;
// calling a function to return the clickHandler function
// because there was some crazy stuff with using the closure of
// termIndex where the clickHandler function was always the last index.
// The 'usual' method of getting around this situation wasnt working for some reason.
var clickHandler = (function (termIndex) {
return function (e) {
var definitionContainer = new createjs.Container();
definitionContainer.myNewCords = yOffsetNumberContainer;
rect = new createjs.Shape();
rect.graphics.beginFill("DarkGreen").drawRoundRect(0, 0, 350, 150, 8);
var name = new createjs.Text(randomTermsForUserSorting[termIndex].Name, "12pt arial", "white");
name.x = 5;
name.y = 5;
name.lineWidth = 300;
var definitionText = new createjs.Text(randomTermsForUserSorting[termIndex].Definition, "10pt arial", "white");
definitionText.x = 5;
definitionText.y = 35;
definitionText.lineWidth = 330;
var xButtonRectangle = new createjs.Shape();
xButtonRectangle.graphics.beginFill("red").drawRoundRect(320, 5, 20, 20, 2);
var xTextCloseButton = new createjs.Text("X", "10pt arial", "white");
xTextCloseButton.x = 325;
xTextCloseButton.y = 7;
definitionContainer.addChild(rect, name, definitionText,xButtonRectangle, xTextCloseButton);
self.stage.addChild(definitionContainer);
definitionContainer.x = 300;
definitionContainer.y = yOffsetNumberContainer;
definitionContainer.addEventListener("click", function () {
self.stage.removeChild(definitionContainer);
});
}
})(c);
questionMarkContainer.addEventListener("click", clickHandler);
yOffsetNumberContainer += 40;
}
}
It looks like you are just adjusting a single yOffsetContainer property, which is referenced inside the click function. The click is fired later, and will use the yOffsetContainer variable, which has already been set to the number of items x 40. It does not save the loop value inside each item.
You should be able to pass the loop value as a parameter in your closure to store the loop value in the click handler:
var clickHandler = (function (termIndex, yOffset) {
return function (e) {
// OTHER CODE NOT SHOWN
definitionContainer.y = yOffset;
// MORE CODE NOT SHOWN
}
})(c, yOffsetNumberContainer);
Related
I'm trying to create a coloring game for kids using animate cc. I used the following code:
var drawingCanvas;
var oldPt;
var oldMidPt;
var color;
var stroke = 50;
var index;
var that = this;
this.colorArray = ["#FF0000", "#009900", "#FFFF00", "#0000FF", "#000000", "#FF00FF"];
function init() {
index = 0;
createjs.Touch.enable(stage);
drawingCanvas = new createjs.Shape();
stage.addEventListener("stagemousedown", handleMouseDown);
stage.addEventListener("stagemouseup", handleMouseUp);
that.obj1.addChild(drawingCanvas);
//that.obj1.update();
}
function handleMouseDown(event) {
color = that.colorArray[(index++) % that.colorArray.length];
oldPt = that.obj1.globalToLocal(stage.mouseX, stage.mouseY);
oldMidPt = oldPt.clone();
stage.addEventListener("stagemousemove", handleMouseMove);
}
function handleMouseMove(event) {
var midPt = that.obj1.globalToLocal(stage.mouseX, stage.mouseY);
drawingCanvas.graphics.setStrokeStyle(stroke, 'round', 'round').beginStroke(color).moveTo(midPt.x, midPt.y).curveTo(oldPt.x, oldPt.y, oldMidPt.x,
oldMidPt.y);
oldPt.x = midPt.x;
oldPt.y = midPt.y;
oldMidPt.x = midPt.x;
oldMidPt.y = midPt.y;
//stage.update();
}
function handleMouseUp(event) {
stage.removeEventListener("stagemousemove", handleMouseMove);
}
init();
There is a movieclip where color will be applied and another movie clip above that which is just outline of the object. My question is, is it possible to check if the object is fully colored? Or is there any way to get the shape's color?
I'm trying to convert one of the Paper.js library examples (http://paperjs.org/examples/smoothing/) from PaperScript to Javascript. Following the documentation, I have
Made the scope global
Installed the event handlers onFrame and onResize
Created a tool and installed the event handlers onMouseMove and onMouseDown
But the canvas is not shown. I only see a couple of small blue lines: AFAIK the problem lies in the view.onFrame() function, since commenting that out at least I can see the shape, but not interact with it. The JS console dosen't show any error. What is missing?
// Make the paper scope global, by injecting it into window
paper.install(window);
window.onload = function () {
// Setup directly from canvas id:
paper.setup('myCanvas');
// Create tool
tool = new Tool();
var width, height, center;
var points = 10;
var smooth = true;
var path = new Path();
var mousePos = view.center / 2;
var pathHeight = mousePos.y;
path.fillColor = 'black';
initializePath();
function initializePath() {
center = view.center;
width = view.size.width;
height = view.size.height / 2;
path.segments = [];
path.add(view.bounds.bottomLeft);
for (var i = 1; i < points; i++) {
var point = new Point(width / points * i, center.y);
path.add(point);
}
path.add(view.bounds.bottomRight);
path.fullySelected = true;
}
view.onFrame = function (event) {
pathHeight += (center.y - mousePos.y - pathHeight) / 10;
for (var i = 1; i < points; i++) {
var sinSeed = event.count + (i + i % 10) * 100;
var sinHeight = Math.sin(sinSeed / 200) * pathHeight;
var yPos = Math.sin(sinSeed / 100) * sinHeight + height;
path.segments[i].point.y = yPos;
}
if (smooth)
path.smooth({ type: 'continuous' });
}
tool.onMouseMove = function (event) {
mousePos = event.point;
}
tool.onMouseDown = function (event) {
smooth = !smooth;
if (!smooth) {
// If smooth has been turned off, we need to reset
// the handles of the path:
for (var i = 0, l = path.segments.length; i < l; i++) {
var segment = path.segments[i];
segment.handleIn = segment.handleOut = null;
}
}
}
// Reposition the path whenever the window is resized:
view.onResize = function (event) {
initializePath();
}
}
To try it: https://jsfiddle.net/1rtkbp9s/
Found the solution (credits to Stefan Krüger of the Paper.js Google Group):
var mousePos = view.center / 2;
Should have been:
var mousePos = view.center.divide(2);
The fact is that Math functions should be used instead of operators for Point and Size object... and I didn't realize that view.center IS a Point object: http://paperjs.org/reference/view/#center
I have a particle animation written in JavaScript using Canvas.
What i'm trying to do is to change the canvas drawing values, specifically radMax and radMin. I have written the code here for you to see: https://jsfiddle.net/u3wwxg58/
What happens now, is that when I call function f(), new particles are added with the right radMax and radMin values, instead of updating the current "drawing" with the new radMax and radMin values. Basically, what i'm trying to do is to simply make my sphere / animation larger when function f() is called.
My code for drawParticle()
var cvs = document.createElement('canvas'),
context = cvs.getContext('2d');
document.body.appendChild(cvs);
var numDots = 500,
n = numDots,
currDot,
maxRad = 100,
minRad = 90,
radDiff = maxRad-minRad,
dots = [],
PI = Math.PI,
centerPt = {x:0, y:0};
resizeHandler();
window.onresize = resizeHandler;
while(n--){
currDot = {};
currDot.radius = minRad+Math.random()*radDiff;
currDot.radiusV = 10+Math.random()*50,
currDot.radiusVS = (1-Math.random()*2)*0.005,
currDot.radiusVP = Math.random()*PI,
currDot.ang = (1-Math.random()*2)*PI;
currDot.speed = 0;
//currDot.speed = 1-Math.round(Math.random())*2;
//currDot.speed = 1;
currDot.intensityP = Math.random()*PI;
currDot.intensityS = Math.random()*0.5;
currDot.intensityO = 64+Math.round(Math.random()*64);
currDot.intensityV = Math.min(Math.random()*255, currDot.intensityO);
currDot.intensity = Math.round(Math.random()*255);
currDot.fillColor = 'rgb('+currDot.intensity+','+currDot.intensity+','+currDot.intensity+')';
dots.push(currDot);
}
function drawPoints(){
var n = numDots;
var _centerPt = centerPt,
_context = context,
dX = 0,
dY = 0;
_context.clearRect(0, 0, cvs.width, cvs.height);
var radDiff,currDot;
//draw dots
while(n--) {
currDot = dots[n];
currDot.radiusVP += currDot.radiusVS;
radDiff = currDot.radius+Math.sin(currDot.radiusVP)*currDot.radiusV;
dX = _centerPt.x+Math.sin(currDot.ang)*radDiff;
dY = _centerPt.y+Math.cos(currDot.ang)*radDiff;
//currDot.ang += currDot.speed;
currDot.ang += currDot.speed*radDiff/40000;
currDot.intensityP += currDot.intensityS;
currDot.intensity = Math.round(currDot.intensityO+Math.sin(currDot.intensityP)*currDot.intensityV);
//console.log(currDot);
_context.fillStyle= 'rgb('+currDot.intensity+','+currDot.intensity+','+currDot.intensity+')';
_context.fillRect(dX, dY, 1, 1);
console.log('draw dots');
} //draw dot
window.requestAnimationFrame(drawPoints);
}
function resizeHandler(){
var box = cvs.getBoundingClientRect();
var w = box.width;
var h = box.height;
cvs.width = w;
cvs.height = h;
centerPt.x = Math.round(w/2);
centerPt.y = Math.round(h/2);
}
drawPoints();
and my code for updating the values:
var myi = 0, timex = 20;
function f() {
numDots =500+myi*10; maxRad = 300;minRad = 200 ; n=numDots;
while(n--){
currDot = {};
currDot.radius = minRad+Math.random()*radDiff;
currDot.radiusV = 10+Math.random()*500,
currDot.radiusVS = (1-Math.random()*2)*0.005,
currDot.radiusVP = Math.random()*PI,
currDot.ang = (1-Math.random()*2)*PI;
currDot.speed = (1-Math.random()*2);
//currDot.speed = 1-Math.round(Math.random())*2;
//currDot.speed = 1;
currDot.intensityP = Math.random()*PI;
currDot.intensityS = Math.random()*0.05;
currDot.intensityO = 64+Math.round(Math.random()*64);
currDot.intensityV = Math.min(Math.random()*255, currDot.intensityO);
currDot.intensity = Math.round(Math.random()*255);
currDot.fillColor = 'rgb('+currDot.intensity+','+currDot.intensity+','+currDot.intensity+')';
dots.push(currDot);
//setTimeout(function(){n++},1000);
}
myi++;
if( myi < timex ){
setTimeout( f, 500 );
}}
f();
Picture to show what I want to do: https://postimg.org/image/9uhb3jda9/
So left one is before calling function f(), right one is when f() is called.
Function f is adding dots because the statement currDot = {}; creates a new object, and the statement dots.push(currDot);
adds it to the array of dots.
If you change it to:
currDot = dots[n];
and remove the push then it will act on the existing dots.
However, that will only work while myi is zero.
Presumably you are intending to increase the number of dots over time. Perhaps what you really want is just to completely replace the existing dots?
In which case just stick dots = []; before the while loop and leave the rest as-is.
No point iterating all the particles again just to change the size of the effect. Do it while you are rendering the particles.
From your code add the variable radiusGrowAt and increase each dot radius every time you render it. radiusGrowAt assumes the frame rate is constant and at 60fps
//just after document.body.appendChild(cvs) where you declare and define
maxRad = 20,
minRad = 10,
radDiff = maxRad-minRad,
//=================================================================
radiusGrowAt = 20 / 60, //<<== add this // grow 20 pixels every 60 frames (one second)
//=================================================================
dots = [],
PI = Math.PI,
centerPt = {x:0, y:0};
... etc
Then
//draw dots
while(n--) {
currDot = dots[n];
//=================================================================
currDot.radius += radiusGrowAt; //<<== add this line
//=================================================================
currDot.radiusVP += currDot.radiusVS;
radDiff = currDot.radius+Math.sin(currDot.radiusVP)*currDot.radiusV;
... etc
Basically I want to scroll a object along path. I've seen several threads looking for similar solution not using paper.js but i was wondering if this possible with paper.js. Or can someone give me a working jsfiddle of object follow svg curve because I couldn't get any thing to work. I ultimately want to have a chain of divs follow the path.
// vars
var point1 = [0, 100];
var point2 = [120, 100];
var point3 = [120, 150];
// draw the line
var path = new Path();
path.add(new Point(point1), new Point(point2), new Point(point3));
path.strokeColor = "#FFF";
path.closed = true;
// draw the circle
var circle = new Path.Circle(0,100,4);
circle.strokeColor = "#FFF";
// target to move to
var target = point2;
// how many frame does it take to reach a target
var steps = 200;
// defined vars for onFrame
var dX = 0;
var dY = 0;
// position circle on path
circle.position.x = target[0];
circle.position.y = target[1];
function onFrame(event) {
//check if cricle reached its target
if (Math.round(circle.position.x) == target[0] && Math.round(circle.position.y) == target[1]) {
switch(target) {
case point1:
target = point2;
break;
case point2:
target = point3;
break;
case point3:
target = point1;
break;
}
// calculate the dX and dY
dX = (target[0] - circle.position.x)/steps;
dY = (target[1] - circle.position.y)/steps;
}
// do the movement
//circle.position.x += dX;
//circle.position.y += dY;
}
Here is the jsfiddle:
http://jsfiddle.net/J9xgY/12/
Thanks!
You can find a point along a path with path.getPointAt(offset) where offset is measured in points along the length of the path. If you can calculate the position of a slider along its track, you can multiply that by the path.length to get an offset.
You can do this with an HTML slider or with a canvas element, as shown here:
// vars
var point1 = [0, 100];
var point2 = [120, 100];
var point3 = [120, 150];
// draw the line
var path = new Path();
path.add(new Point(point1), new Point(point2), new Point(point3));
path.strokeColor = "#FFF";
path.closed = true;
// draw the circle
var circle = new Path.Circle(0,100,4);
circle.strokeColor = "#FFF";
// slider
var sliderLine = new Path(new Point(10,30.5), new Point(210, 30.5));
sliderLine.strokeColor = '#FFF';
var sliderKnob = new Path.Circle(new Point(10,30.5), 5);
sliderKnob.fillColor = '#FFF';
var sliderHit = false;
function onMouseDown(event) {
if (event.item == sliderKnob) sliderHit = true;
}
function onMouseDrag(event) {
if (sliderHit === true) {
if (event.point.x > 10 && event.point.x < 210) {
sliderKnob.position.x = event.point.x;
}
else if (event.point.x < 11) {
sliderKnob.position.x = 10;
}
else if (event.point.x > 209) {
sliderKnob.position.x = 210;
}
// Get offset and set circle position
var percent = ( sliderKnob.position.x - 10 ) / 200;
circle.position = path.getPointAt(path.length * percent);
}
}
function onMouseUp(event) {
sliderHit = false;
}
jsfiddle: http://jsfiddle.net/J9xgY/13/
Click and drag the filled circle along the line to move the circle along the triangle.
I'm working on creating a tic-tac-toe game in canvas. I'm currently stuck at a point where I detect if there is a symbol(X or O) already at x/y cordinates on the canvas.
I tried using ImageData to check if an element is present but it returns an error if nothing is there. I also thought perhaps I could assign an ID to the square or the symbol. However that doesn't seem to be possible from what I've read.
Any help would be appreciated.
You can see the game running here http://jsfiddle.net/weeklygame/dvJ5X/30/
function TTT() {
this.canvas = document.getElementById('ttt');
this.context = this.canvas.getContext('2d');
this.width = this.width;
this.height = this.height;
this.square = 100;
this.boxes = [];
this.turn = Math.floor(Math.random() * 2) + 1;
this.message = $('.message');
};
var ttt = new TTT();
TTT.prototype.currentPlayer = function() {
var symbol = (this.turn === 1) ? 'X' : 'O';
ttt.message.html('It is ' + symbol + '\'s turn');
};
// Draw the board
TTT.prototype.draw = function(callback) {
// Draw Grid
for(var row = 0; row <= 200; row += 100) {
var group = [];
for(var column = 0; column <= 200; column += 100) {
group.push(column);
this.context.strokeStyle = 'white';
this.context.strokeRect(column,row,this.square,this.square);
};
this.boxes.push(group);
};
callback;
};
// Get center of the click area cordinates
TTT.prototype.cordinates = function(e) {
var row = Math.floor(e.clientX / 100) * 100,
column = Math.floor(e.clientY / 100) * 100;
return [row, column];
};
// Check if the clicked box has symbol
TTT.prototype.check = function(row, column) {
};
// Get cordinates and set image in container
TTT.prototype.click = function(e) {
var cordinates = ttt.cordinates(e),
x = cordinates[0] + 100 / 2,
y = cordinates[1] + 100 / 2,
image = new Image();
if (ttt.turn === 1) {
image.src = 'http://s8.postimg.org/tdp7xn6lt/naught.png';
ttt.turn = 2;
} else {
image.src = 'http://s8.postimg.org/9kd44xt81/cross.png';
ttt.turn = 1;
};
ttt.context.drawImage(image, x - (image.width / 2), y - (image.height / 2));
ttt.currentPlayer();
};
function render() {
ttt.draw($('#ttt').on("click", ttt.click));
ttt.currentPlayer();
};
(function init() {
render();
})();
Would it not be easier for you to keep track of the grid positions using an array. When you place something on the grid allocate that position in the array. That way rather than having to work out a way to read it from the Canvas you just look in the array. This also allows you to quickly redraw the canvas from the array when needed, such as when the screen resizes...
To detect which field was clicked, iterate through your 9 fields and check if the clicked position is in the area where the field is drawn.
To be able to do this, store the state of your fields (position and if it has a X, O or nothing in it). You should also store the 9 fields in an array, so you can easily iterate over them. I would store it in a two dimensional array (3x3).
function Field(x, y) {
this.x = x;
this.y = y;
this.value = null; // Can be null, 'X' or 'O'
}
Initialisation of the tic tac toe field:
var fields = [
[new Field(0,0), new Field(1,0), new Field(2,0)],
[new Field(0,1), new Field(1,1), new Field(2,1)],
[new Field(0,2), new Field(1,2), new Field(2,2)]
];
Iteration:
for (var y = 0; y <= 2; y++) {
for (var x = 0; x <= 2; x++) {
var field = fields[y][x];
// Do something with the field.
}
}
I would store the position of the fields with model coordinates. So you multiply the coordinates with a value to get the coordinates for drawing on the canvas.