This commit is contained in:
X1627315083
2024-09-26 15:43:27 +08:00
parent ae4ef573e4
commit e26d57dd76
16 changed files with 743 additions and 386 deletions

View File

@@ -6,7 +6,7 @@ NODE_ENV = 'development'
VUE_APP_BASE_URL = 'https://develop.api.aida.com.hk' VUE_APP_BASE_URL = 'https://develop.api.aida.com.hk'
# VUE_APP_BASE_URL = 'https://www.api.aida.com.hk' # VUE_APP_BASE_URL = 'https://www.api.aida.com.hk'
# 佩佩 # 佩佩
VUE_APP_BASE_URL = 'http://192.168.1.7:5567' # VUE_APP_BASE_URL = 'http://192.168.1.7:5567'
# 海波 # 海波
# VUE_APP_BASE_URL = 'http://192.168.1.9:5567' # VUE_APP_BASE_URL = 'http://192.168.1.9:5567'

View File

@@ -1,6 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id */ font-family: "iconfont"; /* Project id 4292253 */
src: url('iconfont.ttf?t=1711431581952') format('truetype'); src: url('iconfont.woff2?t=1727254748810') format('woff2'),
url('iconfont.woff?t=1727254748810') format('woff'),
url('iconfont.ttf?t=1727254748810') format('truetype');
} }
.iconfont { .iconfont {
@@ -11,36 +13,40 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-a-waitao_changkuanwaitao11x:before { .icon-IC-yehua:before {
content: "\e66c"; content: "\e61b";
} }
.icon-fanchehui:before { .icon-shangyiceng:before {
content: "\e626"; content: "\e751";
} }
.icon-chehui:before { .icon-shangyiceng1:before {
content: "\e609"; content: "\e604";
} }
.icon-yuyan:before { .icon-xiayiceng:before {
content: "\e85f"; content: "\e68a";
} }
.icon-biaoqian:before { .icon-shangyiceng2:before {
content: "\e603"; content: "\e68b";
} }
.icon-bingji:before { .icon-shenpi:before {
content: "\e620"; content: "\e6a1";
} }
.icon-bingji1:before { .icon-yonghu:before {
content: "\e668"; content: "\e617";
} }
.icon-dianwei:before { .icon-usetime:before {
content: "\e685"; content: "\e601";
}
.icon-xiala:before {
content: "\e634";
} }
.icon-bianji:before { .icon-bianji:before {
@@ -87,47 +93,35 @@
content: "\e62d"; content: "\e62d";
} }
.icon-shenpi:before { .icon-dianwei:before {
content: "\e6a1"; content: "\e685";
} }
.icon-yonghu:before { .icon-bingji:before {
content: "\e617"; content: "\e620";
} }
.icon-usetime:before { .icon-bingji1:before {
content: "\e601"; content: "\e668";
} }
.icon-xiala:before { .icon-biaoqian:before {
content: "\e634"; content: "\e603";
} }
.icon-shangyiceng:before { .icon-yuyan:before {
content: "\e751"; content: "\e85f";
} }
.icon-shangyiceng1:before { .icon-fanchehui:before {
content: "\e604"; content: "\e626";
} }
.icon-xiayiceng:before { .icon-chehui:before {
content: "\e68a"; content: "\e609";
} }
.icon-shangyiceng2:before { .icon-a-waitao_changkuanwaitao11x:before {
content: "\e68b"; content: "\e66c";
}
.icon-renwu:before {
content: "\e63f";
}
.icon-caizhi:before {
content: "\e647";
}
.icon-shangchuantupian:before {
content: "\e61e";
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -179,7 +179,7 @@
<input type="file" @change="uploadImage"> <input type="file" @change="uploadImage">
</label> </label>
<i class="icon iconfont" @click="setOperation('text')" :class="{active:operation == 'text'}">T</i> <i class="icon iconfont" @click="setOperation('text')" :class="{active:operation == 'text'}">T</i>
<i @click="setLiquefaction()">液化</i> <i class="icon iconfont icon-IC-yehua" @click="setLiquefaction()"></i>
</div> </div>
<!-- <div class="exportCanvasBox_left_tool exportCanvasBox_left_item" :class="{'closeNav' :closeNav.tool}"> <!-- <div class="exportCanvasBox_left_tool exportCanvasBox_left_item" :class="{'closeNav' :closeNav.tool}">
<div class="exportCanvasBox_left_tool_item"> <div class="exportCanvasBox_left_tool_item">
@@ -506,7 +506,7 @@ export default defineComponent({
canvas.loadFromJSON(oldExportCanvas, () => {}); canvas.loadFromJSON(oldExportCanvas, () => {});
isShowMark.value = false isShowMark.value = false
}else{ }else{
nextTick(async ()=>{ await nextTick(async ()=>{
for (const item of arr) { for (const item of arr) {
for (const key in allBoardData.value) { for (const key in allBoardData.value) {
if (item == key) { if (item == key) {
@@ -588,50 +588,16 @@ export default defineComponent({
} else { } else {
position = sketchGroupingItem[sketchXyIndex.minIndex]; position = sketchGroupingItem[sketchXyIndex.minIndex];
} }
} }
setCanvasImage(img,key,position.x,position.y,allItem)//设置图片 }
position.height = img.height * scaleWH + margin; if(key == "sketchboardFiles" && sketchGroupingItem.length >2){
if (key == "sketchboardFiles") {
if (sketchGroupingItem.length <3) {
sketchGroupingItem.push(JSON.parse(JSON.stringify(position)));
}
if (sketchGroupingItem.length >2) {
let sketchXyIndex = {
maxIndex: 0,
maxNum: 0,
minNum: 999999,
minIndex: 0,
};
sketchGroupingItem.forEach(
(sketchItem,sketchIndex) => {
if (sketchItem.y + sketchItem.height < sketchXyIndex.minNum) {
sketchXyIndex.minNum = sketchItem.y + sketchItem.height
sketchXyIndex.minIndex = sketchIndex;
}
if (sketchItem.y + sketchItem.height > sketchXyIndex.maxNum) {
sketchXyIndex.maxNum = sketchItem.y + sketchItem.height
sketchXyIndex.maxIndex = sketchIndex;
}
}
);
sketchGroupingItem[sketchXyIndex.minIndex].y = sketchXyIndex.minNum
// sketchGroupingItem[sketchXyIndex.maxIndex].y = sketchXyIndex.maxNum
if (allBoardData.value[key].length == allItemIndex + 1) {
maxHeight = sketchXyIndex.maxNum
} else {
position = sketchGroupingItem[sketchXyIndex.minIndex];
}
}
}
if(key == "sketchboardFiles" && sketchGroupingItem.length >2){
}else{ }else{
position.x += img.width * scaleWH + margin; position.x += img.width * scaleWH + margin;
} }
let str = `${img.width} + ${scaleWH}`
img.lock_rotation = true; img.lock_rotation = true;
oldKey = key; oldKey = key;
resolve() resolve()
}
canvas.add(img); canvas.add(img);
},{ crossOrigin: "Anonymous" }); },{ crossOrigin: "Anonymous" });
@@ -1984,43 +1950,31 @@ export default defineComponent({
} }
//液化 //液化
//当前选择的液化对象
let liquefactionData = ref(null)
let liquefaction = ref(null) let liquefaction = ref(null)
let submitLiquefaction = (rv)=>{ let submitLiquefaction = (rv)=>{
const originalWidth = liquefactionData.width * liquefactionData.scaleX; // 保存原始宽度
const originalHeight = liquefactionData.height * liquefactionData.scaleY; // 保存原始高度
console.log(liquefactionData);
liquefactionData.setSrc(rv, function() {
liquefactionData.scaleToWidth(originalWidth);
liquefactionData.scaleToHeight(originalHeight);
delete liquefactionData.minioUrl
canvas.renderAll();
updateCanvasState()
});
} }
let setLiquefaction = ()=>{ let setLiquefaction = ()=>{
const selectedObject = canvas.getActiveObjects(); const activeObjects = canvas.getActiveObjects(); // 获取选中的对象
if (selectedObject.length > 0) { if (activeObjects.length === 1 && activeObjects[0].type === 'image') {
// 创建一个新的画布用于生成图片 liquefactionData = activeObjects[0]
const tempCanvas = new fabric.Canvas(); liquefaction.value.init(activeObjects[0])
tempCanvas.setDimensions({
width: selectedObject.width,
height: selectedObject.height,
});
let cloneCount = 0;
selectedObject.forEach((obj) => {
obj.clone((clonedObject) => {
tempCanvas.add(clonedObject);
clonedObject.set({ left: obj.left, top: obj.top }); // 设置位置
cloneCount++;
// 当所有对象都克隆完成后生成图片
if (cloneCount === selectedObject.length) {
const dataURL = tempCanvas.toDataURL();
console.log(dataURL);
console.log('Image URL:', dataURL);
// 可以根据需要使用 dataURL例如显示在 img 标签中
}
});
});
// 生成图片的地址
} else { } else {
console.log('No object selected.'); console.log('No object selected.');
message.info(useI18.t('exportModel.jsContent6'))
return null; return null;
} }
// liquefaction.value.init()
} }
onMounted(() => { onMounted(() => {
let arr = [ let arr = [

View File

@@ -174,7 +174,7 @@
<a-spin size="large" /> <a-spin size="large" />
</div> </div>
</div> </div>
<scaleImage ref="scaleImage" :isCanvas="true" :workspace="workspace"></scaleImage> <scaleImage ref="scaleImage" :isCanvas="type_.type2 == 'Sketchboard'" :workspace="workspace"></scaleImage>
<createSlogan ref="createSlogan" @setSloganData="setSloganData"></createSlogan> <createSlogan ref="createSlogan" @setSloganData="setSloganData"></createSlogan>
</div> </div>
</template> </template>

View File

@@ -440,15 +440,16 @@ export default defineComponent({
// let layout:any = isMoible() ? this.$refs.layoutMobile : this.$refs.layout // let layout:any = isMoible() ? this.$refs.layoutMobile : this.$refs.layout
let layout:any = this.$refs.layout let layout:any = this.$refs.layout
if(this.layoutList.length <= 0){ if(this.layoutList.length <= 0){
await this.layout() // await this.layout()
let arr = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.moodboard))
this.layoutList = arr
} }
if(window.screen.width<1300){ if(window.screen.width<1300){
layout.isMobile = true layout.isMobile = true
}else{ }else{
layout.isMobile = false layout.isMobile = false
} }
// let arr = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.moodboard))
// this.layoutList = arr
layout.init() layout.init()
}else{ }else{
message.info(this.t('MoodboardUpload.jsContent5')) message.info(this.t('MoodboardUpload.jsContent5'))
@@ -503,14 +504,12 @@ export default defineComponent({
class:this.moodb_className, class:this.moodb_className,
} }
this.store.commit("setDisposeMoodboardPosition", obj); this.store.commit("setDisposeMoodboardPosition", obj);
let moodboardPosition = this.store.state.UploadFilesModule.moodboardPosition
domTurnImg(layoutCentent).then((rv)=>{ domTurnImg(layoutCentent).then((rv)=>{
let file = rv let file = rv
let param = new FormData(); let param = new FormData();
param.append('inPin','0') param.append('inPin','0')
param.append('level1Type','Moodboard') param.append('level1Type','Moodboard')
param.append('gender','') param.append('gender','')
param.append('moodboardPosition',JSON.stringify(moodboardPosition))
param.append('timeZone',Intl.DateTimeFormat().resolvedOptions().timeZone) param.append('timeZone',Intl.DateTimeFormat().resolvedOptions().timeZone)
param.append('file',file); param.append('file',file);
let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }} let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}

View File

@@ -29,11 +29,8 @@
</div> </div>
</div> </div>
<div class="layout_centent" :class="{active:flex_direction}" id="layoutCentent"> <div class="layout_centent" :class="{active:flex_direction}" id="layoutCentent">
<div v-for="item,index in layoutList" :key="item" :class="moodbClassName[index]" class="modal_imgItem" v-layout="index" @mousedown="setpitch(item,index)" @touchstart="setpitch(item,index)" ref="content" > <div v-for="item,index in layoutList" :key="item" :class="moodbClassName[index]" class="modal_imgItem" v-layout="item" @mousedown="setpitch(item,index)" @touchstart="setpitch(item,index)" ref="content" >
<img crossOrigin="anonymous" :src="item.imgUrl" :style="{'transform':item.angle?`translate(-50%, -50%) scale(${item.zoom}) rotateZ(${item.angle}deg)`:`translate(-50%, -50%) scale(${item.zoom}) rotateZ(${item.angle}deg)`}" draggable="false" :class="moodbClassName[index]" v-modelImg> <img crossOrigin="anonymous" :src="item.imgUrl" :style="{'transform':item.angle?`translate(-50%, -50%) scale(${item.zoom}) rotateZ(${item.angle}deg)`:`translate(-50%, -50%) scale(${item.zoom}) rotateZ(${item.angle}deg)`}" draggable="false" :class="moodbClassName[index]" v-modelImg>
<div>
</div>
<ul v-show="item.setPitch" class="layout_btn" > <ul v-show="item.setPitch" class="layout_btn" >
<li class="layout_btn_top" v-compile.stop="'top'"></li> <li class="layout_btn_top" v-compile.stop="'top'"></li>
<li class="layout_btn_bottom" v-compile.stop="'bottom'"></li> <li class="layout_btn_bottom" v-compile.stop="'bottom'"></li>
@@ -704,7 +701,7 @@ export default defineComponent({
this.layoutList = parentList this.layoutList = parentList
this.moodbList = this.moodb[parentList.length-1] this.moodbList = this.moodb[parentList.length-1]
this.moodbClassName = this.styleObj?.class?this.styleObj?.class:[] this.moodbClassName = this.styleObj?.class?this.styleObj?.class:[]
this.moodItemScale = this.layoutList[0].zoom*100 this.moodItemScale = (this.layoutList?.[0]?this.layoutList[0].zoom:1)*100
this.initDomStyle() this.initDomStyle()
@@ -750,14 +747,21 @@ export default defineComponent({
changeTemplateModal(){ changeTemplateModal(){
this.layout = !this.layout this.layout = !this.layout
}, },
setIndex(arr:any){ setIndex(styleArr:any){
const nums = arr.map((obj:any) => obj.num); let arr = JSON.parse(JSON.stringify(styleArr))
const sortedNums = [...nums].sort((a, b) => a - b); const nums = arr.map((obj:any,index:any) => {
GO.zIndex = sortedNums[sortedNums.length - 1] + 1 obj.num = index
const numToNewValue = new Map(); return {
sortedNums.forEach((num, index) => numToNewValue.set(num, index + 1)); num: obj.num,
arr.forEach((obj:any) => { zIndex: obj['z-index']?obj['z-index']:1
obj.num = numToNewValue.get(obj.num); }
});
const sortedNums = nums.sort((a, b) => a.zIndex - b.zIndex);
GO.zIndex = sortedNums.length + 1
// GO.zIndex = sortedNums[sortedNums.length - 1].zIndex + 1
sortedNums.forEach((item:any,index:any) => {
arr[item.num]['z-index'] = index + 1
}); });
return arr return arr
}, },
@@ -788,6 +792,7 @@ export default defineComponent({
initStyle(dom:any,style:any){ initStyle(dom:any,style:any){
if(!style)return if(!style)return
for (const [property, value] of Object.entries(style)) { for (const [property, value] of Object.entries(style)) {
dom.style.setProperty(property, value); dom.style.setProperty(property, value);
} }
}, },
@@ -812,21 +817,19 @@ export default defineComponent({
//提交模板 //提交模板
submitTemplate() { submitTemplate() {
this.loadingShow = true this.loadingShow = true
this.setIndex(this.styleObj.domStyle)//index统一排序设置值 this.styleObj.domStyle = this.setIndex(this.styleObj.domStyle)//index统一排序设置值
this.store.commit("setDisposeMoodboardPosition", this.styleObj); this.store.commit("setDisposeMoodboardPosition", this.styleObj);
this.layoutList.forEach((v:any)=>{ this.layoutList.forEach((v:any)=>{
v.setPitch = false v.setPitch = false
}) })
nextTick().then(async ()=>{ nextTick().then(async ()=>{
let layoutCentent = document.getElementById('layoutCentent') let layoutCentent = document.getElementById('layoutCentent')
let moodboardPosition = this.store.state.UploadFilesModule.moodboardPosition
domTurnImg(layoutCentent).then((rv)=>{ domTurnImg(layoutCentent).then((rv)=>{
let file =rv let file =rv
let param = new FormData(); let param = new FormData();
param.append('inPin','0') param.append('inPin','0')
param.append('gender','') param.append('gender','')
param.append('level1Type','Moodboard') param.append('level1Type','Moodboard')
param.append('moodboardPosition',moodboardPosition)
param.append('timeZone',Intl.DateTimeFormat().resolvedOptions().timeZone) param.append('timeZone',Intl.DateTimeFormat().resolvedOptions().timeZone)
param.append('file',file); param.append('file',file);
let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }} let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}

View File

@@ -130,13 +130,15 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, h, ref ,toRefs,computed,reactive, nextTick} from "vue"; import { defineComponent, h, ref ,toRefs,createVNode,reactive, nextTick} from "vue";
import { Https } from "@/tool/https"; import { Https } from "@/tool/https";
import { Modal } from "ant-design-vue";
// import domTurnImg from '@/tool/domTurnImg' // import domTurnImg from '@/tool/domTurnImg'
import { useStore } from "vuex"; import { useStore } from "vuex";
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { downloadIamge } from "@/tool/util"; import { downloadIamge } from "@/tool/util";
import { getCookie,setCookie } from "@/tool/cookie"; import { getCookie,setCookie } from "@/tool/cookie";
import { useI18n } from "vue-i18n";
import generalMiniCanvas from "@/component/modules/generalMiniCanvas.vue"; import generalMiniCanvas from "@/component/modules/generalMiniCanvas.vue";
export default defineComponent({ export default defineComponent({
components:{generalMiniCanvas}, components:{generalMiniCanvas},
@@ -313,8 +315,24 @@ export default defineComponent({
rv.category = scaleImageList.value[scaleImageIndex.value]?.category rv.category = scaleImageList.value[scaleImageIndex.value]?.category
rv.categoryValue = scaleImageList.value[scaleImageIndex.value]?.categoryValue rv.categoryValue = scaleImageList.value[scaleImageIndex.value]?.categoryValue
delete rv.url delete rv.url
scaleImageList.value.unshift(rv) Modal.confirm({
loadingShow.value = false title: useI18n().t('scaleImage.overlayOrNot'),
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
scaleImageList.value[scaleImageIndex.value] = rv
loadingShow.value = false
scaleImage.value = false
},
onCancel(){
scaleImageList.value.unshift(rv)
loadingShow.value = false
scaleImage.value = false
}
});
} }
).catch(res=>{ ).catch(res=>{
loadingShow.value = false loadingShow.value = false

View File

@@ -3,7 +3,7 @@
class="liquefaction generalModel" class="liquefaction generalModel"
v-model:visible="liqufeaction" v-model:visible="liqufeaction"
:footer="null" :footer="null"
width="50%" width="78%"
:maskClosable="false" :maskClosable="false"
:centered="true" :centered="true"
:closable="false" :closable="false"
@@ -17,254 +17,295 @@
</div> </div>
<div class="liquefaction_center"> <div class="liquefaction_center">
<div class="liquefaction_canvas_box">
<canvas id="c"></canvas>
<div v-show="arrows.show" class="moveDom" :style="arrows.domStyle"></div>
<div v-show="arrows.show" class="jiantouDom" :style="arrows.jiantouStyle"> </div>
</div>
<div class="liquefaction_parameter">
<div class="liquefaction_parameter_item">
<div class="liquefaction_parameter_item_title">
<span>{{ $t('exportModel.Size') }}</span>
<input type="number" v-model="routes" @change="routesChange('routes')">
</div>
<div class="liquefaction_parameter_item_input">
<input type="range" v-model="routes" @change="routesChange('routes')">
</div>
</div>
<div class="liquefaction_parameter_item">
<div class="liquefaction_parameter_item_title">
<span>{{ $t('exportModel.density') }}</span>
<input type="number" v-model="density" @change="routesChange('density')">
</div>
<div class="liquefaction_parameter_item_input">
<input type="range" v-model="density" @change="routesChange('density')">
</div>
</div>
<div class="liquefaction_parameter_item">
<div class="generage_btn started_btn" @click="cancelDsign">取消</div>
<div class="generage_btn started_btn" @click="submit">确定</div>
</div>
</div>
</div> </div>
</a-modal> </a-modal>
<!-- <div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div> -->
</template> </template>
<script> <script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue"; import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue";
import { Https } from "@/tool/https";
import { formatTime } from "@/tool/util";
import { setCookie, getCookie } from "@/tool/cookie";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import allOrder from "@/component/Pay/allOrder.vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { getMousePosition } from "@/tool/mdEvent"; import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({ export default defineComponent({
components: { components: {
creditsDetail,
allOrder,
}, },
emits: ['setSloganData'], emits: ['submitLiquefaction'],
setup(props,{emit}) { setup(props,{emit}) {
let presentState = ref('paypal'); // let presentState = ref('paypal');
let liqufeaction = ref(false); let liqufeaction = ref(false);
let loadingShow = ref(false); let liqufeactionData = reactive({
let { t } = useI18n(); routes: 90,//移动框大小
let canvas = reactive({}); density: 80,//移动大小
let scale = 2;
let ratio = [1,1]
let exportWH = 512
let pencilbtnStyle = ref({
background:'',
width:0+'px',
height:0+'px',
display:'none',
left:0+'px',
top:0+'px',
}) })
let canvasBtn = reactive({ let arrows = ref({
canvasState:'move', show:false,
canvasPencilWidth:{ domStyle:{
pencil:4, left:0,
eraser:4, top:0,
width:0,
height:0,
}, },
spreadState:false, jiantouStyle:{
height:'1px',
transform:`translateY(-100%) rotate(${90}deg)`,
}
}) })
let canvasWH = ref(0); let canvas
onMounted(()=>{ let canvasImgData = {
}) width:0,
let exportUrl = '' height:0,
let reverseCanvasState = ref([])//存放canvas操作 }
let normalCanvasState = ref([])//存放canvas操作 let downX
let canvasState = ref()//存放canvas操作 let downY
let keyDown = []//监听键盘的 keydown 和 keyup 事件 let init = async (data)=>{
let init = (data)=>{ liqufeaction.value = true
console.log(data); await new Promise((resolve, reject) => {
console.log(123); nextTick(()=>{
resolve()
})
})
let img = new Image()
img.setAttribute('crossOrigin', 'Anonymous')
img.onload = () => {
let canvasBox = document.querySelector('.liquefaction .liquefaction_canvas_box')
let width = canvasBox.offsetHeight / img.height * img.width
canvas = document.getElementById('c')
canvas.width = width
canvas.height = canvasBox.offsetHeight
let optfor = false
const context = canvas.getContext('2d');
context.drawImage(img, 1, 1, canvas.width, canvas.height);
let imgData = context.getImageData(0, 0, canvas.width, canvas.height)
let canvasDownX
let canvasDownY
let distance = 0
let angle
let mousedown = (event)=>{
let e = getMousePosition(event,false)
down(e)
}
let touchdown = (event)=>{
let e = getMousePosition(event,true)
down(e)
}
let down = (event)=> {
let canvasPosition = canvas.getBoundingClientRect()
let maxX = canvasPosition.width + canvasPosition.x
let minX = canvasPosition.x
let maxY = canvasPosition.height + canvasPosition.y
let minY = canvasPosition.y
if (event.clientX > minX && event.clientX < maxX && event.clientY > minY && event.clientY < maxY) {
downX = event.clientX
downY = event.clientY
canvasDownX = downX - minX
canvasDownY = downY - minY
}
optfor = true
arrows.value.jiantouStyle.height = distance + 'px'
arrows.value.jiantouStyle.left = event.clientX - canvasBox.getBoundingClientRect().left + 'px'
arrows.value.jiantouStyle.top = event.clientY - canvasBox.getBoundingClientRect().top + 'px'
arrows.value.domStyle.width = liqufeactionData.routes * 2 + 'px'
arrows.value.domStyle.height = liqufeactionData.routes * 2 + 'px'
arrows.value.domStyle.left = event.clientX - canvasBox.getBoundingClientRect().left - liqufeactionData.routes + 'px'
arrows.value.domStyle.top = event.clientY - canvasBox.getBoundingClientRect().top - liqufeactionData.routes + 'px'
arrows.value.show = true
let mouseup = ()=>{
if(!optfor)return
if(distance != 0){
let {upDownX, upDownY} = calculateTargetCoordinates(canvasDownX, canvasDownY,distance,angle)
liquify(imgData, canvasDownX, canvasDownY, upDownX, upDownY, liqufeactionData.routes, liqufeactionData.density)
}
distance = 0
arrows.value.show = false
context.putImageData(imgData, 0, 0);
optfor = false
canvasBox.removeEventListener('mousemove', mouseMove);
canvasBox.removeEventListener('touchmove', touchmove);
document.removeEventListener('mouseup', mouseup);
document.removeEventListener('touchend', mouseup);
}
canvasBox.addEventListener('mousemove', mouseMove);
canvasBox.addEventListener('touchmove', touchmove);
document.addEventListener('mouseup', mouseup);
document.addEventListener('touchend', mouseup);
}
let mouseMove = (event)=>{
let e = getMousePosition(event,false)
move(e)
}
let touchmove = (event)=>{
let e = getMousePosition(event,true)
move(e)
}
let move = function (moveEvent) {
let height = distanceFun(downX , downY , moveEvent.clientX , moveEvent.clientY)
if(optfor){
let height = distanceFun(downX , downY , moveEvent.clientX , moveEvent.clientY)
angle = angleFun(downX , downY , moveEvent.clientX , moveEvent.clientY)
if(height < liqufeactionData.routes){
distance = height
arrows.value.jiantouStyle.height = height + 'px'
}
arrows.value.jiantouStyle.transform = `translateY(-100%) rotate(${angle+90}deg)`
}
}
// canvas.addEventListener('mousedown', down);
canvasBox.addEventListener('mousedown', mousedown);
canvasBox.addEventListener('touchstart', touchdown);
}
img.src = data._element.src
} }
let canvasKeyDown = (event) => { let distanceSqr = (x1, y1, x2, y2) => sqr(x1 - x2) + sqr(y1 - y2);
if(keyDown.indexOf(event.key)>-1){ let sqr = (x) => x * x;;
}else{ let eachCircleDot = (imageData, ox, oy, r, callback)=>{
keyDown.push(event.code) var imgWidth = imageData.width,
if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyZ') > -1 && keyDown.indexOf('ShiftLeft') > -1){ imgHeight = imageData.height,
historyState('reverse') data = imageData.data,
}else if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyZ') > -1){ left = ox - r,
historyState('') right = ox + r,
top = oy - r,
bottom = oy + r,
dotRedOffset, dotGreenOffset, dotBlueOffset, alphaOffset;
for (var x = left; x < right; x++){
for (var y = top; y < bottom; y++){
if (distanceSqr(x, y, ox, oy) <= sqr(r)) {
dotRedOffset = y * imgWidth * 4 + x * 4;
dotGreenOffset = dotRedOffset + 1;
dotBlueOffset = dotGreenOffset + 1;
alphaOffset = dotBlueOffset + 1;
callback(
// 当前点的坐标
{ x: x, y: y },
// 点的RGBA四个分量对应字节的下标
{
r: dotRedOffset,
g: dotGreenOffset,
b: dotBlueOffset,
a: alphaOffset,
},
// 传进来的ImageData的data部分
data
);
}
} }
} }
} }
let canvasKeyUp = (event) =>{ let copyImageDataBuff = (imgData)=>{
keyDown = keyDown.filter(function(item) { var data = imgData.data,
return event.code !== item; imgDataBuff = [];
}) for (var i in data){
imgDataBuff[i] = data[i];
} }
let clearCanvas = ()=>{ return imgDataBuff;
canvasBtn.canvasState = 'move'
canvasBtn.spreadState = false
document.removeEventListener("keydown", canvasKeyDown);
document.removeEventListener("keyup", canvasKeyUp);
} }
let rgba = 'rgba(0, 0, 0, 1)' let moveDot = (imgData, dataBuff, x, y, srcX, srcY)=> {
let mouseMove = (event)=>{
let e = getMousePosition(event,false) var imgWidth = imgData.width,
setCanvasMove(e) imgHeight = imgData.height,
data = imgData.data;
// // 进行边界检查,确保不超出图像范围
x = Math.max(0, Math.min(Math.round(x), imgWidth - 1));
y = Math.max(0, Math.min(Math.round(y), imgHeight - 1));
srcX = Math.max(0, Math.min(Math.round(srcX), imgWidth - 1));
srcY = Math.max(0, Math.min(Math.round(srcY), imgHeight - 1));
srcX = Math.round(srcX);
srcY = Math.round(srcY);
var targetStartOffset = y * imgWidth * 4 + x * 4,
srcStartOffset = srcY * imgWidth * 4 + srcX * 4;
for (var i = 0; i < 4; i++)
data[targetStartOffset + i] = dataBuff[srcStartOffset + i];
} }
let touchmove = (event)=>{ let liquify = (imgData, cx, cy, mx, my, r, strenth) => {
let e = getMousePosition(event,true) var imgDataBuff = copyImageDataBuff(imgData);
setCanvasMove(e) eachCircleDot(imgData, cx, cy, r, function (posi) {
} var tx = posi.x,
let setCanvasMove = (event)=>{ ty = posi.y;
if(canvas.isDrawingMode){ var u = transFormula(cx, cy, mx, my, tx, ty, r, strenth);
canvas.setCursor('none'); moveDot(imgData, imgDataBuff, tx, ty, u.x, u.y);
} function transFormula(cx, cy, mx, my, tx, ty, r, strenth) {
let canvasCenterBox = document.querySelector(".liquefaction .exportCanvasBox_center_box"); strenth = strenth || 100;
if(!canvasCenterBox)return var relativity = sqr(r) - distanceSqr(tx, ty, cx, cy);
let parentX = event.clientX - canvasCenterBox.getBoundingClientRect().left var distanceMovedSqr = distanceSqr(mx, my, cx, cy);
let parentY = event.clientY - canvasCenterBox.getBoundingClientRect().top var rate = sqr(relativity / (relativity + distanceMovedSqr * (100 / strenth)));
pencilbtnStyle.value.left = parentX + "px" var ux = tx - rate * (mx - cx),
pencilbtnStyle.value.top = parentY+'px' uy = ty - rate * (my - cy);
} return { x: ux, y: uy };
let setOperation = (str)=>{ }
canvasBtn.canvasState = str
if(str == 'move'){
setMove()
pencilbtnStyle.value.display = `none`
}else if(str == 'pencil'){
setPencil()
pencilbtnStyle.value.display = `block`
}else if(str == 'eraser'){
setEraser()
pencilbtnStyle.value.display = `block`
}
}
let setMove = ()=>{
canvas.isDrawingMode = false
canvas.forEachObject((obj) =>obj.selectable = true);
}
let setPencil = ()=>{
canvas.isDrawingMode = true//开启绘画模式
canvas.freeDrawingBrush = new fabric.PencilBrush(canvas,{});
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
canvas.freeDrawingBrush.color = rgba
pencilbtnStyle.value.background = rgba
canvas.freeDrawingBrush.isEraser = false
setPencilWidth()
}
let setEraser = ()=>{
canvas.isDrawingMode = true
let eraser = new fabric.EraserBrush(canvas)
canvas.freeDrawingBrush = eraser
canvas.requestRenderAll();
canvas.freeDrawingBrush.isEraser = true
pencilbtnStyle.value.background = `rgb(255,255,255)`
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
setPencilWidth()
}
let deleteObj = ()=> {
// if(!canvas.getActiveObjects()){
// return
// }
let target = canvas.getActiveObjects()
target.forEach((item)=>{
canvas.fxRemove(item, {
onComplete(){
canvas.discardActiveObject(); // 丢弃当前选中的对象
canvas.renderAll(); // 重新渲染 Canvas
}
})
canvas.FX_DURATION = 300
})
}
let setTimeOutWidth
let setPencilWidth = ()=>{//切换颜色给铅笔设置颜色
clearTimeout(setTimeOutWidth)
setTimeOutWidth = setTimeout(()=>{
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState])
pencilbtnStyle.value.height = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
pencilbtnStyle.value.width = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
},300)
}
let updateCanvasState = (str) =>{
if(str != 'mouseUp'){
}
const canvasAsJson = JSON.stringify(canvas.toJSON());
normalCanvasState.value.push(canvasAsJson);
}
//撤回
let historyState = (str)=> {
if(str == 'reverse' && reverseCanvasState.value.length > 0){//反撤回
let obj = reverseCanvasState.value.pop()
// canvasState.value = reverseCanvasState.value[reverseCanvasState.value.length-1]
canvasState.value = obj
normalCanvasState.value.push(obj);
}else if(str == '' && normalCanvasState.value.length > 1){
let obj = normalCanvasState.value.pop()
canvasState.value = normalCanvasState.value[normalCanvasState.value.length-1]
reverseCanvasState.value.push(obj);
}else{
return
}
canvas.loadFromJSON(canvasState.value, () => {});
}
let setSubmit = ()=>{
var allObjects = canvas.getObjects('path');
// if(allObjects.length == 0){
// return message.info(t('addDetails.jsContent1'))
// }
var canvasDom = document.createElement("canvas");
let exportCanvas = new fabric.Canvas(canvasDom, {
backgroundColor: "rgba(255, 255, 255,1)",
width: exportWH * ratio[0],
height: exportWH * ratio[1],
isDrawingMode: false, // 开启绘图模式
}); });
canvas.backgroundImage.clone((back)=>{ }
back.set({ let distanceFun = (x1, y1, x2, y2) => {
scaleX:1, return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
scaleY:1, }
left:back.left*scale, let angleFun = (x1, y1, x2, y2) => {
top:back.top*scale , return Math.atan2(y2 - y1, x2 - x1) * (180 / Math.PI);
}) }
exportCanvas.backgroundImage = back let calculateTargetCoordinates = (x1, y1, distance, angleDegrees) => {
allObjects.forEach((item,index)=>{ let angleRad = angleDegrees * (Math.PI / 180);
// let obj = fabric.util.object.clone(item); let x2 = x1 + distance * Math.cos(angleRad);
if(item.type == 'circle')return let y2 = y1 + distance * Math.sin(angleRad);
let obj return { upDownX: x2, upDownY: y2 };
item.clone((cloned)=>{
obj = cloned
})
obj.set(
{
scaleX:(item.scaleX?item.scaleX:1)*scale,
scaleY:(item.scaleY?item.scaleY:1)*scale,
left:item.left*scale,
top:item.top*scale,
}
)
exportCanvas.add(obj)
})
let data = exportCanvas.toDataURL('jpg')
cancelDsign()
clearCanvas()
emit('setSloganData',data)
})
} }
let cancelDsign = ()=>{ let cancelDsign = ()=>{
document.removeEventListener('keydown',canvasKeyDown);
document.removeEventListener('keyup', canvasKeyUp);
liqufeaction.value = false liqufeaction.value = false
} }
let routesChange = (str)=>{
liqufeactionData[str] = Math.round(liqufeactionData[str]/10)*10;
if (liqufeactionData[str] < 10) {
liqufeactionData[str] = 10; // 设置为最小值
} else if (liqufeactionData[str] > 100) {
liqufeactionData[str] = 100; // 设置为最大值
}
}
let submit = ()=>{
emit('submitLiquefaction',canvas.toDataURL('image/png'))
cancelDsign()
}
return { return {
presentState,
liqufeaction, liqufeaction,
loadingShow, ...toRefs(liqufeactionData),
t, arrows,
pencilbtnStyle,
...toRefs(canvasBtn),
init, init,
setOperation,
setPencilWidth,
historyState,
setSubmit,
cancelDsign, cancelDsign,
routesChange,
submit,
}; };
}, },
data() { data() {
@@ -279,6 +320,83 @@ export default defineComponent({
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.liquefaction { .liquefaction {
background: #f9fafb;
.liquefaction_center{
height: 100%;
display: flex;
align-items: center;
.liquefaction_canvas_box{
background: #fff;
height: 90%;
width: 80%;
text-align: center;
// overflow-x: auto;
position: relative;
overflow-y: hidden;
}
.liquefaction_parameter{
padding-top: 5rem;
height: 100%;
flex: 1;
.liquefaction_parameter_item{
display: flex;
flex-direction: column;
.liquefaction_parameter_item_title{
display: flex;
justify-content: space-between;
input{
width: 30%;
text-align: right;
}
}
.liquefaction_parameter_item_input{
width: 100%;
input{
width: 100%;
}
}
}
.liquefaction_parameter_item:last-child{
margin-top: 20px;
text-align: center;
div{
margin-bottom: 1rem;
}
}
}
.moveDom {
width: 20px;
height: 20px;
border-radius: 50%;
box-sizing: border-box;
border: 1px solid;
position: absolute;
pointer-events: none;
}
.jiantouDom {
position: absolute;
width: 2px;
height: 1px;
background-color: #000;
transform-origin: center bottom;
transform: translateY(-100%);
pointer-events: none;
}
.jiantouDom::before {
content: "";
display: block;
position: absolute;
width: 10px;
height: 10px;
left: 50%;
transform: translateX(-50%) rotate(45deg);
border-top: 2px solid #000;
border-left: 2px solid #000;
pointer-events: none;
}
}
} }
</style> </style>

View File

@@ -66,6 +66,8 @@ export default {
requiresCredits:'执行超分的图片需要消耗{data}积分', requiresCredits:'执行超分的图片需要消耗{data}积分',
Scale:'倍率', Scale:'倍率',
Cancel:'取消', Cancel:'取消',
size:'区域',
density:'密度',
jsContent1:"您是否已经保存画布内容?如果没有,请再关闭前点击'保存'。", jsContent1:"您是否已经保存画布内容?如果没有,请再关闭前点击'保存'。",
jsContent2:'我们只支持对印花进行超分', jsContent2:'我们只支持对印花进行超分',
jsContent3:'您的积分小于一次超分', jsContent3:'您的积分小于一次超分',
@@ -75,6 +77,7 @@ export default {
jsContent7:'保存成功~', jsContent7:'保存成功~',
jsContent8:'是否继续编辑', jsContent8:'是否继续编辑',
jsContent9:'是否需要自动裁剪画布多余空间', jsContent9:'是否需要自动裁剪画布多余空间',
jsContent10:'请选择一张图片后再次尝试',
}, },
upgradePlan:{ upgradePlan:{
BuyCredlts:'购买积分', BuyCredlts:'购买积分',
@@ -562,6 +565,9 @@ export default {
jsContent5:'是否删除当前作品', jsContent5:'是否删除当前作品',
jsContent6:'作品被作者删除', jsContent6:'作品被作者删除',
}, },
scaleImage:{
overlayOrNot:'是否覆盖当前图片',
},
account:{ account:{
personCentered:'个人中心', personCentered:'个人中心',
myInformation:'我的信息', myInformation:'我的信息',

View File

@@ -66,6 +66,8 @@ export default {
requiresCredits:'Performing upscale image requires a {data} credits', requiresCredits:'Performing upscale image requires a {data} credits',
Scale:'Scale', Scale:'Scale',
Cancel:'Cancel', Cancel:'Cancel',
size:'Size',
density:'Density',
jsContent1:"Have you saved your canvas content? If not, please click 'Save' before closing.", jsContent1:"Have you saved your canvas content? If not, please click 'Save' before closing.",
jsContent2:'We only provide super-resolution capabilities for printboard images.', jsContent2:'We only provide super-resolution capabilities for printboard images.',
jsContent3:'Your points are less than one SR', jsContent3:'Your points are less than one SR',
@@ -75,6 +77,7 @@ export default {
jsContent7:'save successfully', jsContent7:'save successfully',
jsContent8:'Whether to continue editing', jsContent8:'Whether to continue editing',
jsContent9:'Whether you need to automatically crop your canvas excess space', jsContent9:'Whether you need to automatically crop your canvas excess space',
jsContent10:'Please select a picture and try again',
}, },
upgradePlan:{ upgradePlan:{
BuyCredlts:'Buy credits', BuyCredlts:'Buy credits',
@@ -519,7 +522,7 @@ export default {
}, },
works:{ works:{
all:'All', all:'All',
FavoriteWorks:'Favorite Works', FavoriteWorks:'Like The Works',
MyWorks:'My Works', MyWorks:'My Works',
}, },
Publish:{ Publish:{
@@ -562,6 +565,9 @@ export default {
jsContent5:'Whether to delete the current gallery', jsContent5:'Whether to delete the current gallery',
jsContent6:'The author deleted the work', jsContent6:'The author deleted the work',
}, },
scaleImage:{
overlayOrNot:'Whether to overwrite the current picture',
},
account:{ account:{
personCentered:'Account', personCentered:'Account',
myInformation:'My Details', myInformation:'My Details',

View File

@@ -241,11 +241,21 @@ const routes: Array<RouteRecordRaw> = [
name: 'feedbackSurveyCN', name: 'feedbackSurveyCN',
component: _import('feedbackSurveyCN'), component: _import('feedbackSurveyCN'),
}, },
{
path: '/emailVerify',
name: 'emailVerify',
component: _import('emailVerify'),
},
{ {
path: '/404', path: '/404',
name: '404', name: '404',
component: _import('404') component: _import('404')
}, },
{
path: "/:catchAll(.*)",
redirect: "/404",
},
] ]
const router = createRouter({ const router = createRouter({
@@ -308,7 +318,7 @@ let setMurmur = (id:any)=> {
} }
router.beforeEach((to:any, from, next) => { router.beforeEach((to:any, from, next) => {
let upgradeList = ['/feedbackSurvey','/feedbackSurveyCN']//指定页面系统维护也可以访问 let upgradeList = ['/feedbackSurvey','/feedbackSurveyCN','emailVerify']//指定页面系统维护也可以访问
// 系统维护 // 系统维护
// const toName = to.name === 'upgrade'; // const toName = to.name === 'upgrade';
@@ -366,30 +376,27 @@ router.beforeEach((to:any, from, next) => {
} }
return return
} }
if (routeExists) {//检测档期那页面是否存在 if (isMurmur && murmurStr && token) {
if (isMurmur && murmurStr && token) { const toName = to.name === 'login';
const toName = to.name === 'login'; if (toName) {
if (toName) { return next({ name: '/home' });//机房用户
next({ name: '/home' });//机房用户 }
} else {
next();
}
} else {
if (routeList.indexOf(to.path) > -1 ) {//指定也买你必须指定用户可以进入
if(userIdList.indexOf(userInfo.userId) > -1){
next();
}else{
next({ name: '/404' });
}
}else{
next();
}
// 如果页面存在,正常跳转
}
} else { } else {
// 如果页面不存在可以跳转到404页面或者其他页面 if (routeList.indexOf(to.path) > -1 ) {//指定也买你必须指定用户可以进入
next('/404'); if(userIdList.indexOf(userInfo.userId) > -1){
}else{
return next({ name: '/404' });
}
}
// 如果页面存在,正常跳转
} }
next();
// if (routeExists) {//检测档期那页面是否存在
// } else {
// // 如果页面不存在可以跳转到404页面或者其他页面
// next('/404');
// }
}); });

View File

@@ -71,8 +71,6 @@ const UploadFilesModule : Module<UploadFiles,RootState> = {
state.moodboard = [...state.moodboardFiles,...state.moodboardGenerateFiles,...state.moodboardMaterialFiles] state.moodboard = [...state.moodboardFiles,...state.moodboardGenerateFiles,...state.moodboardMaterialFiles]
}, },
addGenerateMaterialFils(state,data:any){ addGenerateMaterialFils(state,data:any){
console.log(data);
let file let file
let arr let arr
let maxImg = 8 let maxImg = 8

254
src/views/emailVerify.vue Normal file
View File

@@ -0,0 +1,254 @@
<template>
<div class="emailVerify" :class="{'active': forbid}">
<main class="main">
<h1 id="title">Welcome</h1>
<p id="description" v-if="!forbid">Please take the survey</p>
</main>
</div>
</template>
<script lang="ts">
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Modal,message } from 'ant-design-vue';
import { Https } from "@/tool/https";
import { defineComponent, toRefs,ref, reactive, createVNode } from "vue";
export default defineComponent({
setup() {
let feedbackData:any = reactive({
userName:'',
gender:'Female',
occupation:'',
country:'',
email:'',
age:'20-30',
helpful:[],
improve:[],
isSubscribe:'',
reasonForNotSubscribe:[],
designTools:'',
});
let setSubmit = (value:any)=>{
Https.axiosPost(Https.httpUrls.questionnaire, value).then(
(rv) => {
alert('Submit Successfully!')
}
).catch(res=>{
});
}
let forbid = ref(false)
return {
...toRefs(feedbackData),
setSubmit,
forbid,
};
},
data() {
return {
// moodTemplateId: "", //模板id
};
},
mounted() {},
methods: {},
});
</script>
<style lang="less" scoped>
@import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@400;700&display=swap");
.emailVerify {
font-family: "Quicksand", sans-serif;
font-family: 'Roboto', sans-serif;
text-align: center;
line-height: 1.5;
// background: linear-gradient(180deg, #f3f3e6 0%, #eee4f3 100%);
margin: 1rem;
height: 100%;
overflow-y: auto;
&.active{
#title {
font-size: 3rem;
}
#description {
font-size: 1.4rem;
}
#survey-form {
width: 90%;
padding: 1.5rem;
font-size: 1.2rem;
}
p{
font-size: 1.4rem;
}
input,
#dropdown {
padding: 5px;
}
textarea {
max-height: 125px;
padding: 5px;
}
input[type="radio"],
input[type="checkbox"] {
width: 1rem;
height: 1rem;
}
input,select{
height: 3.5rem;
}
}
.main{
background: linear-gradient(45deg, #eee4f3, #f3f4e6);
padding: 2rem;
}
#title {
font-size: 6rem;
margin: 0;
font-weight: 900;
}
#description {
font-size: 2.8rem;
font-style: italic;
}
#survey-form {
position: relative;
background: rgba(255, 255, 255, 0.2);
width: 60%;
left: 50%;
transform: translateX(-50%);
text-align: left;
border-radius: 15px;
padding: 3rem;
box-shadow: -1px 1px 5px 0.5px;
font-size: 2.4rem;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
&.active{
transition: width 1s ease;
}
}
@media (max-width: 760px) {
form {
width: 75%;
}
}
h2 {
width: 100%;
font-weight: 900;
}
.section {
display: flex;
flex-direction: column;
margin: 1rem;
width: 100%;
}
.section:last-child{
margin-bottom: 4rem;
}
.w40 {
width: 40%;
}
.fontColor{
color: rgb(255, 2, 2);
}
p{
font-size: 2.8rem;
}
p,
label {
font-weight: bold;
margin: 0;
margin-left: 5px;
}
input,
#dropdown {
border: none;
border-radius: 5px;
padding: 10px;
outline: 0;
}
input:focus,
#dropdown:focus {
border: 2px solid rgb(173, 173, 173);
}
input,select{
height: 7rem;
}
input,
button,
select,
textarea {
cursor: pointer;
font-family: inherit;
font-size: inherit;
}
input[type="radio"],
input[type="checkbox"] {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: middle;
margin: 0;
}
label{
vertical-align: baseline;
cursor: pointer;
.others-input{
background: rgba(255, 255, 255, 0);
border-top: none;
border-right: none;
border-left: none;
border-radius: 0;
border-bottom: 2px solid;
}
.others-input:focus{
border: none;
border-bottom: 2px solid;
}
span{
vertical-align: top;
}
textarea{
width: 80%;
vertical-align: top;
margin-left: 1rem;
}
}
textarea {
min-height: 75%;
max-height: 250px;
width: 100%;
resize: vertical;
border: none;
border-radius: 10px;
padding: 10px;
box-sizing: border-box;
}
#submit {
background: green;
background: #39215b;
border: none;
border-radius: 10px;
color: white;
font-size: 3rem;
transition: all 0.3s ease-in;
}
#submit:hover {
background: darkgreen;
background: #543087;
}
}
</style>