<svg version="1.1" id="board" class="container" width="1000" height="500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1000 500" xml:space="preserve">
<style type="text/css">
.element{
stroke:#F15A24;
stroke-width:20px;
fill:none;
}
</style>
<rect id="post_1" x="178" y="450" width="25" height="25" />
<rect id="post_2" x="306" y="450" width="25" height="25" />
<rect id="post_3" x="434" y="450" width="25" height="25" />
<rect id="post_4" x="562" y="450" width="25" height="25" />
<rect id="post_5" x="690" y="450" width="25" height="25" />
<rect id="mid_post" x="50" y="177" width="25" height="25" />
<rect id="frame" class="element" x="40" y="40" width="800" height="420" rx="0" />
<symbol id="bead">
<ellipse cx="35" cy="20" rx="35" ry="20" fill="deepPink" fill-opacity="0.8" />
</symbol>
<symbol id="post">
<rect width="25" height="25" />
</symbol>
</svg>
#viewPort {
background-color: black
}
#viewPort2 {
background-color: #1d1d1d
}
var bead = function(value, options, canMoveUp) {
this.value = value;
this.shape = this.drawSVGBead(options);
this.beadAbove = null;
this.beadBelow = null;
this.canMoveUp = canMoveUp;
this.currPos = options.yPos;
var self = this;
this.moveBead = function() {
// depending on the bead.canMoveUp property, animation bead movement and update the canMoveUp property
if (!self.canMoveUp) {
//moving the bead down
var curTransform = new WebKitCSSMatrix(window.getComputedStyle(self.shape).webkitTransform);
TweenLite.to(self.shape, 0.3, {
y: self.currPos + 48
}, 1.8);
if (self.beadBelow !== null && !self.beadBelow.canMoveUp) {
self.beadBelow.moveBead();
}
self.currPos += 48;
} else {
//moving bead up
var curTransform = new WebKitCSSMatrix(window.getComputedStyle(self.shape).webkitTransform);
TweenLite.to(self.shape, 0.3, {
y: self.currPos - 48
}, 1.8);
if (self.beadAbove !== null && self.beadAbove.canMoveUp) {
self.beadAbove.moveBead();
}
self.currPos -= 48;
}
self.canMoveUp = !self.canMoveUp;
}
this.shape.addEventListener("click", this.moveBead, false);
}
bead.prototype.drawSVGBead = function drawSVGBead(options) {
options = options || {};
var xPos = options.xPos || 0,
yPos = options.yPos || 0,
aSVGBead;
aSVGBead = document.createElementNS('http://www.w3.org/2000/svg', 'use');
aSVGBead.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href','#bead');
aSVGBead.setAttributeNS(null, "width", 70);
aSVGBead.setAttributeNS(null, "height", 50);
TweenLite.set(aSVGBead, {x:xPos, y:yPos});
return aSVGBead;
}
var abacus = function(abacusName, columns, topBeadCount, bottomBeadCount) {
this.element = document.getElementById("board");
this.columns = columns;
this.topBeadCount = topBeadCount;
this.bottomBeadCount = bottomBeadCount;
this.topLevelNodeHeads = [];
this.bottomLevelNodeHeads = [];
this.beadsXAxis = [667, 539, 411, 283, 155]; //Placing the beads from the right most axist fo the left
this.beadYAxisSpaceTop = 50;
this.beadYAxisSpaceBottom = 410;
this.beadYAxisMovementTop = 71;
//Finding out the maximum number the current abacus can hold
var findMaxAbacusVal = function(digits){
var max = 0;
for(var i=0; i<digits; i++)
{
max+=Math.pow(10, i)*9
}
return max;
}
this.maxAbacusVal = findMaxAbacusVal(columns);
this.displayedNumber = 0;
}
abacus.prototype.insertBead = function(headBead, newBead) {
newBead.beadBelow = headBead;
headBead.beadAbove = newBead;
return newBead;
}
abacus.prototype.fillBeads = function() {
var beadWidth = 50;
var beadHeight = 40;
//Loop through the number of columns the abacus contains
for(var i=0; i<this.columns; i++)
{
//Inserting the top-level beads where the initial position is the two beads aligning to the top
//The head of the top bead will be the second bead from the top
var head = null;
for (var j=this.topBeadCount-1; j>-1; j--)
{
var beadShapeOptions = {xPos:this.beadsXAxis[i], yPos:this.beadYAxisSpaceTop+(j*beadHeight)};
var value = Math.pow(10, i)*5;
var newBead = new bead(value, beadShapeOptions, false);
this.element.appendChild(newBead.shape);
if (head === null) {
head = newBead;
this.topLevelNodeHeads.push(head);
}
else {
var insertedNewBead = this.insertBead(head, newBead);
head = insertedNewBead;
}
}
//Inserting the top-level beads where the initial position is the two beads aligning to the top
//The head of the bottom bead will be the bead near the top
head = null;
for (var j=0; j<this.bottomBeadCount; j++)
{
var beadWidth = 50;
var beadHeight = 40;
var beadShapeOptions = {xPos:this.beadsXAxis[i], yPos:this.beadYAxisSpaceBottom-(j*beadHeight)};
var value = Math.pow(10, i);
var newBead = new bead(value, beadShapeOptions, true);
this.element.appendChild(newBead.shape);
if (head === null) {
head = newBead;
//this.bottomLevelNodeHeads.push(head);
}
else {
var insertedNewBead = this.insertBead(head, newBead);
head = insertedNewBead;
}
}
this.bottomLevelNodeHeads.push(head);
}
}
window.onload = function() {
// Drawing the basic abacus frame
var frame = $("#frame"),
midPost = $("#mid_post"),
posts = $("#post_1, #post_2, #post_3, #post_4, #post_5, #post_6"),
tl = new TimelineMax();
tl.to(frame, 2, {
attr: {
rx: "30"
}
})
tl.to(posts, 2, {
scaleY: -16
}, 1.8)
tl.to(midPost, 2, {
scaleX: 32
})
var cnAbacus = new abacus("chineseAbacus", 5, 2, 5);
cnAbacus.fillBeads();
};
This Pen doesn't use any external CSS resources.