Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial port of concentricity project #1

Merged
merged 5 commits into from
Nov 1, 2016
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Ignore build generated files
build/
dist/
dist.zip

# Ignore waf lock file
.lock-waf*

# Ignore installed node modules
node_modules/
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
This is a Rocky.js reboot of the [Concentricity](https://github.com/pebble-examples/concentricity) example watchface. It makes use of Rocky.js and Canvas APIs
`rockyFillRadial` and `fillRect`, as well as demonstrates how to use the `UnobstructedArea` API.

![](screenshots/concentricity_js~emery.png)
![](screenshots/concentricity_js~diorite.png)
![](screenshots/concentricity_js~chalk.png)
![](screenshots/concentricity_js~basalt.png)
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "concentricity_js",
"author": "MakeAwesomeHappen",
"version": "1.0.0",
"keywords": ["pebble-app"],
"private": true,
"dependencies": {},
"pebble": {
"displayName": "concentricity_js",
"uuid": "e4b999b1-aa83-41cb-b29f-f4b74dc2e483",
"projectType": "rocky",
"sdkVersion": "3",
"enableMultiJS": true,
"watchapp": {
"watchface": true
},
"resources": {
"media": []
}
}
}
Binary file added screenshots/concentricity_js~basalt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/concentricity_js~chalk.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/concentricity_js~diorite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/concentricity_js~emery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions src/rocky/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright [2016] Pebble Technology
var rocky = require('rocky');

var round = require('./round');
var rect = require('./rect');

function DrawCommand(platform) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you could just require the relevant file based on platform.

if(rocky.watchInfo.platform === 'chalk') { //require round } else { //require rect }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The require is a directive to webpack to include a module in the bundled JS file. At bundling time, rocky.watchInfo.platform doesn't exist (it's an API accessible at runtime) and I'm not sure how webpack would handle this (maybe ignore it?)

if (platform === 'chalk') {
this.hours = round.drawHours;
this.minutes = round.drawMinutes;
this.seconds = round.drawSeconds;
} else {
this.hours = rect.drawHours;
this.minutes = rect.drawMinutes;
this.seconds = rect.drawSeconds;
}
if (platform === 'diorite') {
this.hourColor = "white";
this.minuteColor = "white";
this.secondColor = "white";
} else {
this.hourColor = "bluemoon";
this.minuteColor = "vividviolet";
this.secondColor = "richbrilliantlavender";
}
}

var draw = new DrawCommand(rocky.watchInfo.platform);

rocky.on('draw', function(event) {
var ctx = event.context;
ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);

var date = new Date();
draw.hours(ctx, date.getHours(), draw.hourColor);
draw.minutes(ctx, date.getMinutes(), draw.minuteColor);
draw.seconds(ctx, date.getSeconds(), draw.secondColor);
});

rocky.on('secondchange', function(event) {
rocky.requestDraw();
});
100 changes: 100 additions & 0 deletions src/rocky/rect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright [2016] Pebble Technology
var utils = require('./utils');

var drawBorder = function(ctx, arcId, segment, totalSegments, color){
// Calculate x, y, width, height of border
var canvasWidth = ctx.canvas.unobstructedWidth;
var canvasHeight = ctx.canvas.unobstructedHeight;
var centerX = canvasWidth / 2;
var centerY = canvasHeight / 2;
var inset = utils.calculateInset(canvasWidth, arcId);

var x = centerX - (canvasWidth / 2) + inset;
var y = centerY - (canvasHeight / 2) + inset;
var width = centerX + (canvasWidth / 2) - (inset * 2);
var height = centerY + (canvasHeight / 2) - (inset * 2);
var strokeWidth = utils.getStrokeWidth(canvasWidth);

// Calculate max no of pixels in perimeter less the size of the border at
// the four corners
var perimeterMax = ((width * 2) + (height * 2)) - (strokeWidth * 4);

// Calculate the corners
var topRight = width / 2;
var bottomRight = topRight + height - strokeWidth;
var bottomLeft = bottomRight + width - strokeWidth;
var topLeft = bottomLeft + height - strokeWidth;

// Calculate our current position around the perimeter
var perimeterPosition = (segment * perimeterMax) / totalSegments;

// Make sure we don't exceed maximum
if (perimeterPosition > perimeterMax) {
perimeterPosition = perimeterMax;
}

// Set the drawing color
ctx.fillStyle = color;

// Prefill any completed sides
// Prefill top right
if (perimeterPosition > topRight) {
ctx.fillRect((width / 2) + x, y, width / 2, strokeWidth);
}

// Prefill right
if (perimeterPosition > bottomRight) {
ctx.fillRect(width - strokeWidth + x, strokeWidth + y, strokeWidth, height - strokeWidth);
}

// Prefill bottom
if (perimeterPosition > bottomLeft) {
ctx.fillRect(x, height - strokeWidth + y, width - strokeWidth, strokeWidth);
}

// Fill left
if (perimeterPosition > topLeft) {
ctx.fillRect(x, y, strokeWidth, height - strokeWidth);
}

// Draw from the last filled side to our current position
if (perimeterPosition >= topLeft) {
// TOP LEFT to TOP MIDDLE
ctx.fillRect(strokeWidth + x, y, perimeterPosition - topLeft, strokeWidth);
} else if (perimeterPosition <= topRight) {
// TOP MIDDLE to TOP RIGHT
ctx.fillRect((width / 2) + x, y, perimeterPosition, strokeWidth);
} else if (perimeterPosition <= bottomRight) {
// TOP RIGHT to BOTTOM RIGHT
ctx.fillRect(width - strokeWidth + x, strokeWidth + y, strokeWidth, perimeterPosition - topRight);
} else if (perimeterPosition <= bottomLeft) {
// BOTTOM RIGHT to BOTTOM LEFT
ctx.fillRect(width - strokeWidth - (perimeterPosition - bottomRight) + x, height - strokeWidth + y,
perimeterPosition - bottomRight, strokeWidth);
} else if (perimeterPosition < topLeft) {
// BOTTOM LEFT to TOP LEFT
ctx.fillRect(x, height - strokeWidth - (perimeterPosition - bottomLeft) + y,
strokeWidth, perimeterPosition - bottomLeft);
}
};

