mirror of https://github.com/bra1n/townsquare.git
fixed zooming with new responsive design (closes #5)
This commit is contained in:
parent
03a6e71dc3
commit
d8b7a91402
10
src/App.vue
10
src/App.vue
|
@ -10,7 +10,7 @@
|
||||||
: ''
|
: ''
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<transition name="zoom">
|
<transition name="blur">
|
||||||
<Intro v-if="!players.length"></Intro>
|
<Intro v-if="!players.length"></Intro>
|
||||||
<TownInfo v-if="players.length && !session.nomination"></TownInfo>
|
<TownInfo v-if="players.length && !session.nomination"></TownInfo>
|
||||||
<Vote v-if="session.nomination"></Vote>
|
<Vote v-if="session.nomination"></Vote>
|
||||||
|
@ -165,13 +165,13 @@ ul {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zoom-enter-active,
|
.blur-enter-active,
|
||||||
.zoom-leave-active {
|
.blur-leave-active {
|
||||||
transition: all 250ms;
|
transition: all 250ms;
|
||||||
filter: blur(0);
|
filter: blur(0);
|
||||||
}
|
}
|
||||||
.zoom-enter,
|
.blur-enter,
|
||||||
.zoom-leave-to {
|
.blur-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
filter: blur(20px);
|
filter: blur(20px);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,12 +57,12 @@
|
||||||
<li v-if="players.length">
|
<li v-if="players.length">
|
||||||
<em>
|
<em>
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
@click="setZoom(grimoire.zoom - 0.1)"
|
@click="setZoom(grimoire.zoom - 1)"
|
||||||
icon="search-minus"
|
icon="search-minus"
|
||||||
/>
|
/>
|
||||||
{{ Math.round(grimoire.zoom * 100) }}%
|
{{ Math.round(100 + grimoire.zoom * 10) }}%
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
@click="setZoom(grimoire.zoom + 0.1)"
|
@click="setZoom(grimoire.zoom + 1)"
|
||||||
icon="search-plus"
|
icon="search-plus"
|
||||||
/>
|
/>
|
||||||
</em>
|
</em>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<li>
|
<li :style="zoom">
|
||||||
<div
|
<div
|
||||||
ref="player"
|
ref="player"
|
||||||
class="player"
|
class="player"
|
||||||
|
@ -7,7 +7,7 @@
|
||||||
{
|
{
|
||||||
dead: player.isDead,
|
dead: player.isDead,
|
||||||
'no-vote': player.isVoteless,
|
'no-vote': player.isVoteless,
|
||||||
you: player.id === session.playerId,
|
you: session.sessionId && player.id && player.id === session.playerId,
|
||||||
'vote-yes': session.votes[index],
|
'vote-yes': session.votes[index],
|
||||||
'vote-lock': voteLocked
|
'vote-lock': voteLocked
|
||||||
},
|
},
|
||||||
|
@ -82,7 +82,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Claimed seat icon -->
|
<!-- Claimed seat icon -->
|
||||||
<font-awesome-icon icon="chair" v-if="player.id" class="seat" />
|
<font-awesome-icon
|
||||||
|
icon="chair"
|
||||||
|
v-if="player.id && session.sessionId"
|
||||||
|
class="seat"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Ghost vote icon -->
|
<!-- Ghost vote icon -->
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
|
@ -192,6 +196,17 @@ export default {
|
||||||
const indexAdjusted =
|
const indexAdjusted =
|
||||||
(this.index - 1 + players - session.nomination[1]) % players;
|
(this.index - 1 + players - session.nomination[1]) % players;
|
||||||
return indexAdjusted < session.lockedVote - 1;
|
return indexAdjusted < session.lockedVote - 1;
|
||||||
|
},
|
||||||
|
zoom: function() {
|
||||||
|
if (this.players.length < 7) {
|
||||||
|
return { width: 9 + this.grimoire.zoom + "vw" };
|
||||||
|
} else if (this.players.length <= 10) {
|
||||||
|
return { width: 8 + this.grimoire.zoom + "vw" };
|
||||||
|
} else if (this.players.length <= 15) {
|
||||||
|
return { width: 7 + this.grimoire.zoom + "vw" };
|
||||||
|
} else {
|
||||||
|
return { width: 6 + this.grimoire.zoom + "vw" };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -567,6 +582,7 @@ li.move:not(.from) .player .overlay svg.move {
|
||||||
|
|
||||||
/***** Player name *****/
|
/***** Player name *****/
|
||||||
.player > .name {
|
.player > .name {
|
||||||
|
text-align: center;
|
||||||
font-size: 120%;
|
font-size: 120%;
|
||||||
line-height: 120%;
|
line-height: 120%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -789,20 +805,18 @@ li.move:not(.from) .player .overlay svg.move {
|
||||||
color: black;
|
color: black;
|
||||||
font-size: 45%;
|
font-size: 45%;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
position: absolute;
|
|
||||||
width: 90%;
|
width: 90%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 25%;
|
margin-top: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon,
|
.icon,
|
||||||
&:after {
|
&:after {
|
||||||
content: " ";
|
content: " ";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 90%;
|
||||||
height: 100%;
|
height: 90%;
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-position: center 0;
|
background-position: center 0;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -821,6 +835,9 @@ li.move:not(.from) .player .overlay svg.move {
|
||||||
&:after {
|
&:after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.icon {
|
||||||
|
top: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.custom {
|
&.custom {
|
||||||
|
|
|
@ -16,7 +16,6 @@ export default {
|
||||||
async capture({ x = 0, y = 0, width = 0, height = 0 }) {
|
async capture({ x = 0, y = 0, width = 0, height = 0 }) {
|
||||||
const canvas = this.$refs.canvas;
|
const canvas = this.$refs.canvas;
|
||||||
const video = this.$refs.video;
|
const video = this.$refs.video;
|
||||||
const zoom = this.$store.state.grimoire.zoom;
|
|
||||||
// start capturing
|
// start capturing
|
||||||
if (!this.stream || !this.stream.active) {
|
if (!this.stream || !this.stream.active) {
|
||||||
alert(
|
alert(
|
||||||
|
@ -40,18 +39,18 @@ export default {
|
||||||
video.play();
|
video.play();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const context = canvas.getContext("2d");
|
const context = canvas.getContext("2d");
|
||||||
canvas.setAttribute("width", width * zoom || video.videoWidth);
|
canvas.setAttribute("width", width || video.videoWidth);
|
||||||
canvas.setAttribute("height", height * zoom || video.videoHeight);
|
canvas.setAttribute("height", height || video.videoHeight);
|
||||||
context.drawImage(
|
context.drawImage(
|
||||||
video,
|
video,
|
||||||
x * zoom || 0,
|
x || 0,
|
||||||
y * zoom || 0,
|
y || 0,
|
||||||
width * zoom || video.videoWidth,
|
width || video.videoWidth,
|
||||||
height * zoom || video.videoHeight,
|
height || video.videoHeight,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
width * zoom || video.videoWidth,
|
width || video.videoWidth,
|
||||||
height * zoom || video.videoHeight
|
height || video.videoHeight
|
||||||
);
|
);
|
||||||
canvas.toBlob(blob => {
|
canvas.toBlob(blob => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
width="150"
|
width="150"
|
||||||
x="66.6%"
|
x="66.6%"
|
||||||
text-anchor="middle"
|
text-anchor="middle"
|
||||||
class="label"
|
class="label mozilla"
|
||||||
v-bind:font-size="role.name | nameToFontSize"
|
v-bind:font-size="role.name | nameToFontSize"
|
||||||
>
|
>
|
||||||
<textPath xlink:href="#curve">
|
<textPath xlink:href="#curve">
|
||||||
|
@ -57,7 +57,7 @@ export default {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
nameToFontSize: name => (name && name.length > 10 ? "85%" : "110%")
|
nameToFontSize: name => (name && name.length > 10 ? "90%" : "110%")
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setRole() {
|
setRole() {
|
||||||
|
@ -141,6 +141,16 @@ export default {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
|
text-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
|
|
||||||
|
@-moz-document url-prefix() {
|
||||||
|
&.mozilla {
|
||||||
|
// Vue doesn't support scoped media queries, so we have to use a second css class
|
||||||
|
stroke: none;
|
||||||
|
text-shadow: none;
|
||||||
|
filter: drop-shadow(0 2px 0 white) drop-shadow(0 -2px 0 white)
|
||||||
|
drop-shadow(2px 0 0 white) drop-shadow(-2px 0 0 white);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
spectator: session.isSpectator,
|
spectator: session.isSpectator,
|
||||||
vote: session.nomination
|
vote: session.nomination
|
||||||
}"
|
}"
|
||||||
v-bind:style="{ zoom: grimoire.zoom }"
|
|
||||||
>
|
>
|
||||||
<ul class="circle" v-bind:class="['size-' + players.length]">
|
<ul class="circle" v-bind:class="['size-' + players.length]">
|
||||||
<Player
|
<Player
|
||||||
|
@ -167,11 +166,10 @@ export default {
|
||||||
|
|
||||||
> li {
|
> li {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
|
||||||
left: 50%;
|
left: 50%;
|
||||||
height: 50%;
|
height: 50%;
|
||||||
transform-origin: 0 100%;
|
transform-origin: 0 100%;
|
||||||
text-align: center;
|
pointer-events: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
z-index: 25 !important;
|
z-index: 25 !important;
|
||||||
|
@ -180,10 +178,12 @@ export default {
|
||||||
> .player {
|
> .player {
|
||||||
margin-left: -50%;
|
margin-left: -50%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
> .reminder {
|
> .reminder {
|
||||||
margin-left: -25%;
|
margin-left: -25%;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,17 +192,7 @@ export default {
|
||||||
$angle: (360 / $item-count);
|
$angle: (360 / $item-count);
|
||||||
$rot: 0;
|
$rot: 0;
|
||||||
|
|
||||||
// general token size depending on player count
|
// rotation and tooltip placement
|
||||||
@if $item-count < 7 {
|
|
||||||
width: 8vw;
|
|
||||||
} @else if($item-count <= 10) {
|
|
||||||
width: 7vw;
|
|
||||||
} @else if($item-count <= 15) {
|
|
||||||
width: 6vw;
|
|
||||||
} @else {
|
|
||||||
width: 5vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
@for $i from 1 through $item-count {
|
@for $i from 1 through $item-count {
|
||||||
&:nth-child(#{$i}) {
|
&:nth-child(#{$i}) {
|
||||||
transform: rotate($rot * 1deg);
|
transform: rotate($rot * 1deg);
|
||||||
|
@ -224,6 +214,8 @@ export default {
|
||||||
> * {
|
> * {
|
||||||
transform: rotate($rot * -1deg);
|
transform: rotate($rot * -1deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// animation cascade
|
||||||
.life,
|
.life,
|
||||||
.token,
|
.token,
|
||||||
.shroud,
|
.shroud,
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
'.png')})`
|
'.png')})`
|
||||||
}"
|
}"
|
||||||
></span>
|
></span>
|
||||||
{{ reminder.name }}
|
<span class="text">{{ reminder.name }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -83,31 +83,38 @@ ul.reminders .reminder {
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
color: black;
|
display: flex;
|
||||||
font-size: 65%;
|
justify-content: center;
|
||||||
font-weight: bold;
|
align-items: center;
|
||||||
display: block;
|
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
text-align: center;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 3px solid black;
|
border: 3px solid black;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 70px 9px 0;
|
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
transition: transform 500ms ease;
|
transition: transform 500ms ease;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 90%;
|
||||||
height: 100%;
|
height: 90%;
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-position: center 0;
|
background-position: center 0;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
color: black;
|
||||||
|
font-size: 65%;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
top: 28%;
|
||||||
|
width: 80%;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: scale(1.2);
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default new Vuex.Store({
|
||||||
isMenuOpen: false,
|
isMenuOpen: false,
|
||||||
isScreenshot: false,
|
isScreenshot: false,
|
||||||
isScreenshotSuccess: false,
|
isScreenshotSuccess: false,
|
||||||
zoom: 1,
|
zoom: 0,
|
||||||
background: "",
|
background: "",
|
||||||
bluffs: []
|
bluffs: []
|
||||||
},
|
},
|
||||||
|
|
|
@ -60,7 +60,7 @@ module.exports = store => {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "setZoom":
|
case "setZoom":
|
||||||
if (payload !== 1) {
|
if (payload !== 0) {
|
||||||
localStorage.setItem("zoom", payload);
|
localStorage.setItem("zoom", payload);
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem("zoom");
|
localStorage.removeItem("zoom");
|
||||||
|
|
Loading…
Reference in New Issue