mirror of
https://github.com/google/pebble.git
synced 2025-05-21 19:04:52 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
116
applib-targets/emscripten/html/css/style.css
Normal file
116
applib-targets/emscripten/html/css/style.css
Normal file
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@import url(https://fonts.googleapis.com/css?family=Bowlby+One+SC|Roboto:400,700,400italic);
|
||||
|
||||
body {
|
||||
font: 16px/1.5 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
|
||||
body > .container:first-child > .row:first-child > div > p:first-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
h1 + blockquote {
|
||||
border: 0 none;
|
||||
max-width: 600px;
|
||||
text-align: center;
|
||||
margin: 0 auto 3em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
font-family: "Bowlby One SC";
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
margin: 2em 0 1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h1:before, h1:after, h2:before, h2:after {
|
||||
background-color: #ddd;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 1px;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
h1:before, h2:before {
|
||||
right: 0.5em;
|
||||
margin-left: -50%;
|
||||
}
|
||||
|
||||
h1:after, h2:after {
|
||||
left: 0.5em;
|
||||
margin-right: -50%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1em 0 0.5em;
|
||||
}
|
||||
|
||||
form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
label {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#githubForkLink {
|
||||
background: url(../img/forkBanner.png) no-repeat top right;
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 149px;
|
||||
height: 149px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
/* Hide the text. */
|
||||
text-indent: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
table.table-compatibility>tbody>tr.standard {
|
||||
background-color: #d9edf7;
|
||||
}
|
||||
|
||||
table.table-compatibility>tbody>tr.implemented {
|
||||
background-color: #dff0db;
|
||||
}
|
||||
|
||||
table.table-compatibility>tbody>tr.partial {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
table.table-compatibility>tbody>tr.planned {
|
||||
background-color: #fcf8e3;
|
||||
}
|
||||
|
||||
table.table-compatibility>tbody>tr.not-planned {
|
||||
background-color: #f2dede
|
||||
}
|
94
applib-targets/emscripten/html/index.html
Normal file
94
applib-targets/emscripten/html/index.html
Normal file
|
@ -0,0 +1,94 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2024 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
|
||||
<title>Simple Rocky Simulator</title>
|
||||
|
||||
<link rel="stylesheet" href="css/bootstrap.css"/>
|
||||
<link rel="stylesheet" href="css/style.css"/>
|
||||
|
||||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script type="text/javascript" src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script type="text/javascript" src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript" src="rocky.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="page-header">
|
||||
<h1>[Simple Rocky Simulator]</h1>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<canvas id="pebble" class="rocky" width="432" height="504"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<h3>Controls</h3>
|
||||
<p><form id="controls-form">
|
||||
<label for="timestamp-input">Set Time (Epoch timestamp)</label>
|
||||
<input id="timestamp-input" type="text" />
|
||||
<label for="timezone-offset-input">Timezone Offset (<span id="timezone-offset-span"></span>)</label>
|
||||
<input id="timezone-offset-input" type="range" min="-720" max="840" step="15" value="0" />
|
||||
<label>24h Style</label>
|
||||
<input id="24h-style-input" type="checkbox" />
|
||||
</form></p>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
// Create a new simulator and bind it to the canvas:
|
||||
var rockySimulator = new RockySimulator({
|
||||
canvas: document.getElementById("pebble")
|
||||
});
|
||||
|
||||
// in the future, we will replace the singleton
|
||||
// `rocky` as well as the namespace `Rocky`, e.g.
|
||||
// `Rocky.tween` and `Rocky.WatchfaceHelper` with modules
|
||||
var rocky = _rocky;
|
||||
|
||||
function getQueryVariable(variable) {
|
||||
var query = window.location.search.substring(1);
|
||||
var vars = query.split('&');
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split('=');
|
||||
if (decodeURIComponent(pair[0]) == variable) {
|
||||
return decodeURIComponent(pair[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load app source from 'src' query param (URL / data URI):
|
||||
var src = getQueryVariable('src');
|
||||
// If 'src' is set to empty string, don't load anything (for testing):
|
||||
if (src !== '') {
|
||||
src = src || 'js/tictoc.js';
|
||||
var script = document.createElement('script');
|
||||
script.src = src;
|
||||
document.getElementsByTagName('html')[0].appendChild(script);
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="js/controls.js"></script>
|
||||
</body>
|
||||
</html>
|
62
applib-targets/emscripten/html/js/controls.js
vendored
Normal file
62
applib-targets/emscripten/html/js/controls.js
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
var form = document.getElementById("controls-form");
|
||||
form.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
var timestampInput = document.getElementById("timestamp-input");
|
||||
timestampInput.addEventListener('change', function(e) {
|
||||
rockySimulator.setTime(Number(e.target.value) * 1000);
|
||||
});
|
||||
|
||||
var timezoneSlider = document.getElementById("timezone-offset-input");
|
||||
var timezoneSpan = document.getElementById("timezone-offset-span");
|
||||
var timezoneSliderOnChange = function() {
|
||||
var offset = timezoneSlider.value;
|
||||
rockySimulator.setTimezoneOffset(offset);
|
||||
var sign;
|
||||
if (offset > 0) {
|
||||
sign = '+';
|
||||
} else if (offset < 0) {
|
||||
sign = '-';
|
||||
} else {
|
||||
sign = '';
|
||||
}
|
||||
var offsetMinutes = (offset % 60);
|
||||
var absOffsetHours = Math.abs((offset - offsetMinutes) / 60);
|
||||
var gmtText = 'GMT ' + sign + absOffsetHours;
|
||||
if (offsetMinutes) {
|
||||
var absOffsetMinutes = Math.abs(offsetMinutes);
|
||||
gmtText += ':' + (absOffsetMinutes < 10 ? '0' : '') + absOffsetMinutes;
|
||||
}
|
||||
timezoneSpan.innerText = gmtText;
|
||||
};
|
||||
timezoneSlider.addEventListener('change', timezoneSliderOnChange);
|
||||
timezoneSlider.addEventListener('input', timezoneSliderOnChange);
|
||||
|
||||
// After loading the page, set the slider to the local TZ:
|
||||
var localTimezoneOffset = new Date().getTimezoneOffset();
|
||||
timezoneSlider.value = localTimezoneOffset;
|
||||
timezoneSliderOnChange();
|
||||
|
||||
var time24hStyle = document.getElementById("24h-style-input");
|
||||
time24hStyle.addEventListener('change', function(e) {
|
||||
rockySimulator.set24hStyle(e.target.checked);
|
||||
});
|
||||
});
|
91
applib-targets/emscripten/html/js/tictoc.js
Normal file
91
applib-targets/emscripten/html/js/tictoc.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var WatchfaceHelper = function(date) {
|
||||
function clockwiseRad(fraction) {
|
||||
// TODO: figure out if this is actually correct orientation for Canvas APIs
|
||||
return (1.5 - fraction) * 2 * Math.PI;
|
||||
}
|
||||
|
||||
date = date || new Date();
|
||||
var secondFraction = date.getSeconds() / 60;
|
||||
var minuteFraction = (date.getMinutes()) / 60;
|
||||
var hourFraction = (date.getHours() % 12 + minuteFraction) / 12;
|
||||
this.secondAngle = clockwiseRad(secondFraction);
|
||||
this.minuteAngle = clockwiseRad(minuteFraction);
|
||||
this.hourAngle = clockwiseRad(hourFraction);
|
||||
};
|
||||
|
||||
// book keeping so that we can easily animate the two hands for the watchface
|
||||
// .scale/.angle are updated by tween/event handler (see below)
|
||||
var renderState = {
|
||||
minute: {style: 'white', scale: 0.80, angle: 0},
|
||||
hour: {style: 'red', scale: 0.51, angle: 0}
|
||||
};
|
||||
|
||||
// helper function for the draw function (see below)
|
||||
// extracted as a standalone function to satisfy common believe in efficient JS code
|
||||
// TODO: verify that this has actually any effect on byte code level
|
||||
var drawHand = function(handState, ctx, cx, cy, maxRadius) {
|
||||
ctx.lineWidth = 8;
|
||||
ctx.strokeStyle = handState.style;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(cx, cy);
|
||||
ctx.lineTo(cx + Math.sin(handState.angle) * handState.scale * maxRadius,
|
||||
cy + Math.cos(handState.angle) * handState.scale * maxRadius);
|
||||
ctx.stroke();
|
||||
};
|
||||
|
||||
// the 'draw' event is being emitted after each call to rocky.requestDraw() but
|
||||
// at most once for each screen update, even if .requestDraw() is called frequently
|
||||
// the 'draw' event might also fire at other meaningful times (e.g. upon launch)
|
||||
rocky.on('draw', function(drawEvent) {
|
||||
var ctx = drawEvent.context;
|
||||
var w = ctx.canvas.unobstructedWidth;
|
||||
var h = ctx.canvas.unobstructedHeight;
|
||||
|
||||
// clear canvas on each render
|
||||
ctx.fillStyle = 'black';
|
||||
ctx.fillRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
|
||||
|
||||
// center point
|
||||
var cx = w / 2;
|
||||
var cy = h / 2;
|
||||
var maxRadius = Math.min(w, h - 2 * 10) / 2;
|
||||
drawHand(renderState.minute, ctx, cx, cy, maxRadius);
|
||||
drawHand(renderState.hour, ctx, cx, cy, maxRadius);
|
||||
|
||||
// Draw a 12 o clock indicator
|
||||
drawHand({style: 'white', scale: 0, angle: 0}, ctx, cx, 8, 0);
|
||||
// overdraw center so that no white part of the minute hand is visible
|
||||
drawHand({style: 'red', scale: 0, angle: 0}, ctx, cx, cy, 0);
|
||||
});
|
||||
|
||||
// listener is called on each full minute and once immediately after registration
|
||||
rocky.on('minutechange', function(e) {
|
||||
// WatchfaceHelper will later be extracted as npm module
|
||||
var wfh = new WatchfaceHelper(e.date);
|
||||
renderState.minute.angle = wfh.minuteAngle;
|
||||
renderState.hour.angle = wfh.hourAngle;
|
||||
rocky.requestDraw();
|
||||
});
|
||||
|
||||
rocky.on('secondchange', function(e) {
|
||||
console.log(e.date.toLocaleTimeString() + ' ' + e.date.toLocaleDateString() +
|
||||
' ' + e.date.toLocaleString());
|
||||
});
|
||||
|
||||
console.log('TicToc launched');
|
Loading…
Add table
Add a link
Reference in a new issue