Skip to content

Instantly share code, notes, and snippets.

@bitardev
Last active July 26, 2024 07:53
Show Gist options
  • Select an option

  • Save bitardev/1923baf4223db37dbe517b8b424160d2 to your computer and use it in GitHub Desktop.

Select an option

Save bitardev/1923baf4223db37dbe517b8b424160d2 to your computer and use it in GitHub Desktop.
This code is a key component of a website I had the privilege to develop as part of thier dev team. (You can find a brief in the comment section below)
<template>
<div class="product_component_wrapper" :style="$q.screen.width >= 1024 ? margin : '' ">
<div class="container-maxwidth2 flex justify-center">
<div class="col_preview">
<div class="preview_wrapper">
<img id="image" :src="imageName" alt=""/>
<!-- vue-magnifier :src="imageName" :src-large="imageName" / -->
</div>
</div>
<div class="col_features">
<q-scroll-area :style="$q.screen.width >= 1024 ? 'height: 600px':'height: 550px'" :visible="true" :class="{'q-pl-md q-pr-md': $q.screen.width >= 1024}">
<div class="flex justify-between q-pb-sm header-features" :class="{'q-pt-sm': $q.screen.width >= 1024, 'items-start': $q.screen.width < 1024}">
<span><b>{{$t('Customize your indoor shades.')}}</b></span>
<img src="statics/logo/logo-icon.svg" width="60px" alt="">
</div>
<div class="transparency_wrapper" :class="{'q-mt-sm': $q.screen.width >= 1024, 'q-pt-sm q-pb-sm': $q.screen.width < 1024}">
<div class="row option-row" :class="{'justify-between': $q.screen.width >= 1024}">
<div class="lab_holder flex items-center">
<label v-if="$q.screen.width >= 1024">{{ $t('Collection') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('Collection')" @click="transparencyToggleMobile = !transparencyToggleMobile ; canvasColorToggleMobile = false; shadeTypeToggleMobile = false; mountStyleToggleMobile = false; ambientLightingToggleMobile = false; potsLightingToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="transparencyToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || canvasColorToggleMobile" class="val_holder q-pr-xs flex justify-end">
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn black" :class="collectionType === 'modern' ? 'active':''" :label="$t('modern_collection')" @click="collectionType = 'modern'" />
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn grey" :class="collectionType === 'deco' ? 'active':''" :label="$t('deco_collection')" @click="collectionType = 'deco'" />
</div>
</div>
</div>
<div class="transparency_wrapper" :class="{'q-mt-sm': $q.screen.width >= 1024, 'q-pt-sm q-pb-sm': $q.screen.width < 1024}">
<div class="row option-row">
<div class="col lab_holder flex items-center">
<label v-if="$q.screen.width >= 1024">{{ $t('transparency') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('transparency')" @click="transparencyToggleMobile = !transparencyToggleMobile ; canvasColorToggleMobile = false; shadeTypeToggleMobile = false; mountStyleToggleMobile = false; ambientLightingToggleMobile = false; potsLightingToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="transparencyToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || transparencyToggleMobile" class="flex justify-end items-center col val_holder q-pr-lg">
<!-- <span class="transparencyModelLabel q-mr-xl">{{ $t(transparencyLabel) }}</span> -->
<div class="column justify-center items-end ">
<q-slider
v-model="transparencyModel"
markers
:min="0"
:step="1"
:max="4"
/>
<span class="markers_wrapper flex justify-between">
<i>0%</i>
<i v-if="collectionType === 'deco'">1/2%</i>
<i>1%</i>
<i>3%</i>
<i>5%</i>
<i v-if="collectionType === 'modern'">10%</i>
</span>
</div>
</div>
</div>
</div>
<div v-if="collectionType === 'modern'" class="colors_wrapper border_top">
<div class="row option-row" :class="{'justify-between': $q.screen.width >= 1024}">
<div class="lab_holder flex items-center" :class="{'col': $q.screen.width < 1024}">
<label v-if="$q.screen.width >= 1024">{{ $t('canvas_color') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('canvas_color')" @click="canvasColorToggleMobile = !canvasColorToggleMobile ; transparencyToggleMobile = false; shadeTypeToggleMobile = false; mountStyleToggleMobile = false; ambientLightingToggleMobile = false; potsLightingToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="canvasColorToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || canvasColorToggleMobile" class="col val_holder q-pr-xs flex justify-end">
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img white" :class="activeColor.white" @click="canvasColor('white')">
<img src="statics/fabric-collection/simulator/White.jpg" class="" alt="">
<q-tooltip>
{{ $t('White') }}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img off-white" :class="activeColor.white_linen" @click="canvasColor('white_linen')">
<img src="statics/fabric-collection/simulator/White-Linen.jpg" class="" alt="">
<q-tooltip>
{{ $t('White-Linen') }}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img grey" :class="activeColor.white_pearl" @click="canvasColor('white_pearl')">
<img src="statics/fabric-collection/simulator/White-Grey.jpg" class="" alt="">
<q-tooltip>
{{ $t('White-Pearl') }}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img black" :class="activeColor.black" @click="canvasColor('black')">
<img src="statics/fabric-collection/simulator/Ebony.jpg" class="" alt="">
<q-tooltip>
{{ $t('Ebony') }}
</q-tooltip>
</q-btn>
</div>
</div>
</div>
<div v-else class="colors_wrapper border_top">
<div class="row option-row" :class="{'justify-between': $q.screen.width >= 1024}">
<div class="lab_holder flex items-center" :class="{'col': $q.screen.width < 1024}">
<label v-if="$q.screen.width >= 1024">{{ $t('canvas_color') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('canvas_color')" @click="canvasColorToggleMobile = !canvasColorToggleMobile ; transparencyToggleMobile = false; shadeTypeToggleMobile = false; mountStyleToggleMobile = false; ambientLightingToggleMobile = false; potsLightingToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="canvasColorToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || canvasColorToggleMobile" class="col val_holder q-pr-xs flex justify-end">
<template v-if="transparencyModel === 0 || transparencyModel === 1">
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img eclipse" :class="activeColor.eclipse" @click="canvasColor('eclipse')">
<img src="statics/fabric-collection/simulator/Eclipse.jpg" class="" alt="">
<q-tooltip>
{{ $t('Eclipse')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img stardust" :class="activeColor.stardust" @click="canvasColor('stardust')">
<img src="statics/fabric-collection/simulator/Stardust.jpg" class="" alt="">
<q-tooltip>
{{ $t('Stardust')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img orion" :class="activeColor.orion" @click="canvasColor('orion')">
<img src="statics/fabric-collection/simulator/Orion.jpg" class="" alt="">
<q-tooltip>
{{ $t('Orion')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img nova" :class="activeColor.nova" @click="canvasColor('nova')">
<img src="statics/fabric-collection/simulator/Nova.jpg" class="" alt="">
<q-tooltip>
{{ $t('Nova')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img luna" :class="activeColor.luna" @click="canvasColor('luna')">
<img src="statics/fabric-collection/simulator/Luna.jpg" class="" alt="">
<q-tooltip>
{{ $t('Luna')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img polaris" :class="activeColor.polaris" @click="canvasColor('polaris')">
<img src="statics/fabric-collection/simulator/Polaris.jpg" class="" alt="">
<q-tooltip>
{{ $t('Polaris')}}
</q-tooltip>
</q-btn>
</template>
<template v-if="transparencyModel !== 0 && transparencyModel !== 1 && transparencyModel !== 5">
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img latte" :class="activeColor.latte" @click="canvasColor('latte')">
<img src="statics/fabric-collection/simulator/Latte.jpg" class="" alt="">
<q-tooltip>
{{ $t('Latte')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img cappuccino" :class="activeColor.cappuccino" @click="canvasColor('cappuccino')">
<img src="statics/fabric-collection/simulator/Cappuccino.jpg" class="" alt="">
<q-tooltip>
{{ $t('Cappuccino')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img mocha" :class="activeColor.mocha" @click="canvasColor('mocha')">
<img src="statics/fabric-collection/simulator/Mocha.jpg" class="" alt="">
<q-tooltip>
{{ $t('Mocha')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img espresso" :class="activeColor.espresso" @click="canvasColor('espresso')">
<img src="statics/fabric-collection/simulator/Espresso.jpg" class="" alt="">
<q-tooltip>
{{ $t('Espresso')}}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img toffee" :class="activeColor.toffee" @click="canvasColor('toffee')">
<img src="statics/fabric-collection/simulator/Toffee.jpg" class="" alt="">
<q-tooltip>
{{ $t('Toffee')}}
</q-tooltip>
</q-btn>
</template>
</div>
</div>
</div>
<div class="ambient_lighting_wrapper border_top">
<div class="row option-row">
<div class="col lab_holder flex items-center">
<label v-if="$q.screen.width >= 1024">{{ $t('shade_type') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('shade_type')" @click="shadeTypeToggleMobile = !shadeTypeToggleMobile ; canvasColorToggleMobile = false; transparencyToggleMobile = false; mountStyleToggleMobile = false; ambientLightingToggleMobile = false; potsLightingToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="shadeTypeToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || shadeTypeToggleMobile" class="col val_holder col-8 q-pr-xs flex justify-end">
<q-btn-toggle
unelevated
no-caps
v-model="shadeTypeModel"
toggle-color="black"
round
@click="fasciaNoFascia()"
:options="[
{label: $t('open_roll'), value: 'openroll' },
{label: $t('enclosed'), value: 'enclosed' }
]"
/>
</div>
</div>
</div>
<div class="colors_wrapper border_top">
<div class="row option-row" :class="{'justify-between': $q.screen.width >= 1024}">
<div class="lab_holder flex items-center" :class="{'col': $q.screen.width < 1024}">
<label v-if="$q.screen.width >= 1024">{{ $t('Hardware Color') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('Hardware Color')" @click="canvasColorToggleMobile = !canvasColorToggleMobile ; transparencyToggleMobile = false; shadeTypeToggleMobile = false; mountStyleToggleMobile = false; ambientLightingToggleMobile = false; potsLightingToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="canvasColorToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || canvasColorToggleMobile" class="col val_holder q-pr-xs flex justify-end">
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img black" :class="hardwareColor === 'black' ? 'active':''" @click="hardwareColor = 'black'">
<span class="black"></span>
<q-tooltip>
{{ $t('Black2') }}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img gray" :class="hardwareColor === 'gray' ? 'active':''" @click="hardwareColor = 'gray'">
<span class="gray"></span>
<q-tooltip>
{{ $t('Gray') }}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img white" :class="hardwareColor === 'white' ? 'active':''" @click="hardwareColor = 'white'">
<span class="white"></span>
<q-tooltip>
{{ $t('White') }}
</q-tooltip>
</q-btn>
<q-btn text-color="black" color="white" unelevated no-caps class="color_btn fabric-btn-img vanilla" :class="hardwareColor === 'vanilla' ? 'active':''" @click="hardwareColor = 'vanilla'">
<span class="vanilla"></span>
<q-tooltip>
{{ $t('Vanilla') }}
</q-tooltip>
</q-btn>
</div>
</div>
</div>
<div class="ambient_lighting_wrapper border_top">
<div class="row option-row">
<div class="col lab_holder flex items-center">
<label v-if="$q.screen.width >= 1024">{{ $t('mount_style') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('mount_style')" @click="mountStyleToggleMobile = !mountStyleToggleMobile ; canvasColorToggleMobile = false; shadeTypeToggleMobile = false; transparencyToggleMobile = false; ambientLightingToggleMobile = false; potsLightingToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="mountStyleToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || mountStyleToggleMobile" class="col val_holder col-8 q-pr-xs flex justify-end">
<q-btn-toggle
unelevated
no-caps
v-model="mountModel"
toggle-color="black"
round
:options="[
{label: $t('inside'), value: true },
{label: $t('outside'), value: false }
]"
/>
</div>
</div>
</div>
<div class="ambient_lighting_wrapper border_top">
<div class="row option-row">
<div class="col lab_holder flex items-center">
<label v-if="$q.screen.width >= 1024">{{ $t('ambient_lighting') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('ambient_lighting')" @click="ambientLightingToggleMobile = !ambientLightingToggleMobile ; canvasColorToggleMobile = false; shadeTypeToggleMobile = false; mountStyleToggleMobile = false; transparencyToggleMobile = false; potsLightingToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="ambientLightingToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || ambientLightingToggleMobile" class="col val_holder col-8 q-pr-xs flex justify-end">
<q-btn-toggle
unelevated
no-caps
v-model="ambientLightingModel"
toggle-color="black"
round
:options="[
{label: $t('day'), value: true },
{label: $t('night'), value: false }
]"
/>
</div>
</div>
</div>
<div class="ambient_lighting_wrapper border_top">
<div class="row option-row">
<div class="col lab_holder flex items-center">
<label v-if="$q.screen.width >= 1024">{{ $t('pots_lighting') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('pots_lighting')" @click="potsLightingToggleMobile = !potsLightingToggleMobile ; canvasColorToggleMobile = false; shadeTypeToggleMobile = false; mountStyleToggleMobile = false; ambientLightingToggleMobile = false; transparencyToggleMobile = false; viewingAngleToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="potsLightingToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || potsLightingToggleMobile" class="col val_holder col-8 q-pr-xs flex justify-end">
<q-btn-toggle
unelevated
no-caps
v-model="potsLightingModel"
toggle-color="black"
round
:options="[
{label: $t('on'), value: true },
{label: $t('off'), value: false }
]"
/>
</div>
</div>
</div>
<div class="viewing_angles_wrapper border_top">
<div class="row option-row">
<div class="col lab_holder flex items-center">
<label v-if="$q.screen.width >= 1024">{{ $t('viewing_angle') }}</label>
<q-btn v-else flat no-caps unelevated :label="$t('viewing_angle')" @click="viewingAngleToggleMobile = !viewingAngleToggleMobile ; canvasColorToggleMobile = false; shadeTypeToggleMobile = false; mountStyleToggleMobile = false; ambientLightingToggleMobile = false; potsLightingToggleMobile = false; transparencyToggleMobile = false" color="white" text-color="black" align="left" class="full-width nav_item parent" :icon-right="viewingAngleToggleMobile ? 'keyboard_arrow_up':'keyboard_arrow_down'" />
</div>
<div v-if="$q.screen.width >= 1024 || viewingAngleToggleMobile" class="col val_holder col-8 q-pr-xs flex justify-end">
<q-btn-toggle
unelevated
no-caps
v-model="viewingAnglesModel"
toggle-color="black"
round
:options="[
{label: $t('front'), value: 'front' },
{label: $t('side'), value: 'side' },
{label: $t('outside2'), value: 'outside' }
]"
/>
</div>
</div>
</div>
<div class="flex justify-between q-pt-lg footer-features">
<span>{{$t('Color Picker is for illustrative ...')}}</span>
</div>
</q-scroll-area>
</div>
</div>
</div>
</template>
<script>
// import vueMagnifier from 'components/vueMagnifier'
import { openURL } from 'quasar'
export default {
name: 'VirtualSimulator',
components: {
// vueMagnifier
},
data () {
return {
transparencyToggleMobile: false,
canvasColorToggleMobile: false,
shadeTypeToggleMobile: false,
mountStyleToggleMobile: false,
ambientLightingToggleMobile: false,
potsLightingToggleMobile: false,
viewingAngleToggleMobile: false,
email: '<a href="mailto:info@clarashades.com?subject=Contact Clara for the technical specifications">info@Clarashades.com</a>',
fixedClassOnMobile: '',
activeColor: {
black: 'active',
white: null,
white_pearl: null,
white_linen: null,
latte: null,
toffee: null,
cappuccino: null,
mocha: null,
espresso: null,
polaris: null,
luna: null,
stardust: null,
orion: null,
eclipse: null,
nova: null
},
style: {
label: null,
code: null,
features: null
},
shadeTypeModel: 'enclosed',
layout: this.$route.params.layout,
margin: '',
moreDetailIcon: 'keyboard_arrow_down',
showMoreDetailTab: false,
tab: 'features',
transparencyModel: 0,
hardwareColor: 'black',
collectionType: 'modern',
transparencyLabel: 'Blackout',
transparencyCode: 'blackout',
ambientLightingModel: false,
ambientLightingLabel: 'Night',
ambientLightingCode: 'EL_',
potsLightingModel: false,
potsLightingLabel: 'Off',
potsLightingCode: 'LOFF_',
viewingAnglesModel: 'side',
viewingAnglesLabel: 'Side',
viewingAnglesCode: '_SV_',
canvasColorModel: 'Ebony',
canvasColorLabel: 'Ebony',
canvasColorCode: 'Ebony',
mountModel: false,
mountLabel: 'Outside',
mountCode: 'outside_'
}
},
computed: {
imageName: function () {
// statics/simulator-renders/
let renderURL = ''
if (this.viewingAnglesModel === 'outside') {
renderURL = 'https://storage.googleapis.com/shade-simulator/Shade_Ext_view/' +
(this.transparencyCode === 'blackout' ? 'White' : ((this.collectionType === 'deco' && this.transparencyCode !== '0_5p') ? 'Latte' : this.canvasColorCode)) +
this.viewingAnglesCode +
(this.ambientLightingCode) +
('LOFF_') + // HUGO this need to edit for this.potsLightingModel ? 'ON' : 'OFF'
'outside_NO-fascia_' +
this.transparencyCode +
'.jpg'
} else {
renderURL = 'https://storage.googleapis.com/shade-simulator/' +
(this.ambientLightingModel ? 'DayLight' : 'EveningLight') +
'_Light-' +
(this.potsLightingModel ? 'ON' : 'OFF') +
'/' +
(this.viewingAnglesModel === 'front' ? 'Front' : this.viewingAnglesModel === 'side' ? 'Side' : 'Outside') +
'-view-' +
(this.mountLabel === 'Inside' ? 'Inside' : 'Outside') +
'-with-' +
(this.shadeTypeModel === 'enclosed' ? 'Fascia' : 'NO-Fascia') +
'-hardware-' +
this.hardwareColor +
'/' +
this.canvasColorCode +
this.viewingAnglesCode +
this.ambientLightingCode +
(this.potsLightingModel ? 'LON_' : 'LOFF_') +
this.mountCode +
this.style.code +
this.transparencyCode +
'.jpg'
}
// console.log([this.canvasColorCode,
// this.viewingAnglesCode,
// this.ambientLightingCode,
// this.potsLightingModel,
// this.mountCode,
// this.style.code,
// this.transparencyCode])
return renderURL
}
},
created () {
this.fasciaNoFascia()
this.layout !== 'main' ? this.margin = 'margin-top: 0px!; margin: 16px 16px;' : this.margin = 'margin-top: 50px!; padding: 100px 0px;'
// console.log('this.layout', this.layout)
},
watch: {
'$route.params.style' () {
this.fasciaNoFascia()
},
collectionType: function (val) {
if (val === 'modern') {
this.transparencyModel = 0
this.transparencyLabel = 'Blackout'
this.transparencyCode = 'blackout'
this.canvasColor('White')
}
if (val === 'deco') {
this.transparencyModel = 0
this.transparencyLabel = 'Blackout'
this.transparencyCode = 'blackout'
this.canvasColor('Polaris')
}
},
transparencyModel: function (val) {
if (this.collectionType === 'deco' && (val === 2 || val === 3 || val === 4) && !['Cappuccino', 'Expresso', 'Mocha', 'Latte', 'Toffee'].find((c) => c === this.canvasColorCode)) {
this.canvasColor('Toffee')
}
if (this.collectionType === 'deco' && (val === 0 || val === 1) && !['Eclipse', 'Stardust', 'Orion', 'Nova', 'Luna', 'Polaris'].find((c) => c === this.canvasColorCode)) {
this.canvasColor('Polaris')
}
if (val === 0) {
this.transparencyModel = 0
this.transparencyLabel = 'Blackout'
this.transparencyCode = 'blackout'
}
if (val === 1 && this.collectionType === 'modern') {
this.transparencyModel = 1
this.transparencyLabel = '1%'
this.transparencyCode = '01p'
} else if (val === 1 && this.collectionType === 'deco') {
this.transparencyModel = 1
this.transparencyLabel = '1/2%'
this.transparencyCode = '0_5p'
}
if (val === 2 && this.collectionType === 'modern') {
this.transparencyModel = 2
this.transparencyLabel = '3%'
this.transparencyCode = '03p'
} else if (val === 2 && this.collectionType === 'deco') {
this.transparencyModel = 2
this.transparencyLabel = '1%'
this.transparencyCode = '01p'
}
if (val === 3 && this.collectionType === 'modern') {
this.transparencyModel = 3
this.transparencyLabel = '5%'
this.transparencyCode = '05p'
} else if (val === 3 && this.collectionType === 'deco') {
this.transparencyModel = 3
this.transparencyLabel = '3%'
this.transparencyCode = '03p'
}
if (val === 4 && this.collectionType === 'modern') {
this.transparencyModel = 4
this.transparencyLabel = '10%'
this.transparencyCode = '10p'
} else if (val === 4 && this.collectionType === 'deco') {
this.transparencyModel = 4
this.transparencyLabel = '5%'
this.transparencyCode = '05p'
}
},
mountModel: function (val) {
if (val) {
this.mountLabel = 'Inside'
this.mountCode = 'inside_'
} else {
this.mountLabel = 'Outside'
this.mountCode = 'outside_'
}
},
ambientLightingModel: function (val) {
if (val) {
this.ambientLightingLabel = 'Day'
this.ambientLightingCode = 'DL_'
} else {
this.ambientLightingLabel = 'Night'
this.ambientLightingCode = 'EL_'
}
if (val && this.viewingAnglesModel === 'outside') {
this.ambientLightingLabel = 'Day'
this.ambientLightingCode = 'DL_'
this.potsLightingLabel = 'Off'
this.potsLightingCode = 'LOFF_'
}
if (!val && this.viewingAnglesModel === 'outside') {
this.ambientLightingLabel = 'Night'
this.ambientLightingCode = 'EL_'
this.potsLightingLabel = 'Off'
this.potsLightingCode = 'LOFF_'
}
// console.log('this.ambientLightingCode', this.ambientLightingCode)
},
potsLightingModel: function (val) {
// console.log('viewingAnglesModel', this.viewingAnglesModel)
if (val) {
this.potsLightingLabel = 'On'
this.potsLightingCode = 'LON_'
} else {
this.potsLightingLabel = 'Off'
this.potsLightingCode = 'LOFF_'
}
if (this.viewingAnglesModel === 'outside') {
this.potsLightingLabel = 'Off'
this.potsLightingCode = 'LOFF_'
}
},
viewingAnglesModel: function (val) {
if (val === 'front') {
this.viewingAnglesLabel = 'Front'
this.viewingAnglesCode = '_FV_'
} else if (val === 'side') {
this.viewingAnglesLabel = 'Side'
this.viewingAnglesCode = '_SV_'
} else {
this.viewingAnglesLabel = 'Outside'
this.viewingAnglesCode = '_OUT_'
this.potsLightingLabel = 'Off'
this.potsLightingCode = 'LOFF_'
if (this.ambientLightingLabel === 'Day') {
this.ambientLightingLabel = 'Day'
this.ambientLightingCode = 'DL_'
} else {
this.ambientLightingLabel = 'Night'
this.ambientLightingCode = 'EL_'
}
}
},
showMoreDetailTab: function (val) {
if (val) {
this.moreDetailIcon = 'keyboard_arrow_up'
} else {
this.moreDetailIcon = 'keyboard_arrow_down'
}
}
},
methods: {
goMailTo () {
openURL('mailto:support@clarashades.com?subject=Clara Support')
},
onScroll (info) {
// this.scrollInfo = info
if (info.position >= 177) {
this.fixedClassOnMobile = 'fixed_me'
} else {
this.fixedClassOnMobile = ''
}
// console.log(info.position)
},
canvasColor (color) {
Object.keys(this.activeColor).forEach(key => {
if (key === color) {
this.activeColor[key] = 'active'
} else {
this.activeColor[key] = null
}
})
// http://localhost:8080/statics/simulator-renders/DayLight_Light-ON/Front-view-Inside-with-Fascia-hardware-black/White-Pearl_FV_DL_LON_inside_fascia_01p.jpg
if (color === 'black') {
this.canvasColorCode = 'Ebony'
} else if (color === 'white_pearl') {
this.canvasColorCode = 'White-Pearl'
} else if (color === 'white') {
this.canvasColorCode = 'White'
} else if (color === 'white_linen') {
this.canvasColorCode = 'White-Linen'
} else if (color === 'espresso') {
this.canvasColorCode = 'Expresso'
} else {
this.canvasColorCode = color.charAt(0).toUpperCase() + color.slice(1)
}
},
fasciaNoFascia () {
if (this.shadeTypeModel === 'openroll') {
this.style = {
label: 'open_roll',
labelId: 'open_roll',
code: 'NO-fascia_',
features2: this.$t('features_open_roll'),
connectivity: this.$t('connectivity_open_roll'),
fabric: '<img src="statics/simulator/ComingSoon.jpg" alt="" />',
accessories: '<img width="500" src="statics/simulator/ComingSoon.jpg" alt="">',
resources: '<img width="500" src="statics/simulator/ComingSoon.jpg" alt="">'
}
} else {
this.style = {
label: 'enclosed',
labelId: 'enclosed',
code: 'fascia_',
features2: this.$t('features_enclosed'),
connectivity: this.$t('connectivity_enclosed'),
fabric: '<img src="statics/simulator/ComingSoon.jpg" alt="" />',
accessories: '<img width="500" src="statics/simulator/ComingSoon.jpg" alt="">',
resources: '<img width="500" src="statics/simulator/ComingSoon.jpg" alt="">'
}
}
}
}
}
</script>
<style lang="scss" scoped>
@import "assets/styles/variables.scss";
.head_title_wrapper {
h1 {
font-family: $MainFont;
font-weight: 400;
font-size: 70px;
position: relative;
z-index: 2;
margin-bottom: 0px;
margin-top: 0px;
padding-top: 25px;
text-transform: lowercase;
@media screen and (max-width: 1023px) {
padding-top: 0px;
font-size: 50px;
}
}
p {
font-family: $MainFont;
font-size: 14px;
font-weight: 400;
line-height: 20px;
color: #707070;
@media screen and (max-width: 1023px) {
padding-left: 25px;
padding-right: 25px;
}
}
hr {
border-bottom-color: $colorMain2;
margin-bottom: 20px;
margin-top: -20px;
max-width: 400px;
border-bottom-width: 3px;
border-top: none;
border-left: none;
border-right: none;
}
div.links {
@media screen and (max-width: 1023px) {
display: none;
}
ul {
list-style: none;
padding: 0px;
margin: 0px;
li {
margin: 0px 10px;
font-family: $MainFont;
font-size: 14px;
font-weight: 400;
line-height: 20px;
color: #000;
}
}
}
}
.product_component_wrapper {
margin-top: 0px;
// background-color: #f2f2f2;
padding: 100px 0px;
padding-top: 0px !important;
@media screen and (max-width: 1023px) {
padding-bottom: 30px;
padding-top: 0px;
margin-top: 0px;
position: relative;
&.fixed_me{
min-height: 110vh;
}
}
.col_preview {
/*flex-basis: 60%;
position: relative;
overflow: hidden;
max-width: 850px;*/
flex-basis: 50%;
position: relative;
overflow: hidden;
max-width: 660px;
max-height: 600px;
@media screen and (max-width: 1023px) {
flex-basis: 100%;
&.fixed_me{
position: fixed;
top: 14vh;
z-index: 99;
left: 0px;
}
}
.preview_wrapper {
/*width: 100%;
height: 600px;
background: #F9F9F9;
overflow: hidden;
position: relative;*/
width: 660px;
height: 660px;
background: #F9F9F9;
overflow: hidden;
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 150%;
left: -25%;
@media screen and (max-width: 1023px) {
height: auto;
img {
position: static !important;
width: 100% !important;
height: auto !important;
}
}
img {
position: absolute;
width: auto;
height: 100%;
// max-height: 800px;
// left: 0px;
// top: 0px;
@media screen and (min-width: 1024px) {
// height: 600px;
}
}
}
}
.col_features {
/*flex-basis: 40%;
padding-left: 16px;
background: #F9F9F9;*/
flex-basis: 50%;
max-width: 660px;
max-height: 600px;
padding-left: 16px;
background: #F9F9F9;
.footer-features{
border-top: 1px solid rgba(black, .1);
span{
font-size: 12px;
line-height: 16px;
font-family: $MainFont;
font-weight: 400;
color: rgba(black, .6);
}
}
.header-features{
border-bottom: 1px solid rgba(black, .1);
span{
font-size: 24px;
line-height: 32px;
font-family: $MainFont;
font-weight: 400;
max-width: 80%;
@media screen and (max-width: 1023px) {
font-size: 22px;
line-height: 28px;
max-width: 75%;
br{
display: none;
}
}
}
img{
transform: scale3d(1,1,1);
}
}
@media screen and (max-width: 1023px) {
flex-basis: 100%;
padding-left: 10px;
padding-right: 10px;
padding-top: 10px;
&.fixed_me{
position: fixed;
top: 52vh;
z-index: 99;
left: 0px;
width: 100%;
max-height: 40vh;
overflow: auto;
background: #f2f2f2;
}
}
.title {
font-family: $MainFont;
font-weight: 400;
font-size: 30px;
margin-bottom: 10px;
margin-top: -80px;
padding-top: 20px;
.hide_on_xs{
@media screen and (max-width: 1023px) {
display: none;
}
}
@media screen and (max-width: 1023px) {
display: flex;
flex-direction: row;
justify-content: center;
}
a{
text-decoration: none;
outline: none;
}
.tab_link{
padding: 0px;
margin: 0px 15px;
opacity: .5;
cursor: pointer;
color: #000;
&.active{
opacity: 1;
border-bottom: 1px solid rgb(153, 153, 153);
}
&.show_on_xs{
@media screen and (min-width: 1024px) {
display: none;
}
}
}
@media screen and (max-width: 1023px) {
position: absolute;
top: 20px;
width: 100%;
text-align: center;
left: 0px;
font-size: 16px;
line-height: 26px;
margin-bottom: 0px;
}
}
.border_top {
border-top: 1px solid rgba(black, .1);
padding-bottom: 2px;
padding-top: 2px;
}
.lab_holder {
font-family: $MainFont;
font-weight: 500;
font-size: 16px;
line-height: 24px;
letter-spacing: 0.15000000596046448px;
@media screen and (max-width: 1023px) {
font-size: 13px;
}
label {
color: #000;
.val {
font-weight: 500;
font-size: 12px;
color: rgba(black, .6);
}
}
p {
margin-top: 30px;
font-family: $MainFont;
font-weight: 400;
font-size: 15px;
color: #707070;
padding-right: 30px;
line-height: 18px;
@media screen and (max-width: 1023px) {
font-size: 13px;
position: absolute;
bottom: 0px;
padding-right: 0px;
margin-top: 0px;
margin-bottom: 0px;
}
}
&.hide_on_mobile {
@media screen and (max-width: 1023px) {
display: none;
}
}
}
.btn-model{
height: 32px;
border-radius: 8px;
margin: 5px;
box-shadow: 0px 4px 4px 0px rgba(black, .05);
font-size: 14px !important;
line-height: 20px !important;
font-weight: 400 !important;
font-family: $MainFont !important;
background: #FFF;
}
.val_holder {
/deep/ .q-btn-group{
button{
@extend .btn-model;
.q-btn__wrapper{
min-height: 32px;
}
&.bg-black{
color: #000 !important;
background: $MainColor !important;
}
}
}
.color_btn {
@extend .btn-model;
/deep/ .q-btn__wrapper{
min-height: 32px;
}
&.active {
background: $MainColor !important;
}
@media screen and (max-width: 1023px) {
margin: 3px;
}
}
.fabric-btn-img{
height: auto !important;
border-radius: 5px;
/deep/ .q-btn__wrapper{
padding-right: 4px;
padding-left: 4px;
img{
width: 36px;
height: 36px;
border-radius: 5px;
}
.black,
.gray,
.white,
.vanilla{
width: 36px;
height: 36px;
border-radius: 5px;
}
.black{
background: #000;
}
.gray{
background: #CCC;
}
.white{
background: #fff;
}
.vanilla{
background: #fff5df;
}
}
}
}
.transparency_wrapper {
.transparencyModelLabel{
font-size: 12px;
font-family: $MainFont;
font-weight: 400;
letter-spacing: .4px;
color: rgba(black, .6);
@media screen and (max-width: 1023px) {
padding-left: 6px;
margin-top: -30px;
}
}
}
.nav_item{
/deep/ .q-btn__content {
width: 100%;
justify-content: space-between;
}
}
@media screen and (max-width: 1023px) {
.option-row {
flex-direction: column;
.col{
flex-basis: 100%;
width: 100%;
}
}
.lab_holder label{
font-size: 16px;
font-weight: 500;
line-height: 24px;
color: black;
}
.nav_item{
margin-left: -10px !important;
margin-right: -10px !important;
}
.val_holder{
// display: none;
padding-top: 8px;
padding-right: 0px;
padding-left: 0px;
}
}
.more_details_wrapper {
margin-top: 48px;
@media screen and (max-width: 1023px) {
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 9;
}
.more_btn {
box-shadow: none;
text-transform: initial;
font-size: 18px;
font-family: $MainFont;
font-weight: 400;
margin-left: -15px;
@media screen and (max-width: 1023px) {
display: none;
box-shadow: none;
text-transform: initial;
font-size: 13px;
font-family: $MainFont;
font-weight: 400;
margin-left: 0px;
background: #000 !important;
color: #fff !important;
border-right: 2px solid #fff !important;
width: 100%;
height: 100%;
}
}
.next_btn {
font-weight: 400;
font-family: $MainFont;
font-size: 14px;
padding: 10px 30px;
border-radius: 0px;
@media screen and (max-width: 1023px) {
font-size: 14px;
padding: 15px 10px;
border-radius: 0px;
width: 100%;
line-height: 18px;
}
}
}
}
.col_details {
margin-top: 70px;
@media screen and (max-width: 1023px) {
margin-top: 20px;
}
}
}
.show_on_xs {
display: none;
@media screen and (max-width: 1023px) {
display: block;
&.more_btn {
box-shadow: none !important;
margin-left: -15px;
margin-top: 30px;
}
}
}
.markers_wrapper {
font-family: $MainFont;
font-weight: 400;
color: #707070;
font-size: 12px;
// opacity: 0.5;
margin-left: 0px;
margin-right: -10px;
@media screen and (max-width: 1023px) {
margin-right: 40px;
}
width: 200px;
i {
font-style: initial !important;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
&::before {
display: none;
content: "";
width: 2px;
height: 10px;
background-color: #707070;
margin-top: -8px;
margin-bottom: 3px;
}
}
}
.q-slider {
z-index: 3;
width: 190px;
@media screen and (max-width: 1023px) {
margin-right: 50px;
}
}
</style>
<style>
.q-slider__track-container {
height: 4px;
border-radius: 20px;
background: #DFDFDF;
}
.q-slider .q-slider__thumb-container {
transform: scale(1.6) translateX(-20%);
top: 11px;
}
.q-slider--inactive .q-slider__thumb-container {
transform: scale(1.6) translateX(-20%);
top: 11px;
}
.q-slider__thumb circle {
stroke: #000;
fill: #000;
}
.q-slider__track {
background: rgba(0,0,0, .6);
}
.q-slider__track-markers {
display: none;
}
.q-tabs--dense .q-tab {
min-height: 60px;
background: #fff;
margin-right: 15px;
}
.q-tabs--dense .q-tab.q-tab--active {
background: #f1dfd1;
}
.q-tabs--dense .q-tab:last-child {
margin-right: 0px;
}
.q-tab__content .q-tab__label {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 16px;
color: #000;
}
.q-separator--horizontal {
height: 4px;
background-color: #f1dfd1;
}
.q-tab__indicator {
display: none !important;
}
@media screen and (max-width: 1023px) {
.q-tab__content .q-tab__label {
font-size: 12px;
}
.q-tabs--dense .q-tab {
min-height: 40px;
margin-right: 5px;
}
.col_features .q-scrollarea {
position: relative;
contain: content;
}
.col_features .q-scrollarea__container{
height: auto !important;
}
.col_features .q-scrollarea__content {
position: relative !important;
}
}
.col_features .q-scrollarea {
position: relative;
contain: content;
}
.col_features .q-scrollarea__container{
height: auto !important;
}
.col_features .q-scrollarea__content {
position: relative !important;
}
.q-scrollarea__thumb{
border-radius: 10px;
width: 10px;
transform: scale(0.9);
}
.simulator-wrapper.q-layout-container .q-layout{
min-height: 100vh;
}
</style>
@bitardev
Copy link
Author

This component is designed to provide a comprehensive UI for customizing indoor shades. It offers a visual preview and various customization options, such as selecting the shade collection, fabric color, transparency levels, canvas colors, and hardware colors. This component is part of a PWA built using Vue.js and the Quasar framework.

Here is a link to the website, so you can have an idea about the look and feel : ShadeSimulator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment