-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
109 changed files
with
1,148 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
.DS_Store | ||
node_modules/** | ||
dist/* | ||
npm-debug.log | ||
yarn-debug.log* | ||
yarn-error.log* | ||
yarn.lock | ||
package-lock.json | ||
selenium-debug.log | ||
.idea | ||
.vscode | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Concentric Data Watchface | ||
Watchface for Amazfit GTR Mini and for other round ZeppOS watch. | ||
|
||
![demo](./demo-gtr-mini.png) | ||
|
||
## Features | ||
|
||
**Main features** | ||
- sliding minutes and seconds | ||
- date and weekday | ||
- step counter | ||
- sleep time or sunrise/sunset time if no sleep data | ||
- heart rate | ||
- battery level | ||
|
||
|
||
**Model compatibility:** Amazfit GTR Mini, Amazfit GTR 4 and all other round ZeppOS watches | ||
|
||
**Note: It requires devices with ZeppOS 2 and higher and is not compatible with older models like the GTR 3 and GTR 3.** | ||
|
||
**AOD:** No | ||
|
||
**Tap-zones:** No | ||
|
||
**Language:** English, Russian | ||
|
||
**Inspired:** [Famous Concentric Watchface for Pixel Watches](https://play.google.com/store/apps/details?id=com.watchfacedesigns.Concentric) | ||
|
||
## Download ⏬ | ||
|
||
To install it to your smartwatch: | ||
|
||
See instructions [here](https://github.com/novvember/amazfit-watchfaces/blob/main/README.md) to download and install to your watch. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
App({ | ||
globalData: {}, | ||
onCreate(options) { | ||
console.log('app on create invoke') | ||
}, | ||
|
||
onDestroy(options) { | ||
console.log('app on destroy invoke') | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"configVersion": "v3", | ||
"app": { | ||
"appId": 1067740, | ||
"appName": "Concentric Data", | ||
"appType": "watchface", | ||
"version": { | ||
"code": 1, | ||
"name": "1.0.0" | ||
}, | ||
"icon": "icon.png", | ||
"vender": "novvember", | ||
"cover": [ | ||
"cover.png" | ||
], | ||
"description": "Concentric Data watchface. Source code here: https://github.com/novvember/amazfit-watchfaces" | ||
}, | ||
"runtime": { | ||
"apiVersion": { | ||
"compatible": "1.0.0", | ||
"target": "1.0.1", | ||
"minVersion": "1.0.0" | ||
} | ||
}, | ||
"permissions": [], | ||
"targets": { | ||
"common": { | ||
"module": { | ||
"watchface": { | ||
"path": "watchface/index", | ||
"main": 1, | ||
"editable": 0, | ||
"lockscreen": 1, | ||
"photoscreen": 0 | ||
} | ||
}, | ||
"platforms": [ | ||
{ | ||
"st": "r" | ||
} | ||
], | ||
"designWidth": 480 | ||
} | ||
}, | ||
"i18n": { | ||
"en-US": { | ||
"appName": "Concentric Data" | ||
}, | ||
"ru-RU": { | ||
"appName": "Concentric Data" | ||
}, | ||
"uk-UA": { | ||
"appName": "Concentric Data" | ||
} | ||
}, | ||
"defaultLanguage": "en-US", | ||
"debug": false | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { | ||
TEXT_CHAR_HEIGHT, | ||
TEXT_CHAR_WIDTH, | ||
TEXT_CHARS, | ||
} from '../utils/textChars'; | ||
|
||
const lang = DeviceRuntimeCore.HmUtils.getLanguage(); | ||
const isRusLang = ['ru-RU', 'uk-UA'].includes(lang); | ||
|
||
const { width, height } = hmSetting.getDeviceInfo(); | ||
|
||
export const SCREEN = { | ||
width, | ||
height, | ||
centerX: width / 2, | ||
centerY: height / 2, | ||
}; | ||
|
||
export const COLORS = { | ||
primary: 0xffffff, | ||
secondary: 0xbdbdbd, | ||
tertiary: 0x525457, | ||
}; | ||
|
||
export const FONTS = { | ||
primary: 'fonts/FiraSansCondensed-Medium.ttf', | ||
secondary: 'fonts/FiraSans-Regular.ttf', | ||
tertiary: 'fonts/FiraSans-Medium.ttf', | ||
}; | ||
|
||
export const SECOND = { | ||
image: { | ||
src: 'time/second.png', | ||
}, | ||
text: { | ||
width: px(30), | ||
height: px(30), | ||
textSize: px(22), | ||
color: COLORS.secondary, | ||
radius: px(224), | ||
}, | ||
}; | ||
|
||
export const MINUTE = { | ||
image: { | ||
src: 'time/minute.png', | ||
}, | ||
text: { | ||
width: px(40), | ||
height: px(40), | ||
textSize: px(28), | ||
color: COLORS.secondary, | ||
radius: px(112), | ||
}, | ||
}; | ||
|
||
export const CURRENT_HOUR = { | ||
width: px(140), | ||
height: px(140), | ||
textSize: px(110), | ||
color: COLORS.primary, | ||
}; | ||
|
||
export const CURRENT_MINUTE = { | ||
width: px(70), | ||
height: px(70), | ||
textSize: px(54), | ||
color: COLORS.primary, | ||
radius: px(100), | ||
}; | ||
|
||
export const MIN_ANGLE_TO_UPDATE_WHEEL = 0.7; | ||
|
||
export const DATA = { | ||
radius: px(186), | ||
circleText: { | ||
charImages: TEXT_CHARS, | ||
imageWidth: TEXT_CHAR_WIDTH, | ||
imageHeight: TEXT_CHAR_HEIGHT, | ||
}, | ||
arc: { | ||
width: px(5), | ||
}, | ||
}; | ||
|
||
export const WEEKDAYS = isRusLang | ||
? ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС'] | ||
: ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN']; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/** | ||
* Converts radian angle value to degrees | ||
* @param {number} rad - radian value | ||
* @returns {number} - degrees value | ||
*/ | ||
function radiansToDegrees(rad) { | ||
return (rad * 180) / Math.PI; | ||
} | ||
|
||
/** | ||
* Calculates angular length of element | ||
* @param {Number} r - radius of circle, where element is | ||
* @param {Number} length - size of elenet | ||
* @returns {Number} - angle in degrees | ||
*/ | ||
function calculateAnglularLength(r, length) { | ||
return radiansToDegrees(Math.acos((2 * r ** 2 - length ** 2) / (2 * r ** 2))); | ||
} | ||
|
||
/** | ||
* Builds circle text, where every char is hmUI.widget.IMG widget | ||
* - center of text rotation is the center of the screen of w480 size | ||
* @param {Object} params | ||
* @returns {Objcet} | ||
*/ | ||
export function createCircleTextWidget({ | ||
maxLength, | ||
text, | ||
angleStart, | ||
radius, | ||
gap, | ||
charImages, | ||
imageWidth, | ||
imageHeight, | ||
isTextReversed, | ||
}) { | ||
const SCREEN_SIZE = px(480); | ||
|
||
if (isTextReversed) { | ||
angleStart *= -1; | ||
} | ||
|
||
const chars = text | ||
.toLowerCase() | ||
.slice(0, maxLength) | ||
.padEnd(maxLength, ' ') | ||
.split(''); | ||
const imageAngle = calculateAnglularLength(radius, imageWidth); | ||
let gapAngle = calculateAnglularLength(radius, gap); | ||
|
||
if (gap < 0) { | ||
gapAngle *= -1; | ||
} | ||
|
||
const widgets = chars.map((char, i) => | ||
hmUI.createWidget(hmUI.widget.IMG, { | ||
src: charImages[char] || charImages[' '], | ||
w: SCREEN_SIZE, | ||
h: SCREEN_SIZE, | ||
x: 0, | ||
y: 0, | ||
pos_x: SCREEN_SIZE / 2 - imageWidth / 2, | ||
pos_y: isTextReversed | ||
? SCREEN_SIZE / 2 + radius | ||
: SCREEN_SIZE / 2 - radius - imageHeight, | ||
center_x: SCREEN_SIZE / 2, | ||
center_y: SCREEN_SIZE / 2, | ||
angle: isTextReversed | ||
? angleStart - i * imageAngle - i * gapAngle | ||
: angleStart + i * imageAngle + i * gapAngle, | ||
show_level: hmUI.show_level.ONLY_NORMAL, | ||
}), | ||
); | ||
|
||
const updateText = (newText) => { | ||
newText = newText.toLowerCase(); | ||
|
||
for (let i = 0; i < chars.length; i++) { | ||
if (!newText[i]) newText[i] = ' '; | ||
if (chars[i] === newText[i]) continue; | ||
|
||
widgets[i].setProperty( | ||
hmUI.prop.SRC, | ||
charImages[newText[i]] || charImages[' '], | ||
); | ||
} | ||
}; | ||
|
||
return { updateText }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/** | ||
* Converts radian angle value to degrees | ||
* @param {number} rad - radian value | ||
* @returns {number} - degrees value | ||
*/ | ||
export function radiansToDegrees(rad) { | ||
return (rad * 180) / Math.PI; | ||
} | ||
|
||
/** | ||
* Converts degrees angle value to radian | ||
* @param {number} deg - degrees value | ||
* @returns {number} - radian value | ||
*/ | ||
export function degreesToRadians(deg) { | ||
return (deg * Math.PI) / 180; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* Transforms seconds time value to angle of second hand | ||
* @param {Number} seconds | ||
* @returns {Number} | ||
*/ | ||
export function getAngleFromSeconds(seconds) { | ||
return seconds * 6; | ||
} | ||
|
||
/** | ||
* Transforms minutes ans seconds time value to angle of minute hand | ||
* @param {Number} minutes | ||
* @param {Number} seconds | ||
* @returns {Number} | ||
*/ | ||
export function getAngleFromMinutes(minutes, seconds = 0) { | ||
return ((minutes + seconds / 60) * 360) / 60; | ||
} | ||
|
||
/** | ||
* Transforms hours time value to angle of hour hand | ||
* @param {Number} hours | ||
* @returns {Number} | ||
*/ | ||
export function getAngleFromHours(hours) { | ||
hours = hours % 12; | ||
return (hours * 360) / 12; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Calculates closest sun time (will it be sunset or sunrise) and its time in minutes | ||
* @param {*} timeSensor - hmSensor.id.TIME | ||
* @param {*} timeSensor - hmSensor.id.WEATHER | ||
* @returns {Object} | ||
*/ | ||
export function getClosestSunriseSunsetTime(timeSensor, weatherSensor) { | ||
const { hour, minute } = timeSensor; | ||
const forecastWeather = weatherSensor.getForecastWeather(); | ||
const tideData = forecastWeather.tideData; | ||
|
||
if (!tideData.count) { | ||
return; | ||
} | ||
|
||
const nowMins = hour * 60 + minute; | ||
const { sunrise, sunset } = tideData.data[0] || {}; | ||
const sunriseMins = sunrise.hour * 60 + sunrise.minute; | ||
const sunsetMins = sunset.hour * 60 + sunset.minute; | ||
|
||
const isDay = nowMins >= sunriseMins && nowMins <= sunsetMins; | ||
const type = isDay ? 'sunset' : 'sunrise'; | ||
const obj = isDay ? sunset : sunrise; | ||
|
||
return { | ||
type, | ||
hour: obj.hour, | ||
minute: obj.minute, | ||
}; | ||
} |
Oops, something went wrong.