fixed zooming with new responsive design (closes #5)

This commit is contained in:
Steffen 2020-06-08 12:35:13 +02:00
parent 03a6e71dc3
commit d8b7a91402
No known key found for this signature in database
GPG Key ID: 764D74E98267DFC6
9 changed files with 78 additions and 53 deletions

View File

@ -10,7 +10,7 @@
: ''
}"
>
<transition name="zoom">
<transition name="blur">
<Intro v-if="!players.length"></Intro>
<TownInfo v-if="players.length && !session.nomination"></TownInfo>
<Vote v-if="session.nomination"></Vote>
@ -165,13 +165,13 @@ ul {
justify-content: center;
}
.zoom-enter-active,
.zoom-leave-active {
.blur-enter-active,
.blur-leave-active {
transition: all 250ms;
filter: blur(0);
}
.zoom-enter,
.zoom-leave-to {
.blur-enter,
.blur-leave-to {
opacity: 0;
filter: blur(20px);
}

View File

@ -57,12 +57,12 @@
<li v-if="players.length">
<em>
<font-awesome-icon
@click="setZoom(grimoire.zoom - 0.1)"
@click="setZoom(grimoire.zoom - 1)"
icon="search-minus"
/>
{{ Math.round(grimoire.zoom * 100) }}%
{{ Math.round(100 + grimoire.zoom * 10) }}%
<font-awesome-icon
@click="setZoom(grimoire.zoom + 0.1)"
@click="setZoom(grimoire.zoom + 1)"
icon="search-plus"
/>
</em>

View File

@ -1,5 +1,5 @@
<template>
<li>
<li :style="zoom">
<div
ref="player"
class="player"
@ -7,7 +7,7 @@
{
dead: player.isDead,
'no-vote': player.isVoteless,
you: player.id === session.playerId,
you: session.sessionId && player.id && player.id === session.playerId,
'vote-yes': session.votes[index],
'vote-lock': voteLocked
},
@ -82,7 +82,11 @@
</div>
<!-- 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 -->
<font-awesome-icon
@ -192,6 +196,17 @@ export default {
const indexAdjusted =
(this.index - 1 + players - session.nomination[1]) % players;
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() {
@ -567,6 +582,7 @@ li.move:not(.from) .player .overlay svg.move {
/***** Player name *****/
.player > .name {
text-align: center;
font-size: 120%;
line-height: 120%;
cursor: pointer;
@ -789,20 +805,18 @@ li.move:not(.from) .player .overlay svg.move {
color: black;
font-size: 45%;
font-weight: bold;
position: absolute;
width: 90%;
text-align: center;
margin-top: 25%;
margin-top: 50%;
}
.icon,
&:after {
content: " ";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
width: 90%;
height: 90%;
background-size: 100%;
background-position: center 0;
background-repeat: no-repeat;
@ -821,6 +835,9 @@ li.move:not(.from) .player .overlay svg.move {
&:after {
display: none;
}
.icon {
top: auto;
}
}
&.custom {

View File

@ -16,7 +16,6 @@ export default {
async capture({ x = 0, y = 0, width = 0, height = 0 }) {
const canvas = this.$refs.canvas;
const video = this.$refs.video;
const zoom = this.$store.state.grimoire.zoom;
// start capturing
if (!this.stream || !this.stream.active) {
alert(
@ -40,18 +39,18 @@ export default {
video.play();
setTimeout(() => {
const context = canvas.getContext("2d");
canvas.setAttribute("width", width * zoom || video.videoWidth);
canvas.setAttribute("height", height * zoom || video.videoHeight);
canvas.setAttribute("width", width || video.videoWidth);
canvas.setAttribute("height", height || video.videoHeight);
context.drawImage(
video,
x * zoom || 0,
y * zoom || 0,
width * zoom || video.videoWidth,
height * zoom || video.videoHeight,
x || 0,
y || 0,
width || video.videoWidth,
height || video.videoHeight,
0,
0,
width * zoom || video.videoWidth,
height * zoom || video.videoHeight
width || video.videoWidth,
height || video.videoHeight
);
canvas.toBlob(blob => {
try {

View File

@ -26,7 +26,7 @@
width="150"
x="66.6%"
text-anchor="middle"
class="label"
class="label mozilla"
v-bind:font-size="role.name | nameToFontSize"
>
<textPath xlink:href="#curve">
@ -57,7 +57,7 @@ export default {
return {};
},
filters: {
nameToFontSize: name => (name && name.length > 10 ? "85%" : "110%")
nameToFontSize: name => (name && name.length > 10 ? "90%" : "110%")
},
methods: {
setRole() {
@ -141,6 +141,16 @@ export default {
font-weight: bold;
text-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
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);
}
}
}
}

View File

@ -7,7 +7,6 @@
spectator: session.isSpectator,
vote: session.nomination
}"
v-bind:style="{ zoom: grimoire.zoom }"
>
<ul class="circle" v-bind:class="['size-' + players.length]">
<Player
@ -167,11 +166,10 @@ export default {
> li {
position: absolute;
top: 0;
left: 50%;
height: 50%;
transform-origin: 0 100%;
text-align: center;
pointer-events: none;
&:hover {
z-index: 25 !important;
@ -180,10 +178,12 @@ export default {
> .player {
margin-left: -50%;
width: 100%;
pointer-events: all;
}
> .reminder {
margin-left: -25%;
width: 50%;
pointer-events: all;
}
}
}
@ -192,17 +192,7 @@ export default {
$angle: (360 / $item-count);
$rot: 0;
// general token size depending on player count
@if $item-count < 7 {
width: 8vw;
} @else if($item-count <= 10) {
width: 7vw;
} @else if($item-count <= 15) {
width: 6vw;
} @else {
width: 5vw;
}
// rotation and tooltip placement
@for $i from 1 through $item-count {
&:nth-child(#{$i}) {
transform: rotate($rot * 1deg);
@ -224,6 +214,8 @@ export default {
> * {
transform: rotate($rot * -1deg);
}
// animation cascade
.life,
.token,
.shroud,

View File

@ -21,7 +21,7 @@
'.png')})`
}"
></span>
{{ reminder.name }}
<span class="text">{{ reminder.name }}</span>
</li>
</ul>
</Modal>
@ -83,31 +83,38 @@ ul.reminders .reminder {
background-size: 100%;
width: 100px;
height: 100px;
color: black;
font-size: 65%;
font-weight: bold;
display: block;
display: flex;
justify-content: center;
align-items: center;
margin: 5px;
text-align: center;
border-radius: 50%;
border: 3px solid black;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
cursor: pointer;
padding: 70px 9px 0;
line-height: 100%;
transition: transform 500ms ease;
.icon {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
width: 90%;
height: 90%;
background-size: 100%;
background-position: center 0;
background-repeat: no-repeat;
}
.text {
color: black;
font-size: 65%;
font-weight: bold;
text-align: center;
top: 28%;
width: 80%;
line-height: 1;
}
&:hover {
transform: scale(1.2);
}

View File

@ -34,7 +34,7 @@ export default new Vuex.Store({
isMenuOpen: false,
isScreenshot: false,
isScreenshotSuccess: false,
zoom: 1,
zoom: 0,
background: "",
bluffs: []
},

View File

@ -60,7 +60,7 @@ module.exports = store => {
}
break;
case "setZoom":
if (payload !== 1) {
if (payload !== 0) {
localStorage.setItem("zoom", payload);
} else {
localStorage.removeItem("zoom");