Compass
Code is HERE
<template>
<div class="windrose" v-resize="onResize">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0" y="0" width="100%" height="100%" viewBox="0 0 500 500">
<g>
<circle cx="250" cy="250" r="205" class="ring" />
<circle cx="250" cy="250" r="205" class="tick major" pathLength="720"/>
<circle cx="250" cy="250" r="200" class="tick mid" pathLength="720"/>
<circle cx="250" cy="250" r="195" class="tick minor" pathLength="720"/>
</g>
<g>
<text transform="matrix(1 0 0 1 385 268)" class="letters">E</text>
<text transform="matrix(1 0 0 1 233 420)" class="letters">S</text>
<text transform="matrix(1 0 0 1 233 112)" class="letters">N</text>
<text transform="matrix(1 0 0 1 82 268)" class="letters">W</text>
</g>
</svg>
<div class="txt">
<div>{{formattedDirection}}</div>
<div class="small">DIRECTION</div>
<div class="small">SPEED</div>
<div>{{formattedSpeed}}</div>
</div>
<div ref="needle" class="needle" :style="{'rotate': direction +'deg'}"></div>
</div>
</template>
<script>
export default {
data() {
return {
direction:0,
speed:0,
timeout:null
}
},
watch: {
msg: function(){
if(this.msg?.payload != undefined){
if(this.msg.payload.direction != undefined){
this.direction = this.shortWayRotation(this.direction, this.msg.payload.direction)
if(this.msg.speed == undefined){
this.msg.speed = this.speed
}
}
if(this.msg.payload.speed != undefined){
this.speed = this.msg.payload.speed
if(this.msg.payload.direction == undefined){
this.msg.payload.direction = this.direction;
}
}
this.send({payload:this.msg.payload})
}
}
}
,
computed: {
formattedSpeed:function(){
return this.speed + "m/s"
},
formattedDirection:function(){
let r = (this.direction + 360) % 360;
if(r<0){
r += 360;
}
return r + "°"
}
},
methods: {
onResize(){
console.log('this',this)
},
shortWayRotation:function(frm, to){
let delta = ((((to - frm) % 360) + 540) % 360) - 180;
return (frm + delta);
},
manageAnimations:function(event){
if(document.hidden){
if(this.$refs.needle){
this.$refs.needle.style.transition = "rotate 0s"
}
}
else{
if(this.$refs.needle){
if(this.timeout){
clearTimeout(this.timeout)
this.timeout = null
}
this.timeout = setTimeout(()=>{
this.$refs.needle.style.transition = "rotate .5s"
},40)
}
}
}
},
mounted() {
document.addEventListener("visibilitychange", this.manageAnimations);
window.addEventListener("blur", this.manageAnimations);
window.addEventListener("focus", this.manageAnimations);
},
unmounted() {
if(this.timeout){
clearTimeout(this.timeout)
this.timeout = null
}
document.removeEventListener("visibilitychange", this.manageAnimations);
window.removeEventListener("blur", this.manageAnimations);
window.removeEventListener("focus", this.manageAnimations);
}
}
</script>
<style>
div:has(>.windrose){
align-items: center;
}
.windrose{
position:relative;
width:100%;
aspect-ratio: 1;
container-type: inline-size;
}
.tick {
fill: none;
stroke: currentColor;
}
.major{
stroke-dasharray:1 89;
stroke-dashoffset:0.5;
stroke-width:40px;
}
.mid{
stroke-dasharray:0 45 1 44 0 45 1 44;
stroke-dashoffset:0.5;
stroke-width:30px;
}
.minor{
stroke-dasharray:0 5 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4;
stroke-dashoffset:0.5;
stroke-width:20px;
}
.letters {
font-size: 48px;
fill:currentColor;
}
.ring{
fill:none;
stroke:currentColor;
stroke-width:40;
opacity:0.1;
}
.needle{
position: absolute;
inset: 0;
left: calc(50% - 1px);
width: 2px;
height: 100%;
transform-origin: center;
transition: rotate .5s;
}
.needle:before, .needle:after{
content: "▼";
color: red;
position: absolute;
top: 1%;
text-align: center;
font-size: clamp(0.5rem, 10cqi, 2rem);
transform: translateX(calc(-50% + 1px));
}
.needle:before{
color:currentColor;
font-size: calc(clamp(0.5rem, 10cqi, 2rem) + 4px);
}
.txt{
position:absolute;
inset:0;
display: grid;
place-content: center;
width: 100%;
text-align: center;
font-size: clamp(0.5rem, 12cqi, 3rem);
font-weight:700;
line-height:1.2em;
}
.txt .small{
font-size: clamp(0.2rem, 6cqi, 1.5rem);
line-height: 1em;
font-weight:500;
}
</style>
The payload for compass must be combined to have speed and direction properties. (previously was topic = "direction") This is changed to have porper wakeup on replayMessage.