// Handle representation for hours
var drawHours = function(ctx, hours, color) {
drawBorder(ctx, 2, hours % 12, 12, color);
};

// Handle representation for minutes
var drawMinutes = function(ctx, minutes, color) {
drawBorder(ctx, 1, minutes + 1, 60, color);
};

// Handle representation for seconds
var drawSeconds = function(ctx, seconds, color) {
drawBorder(ctx, 0, seconds + 1, 60, color);
};

module.exports = {
drawHours: drawHours,
drawMinutes: drawMinutes,
drawSeconds: drawSeconds
};
52 changes: 52 additions & 0 deletions src/rocky/round.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright [2016] Pebble Technology
var utils = require('./utils');

var timeAngle = function(time) {
return time * (2 * Math.PI / 60);
};
var hourAngle = function(hour) {
return hour * (2 * Math.PI / 12);
};

// Draw an arc with given inner/outer radii
var drawArc = function(ctx, arcId, endAngle, color) {
var startAngleOffset = Math.PI / 2;
var canvasWidth = ctx.canvas.unobstructedWidth;
var centerX = canvasWidth / 2;
var centerY = ctx.canvas.unobstructedHeight / 2;

var strokeWidth = utils.getStrokeWidth(canvasWidth);
var outerRadius = utils.calculateOuterRadius(arcId, canvasWidth);

// Set the drawing color
ctx.fillStyle = color;

if (endAngle == 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (endAngle === 0) {

ctx.rockyFillRadial(centerX, centerY, outerRadius - strokeWidth, outerRadius,
-startAngleOffset, (2 * Math.PI) - startAngleOffset);
} else {
ctx.rockyFillRadial(centerX, centerY, outerRadius - strokeWidth, outerRadius,
-startAngleOffset, endAngle - startAngleOffset);
}
};

// Handle representation for hours
var drawHours = function(ctx, hours, color) {
drawArc(ctx, 2, hourAngle(hours % 12), color);
};

// Handle representation for minutes
var drawMinutes = function(ctx, minutes, color) {
drawArc(ctx, 1, timeAngle(minutes), color);
};

// Handle representation for seconds
var drawSeconds = function(ctx, seconds, color) {
drawArc(ctx, 0, timeAngle(seconds), color);
};

module.exports = {
drawHours: drawHours,
drawMinutes: drawMinutes,
drawSeconds: drawSeconds
};
22 changes: 22 additions & 0 deletions src/rocky/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright [2016] Pebble Technology

var PADDING = 10;
var NUM_ARCS = 3;

var calculateInset = function(canvasWidth, arcId) {
return (getStrokeWidth(canvasWidth) + PADDING) * arcId;
};

var getStrokeWidth = function(canvasWidth) {
return ((canvasWidth / NUM_ARCS) / 2) - PADDING;
};

var calculateOuterRadius = function(arcId, canvasWidth) {
return (canvasWidth / 2) - ((getStrokeWidth(canvasWidth) + PADDING) * arcId);
};

module.exports = {
getStrokeWidth: getStrokeWidth,
calculateInset: calculateInset,
calculateOuterRadius: calculateOuterRadius
};
30 changes: 30 additions & 0 deletions wscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# This file is the default set of rules to compile a Pebble application.
#
# Feel free to customize this to your needs.
#
top = '.'
out = 'build'


def options(ctx):
ctx.load('pebble_sdk')


def configure(ctx):
"""
This method is used to configure your build. ctx.load(`pebble_sdk`) automatically configures
a build for each valid platform in `targetPlatforms`. Platform-specific configuration: add your
change after calling ctx.load('pebble_sdk') and make sure to set the correct environment first.
Universal configuration: add your change prior to calling ctx.load('pebble_sdk').
"""
ctx.load('pebble_sdk')


def build(ctx):
ctx.load('pebble_sdk')
ctx.pbl_bundle(js=ctx.path.ant_glob(['src/pkjs/**/*.js',
'src/pkjs/**/*.json',
'src/common/**/*.js']),
js_entry_file='src/pkjs/index.js',
bin_type='rocky')