background:url(../images/list01.png) no-repeat各个字段的含义

本文详细解释了CSS中background-position属性的用法,包括其默认值、可能的取值方式及如何精确控制背景图像的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

background:url(../images/list01.png) no-repeat 0 center;
的意思是 图像地址 不重复 水平位置0 垂直位置居中

0 center 的意思就是 水平位置0 垂直位置居中
-4px -3px 的意思就是 水平位置-4px  垂直位置-3px 

这两个值和background-position 属性是一样的,即设置背景图像的起始位置。
这个属性设置背景原图像的位置,背景图像如果要重复,将从这一点开始。
默认值:0% 0%
可能的值
 top left
 top center
 top right
 center left
 center center
 center right
 bottom left
 bottom center
 bottom right (以上,如果您仅规定了一个关键词,那么第二个值将是"center"。)

 x% y% ( 第一个值是水平位置,第二个值是垂直位置。左上角是 0% 0%。右下角是 100% 100%。如果您仅规定了一个值,另一个值将是 50%。)

mpx npx (第一个值是水平位置,第二个值是垂直位置。左上角是 0 0。单位是像素 (0px 0px) 或任何其他的 CSS 单位。如果您仅规定了一个值,另一个值将是50%。)
 
您可以混合使用 % 和 position 值。
<template> <div class="nav has-pe" :class="isDark ? 'dark' : ''"> <div class="header-bg"> <!-- <img :src="headerBg" style="width:100%;"/>--> </div> <!-- <div class="animate-blocks">--> <!-- <div v-for="i in 3" class="animate-block-item"></div>--> <!-- </div>--> <div class="animate-1-con"><img :src="animate1Image" class="animate-1-img"/></div> <div class="animate-2-con"><img :src="animate2Image" class="animate-2-img"/></div> <!-- <div class="star"></div>--> <div style="height:100%;display: flex;align-items: center;"> <div class="logo-con has-pe" style="height:100%;"> <div class="logo-border"> <logo-svg class="logo-svg" /> </div> <router-link :to="{name:'home'}" class="logo-text"> {{appStore.title}} </router-link> </div> <div class="menu-con has-pe"> <template v-for="m in menus"> <a v-if="m.href" :href="m.href" target="_blank" class="menu-item nav-ab t" :class="m.code"> <span class="mdi mgr-5" :class="m.icon"></span> <span>{{m.text}}</span> </a> <router-link v-else :to="{name: m.code}" @click="play" class="menu-item nav-ab t" :class="m.code"> <span class="mdi mgr-5" :class="m.icon"></span> <span>{{m.text}}</span> </router-link> </template> </div> <div class="right-side text-right mgr-10 mgt-5"> <div class="font-18">欢迎你,超级管理员</div> <div class="font-ntf font-20 mgt-5 op-60"> <el-button size="small" type="primary" plain class="is-square" icon="Sunny" @click="appStore.toggleTheme()"></el-button> <el-button size="small" type="primary" plain class="is-square" icon="FullScreen" @click="toggleFullscreen()"></el-button> <el-button size="small" type="primary" plain class="is-square" icon="MoreFilled"></el-button> <el-button size="small" type="danger" plain>退出</el-button> </div> </div> </div> </div> </template> <script setup lang="ts"> import _ from "lodash" import {computed, onMounted, ref, onUnmounted} from "vue"; import {useAppStore} from "@/services/store/app"; import {Howl} from 'howler'; import menuSound from "@/assets/medias/menu.mp3" import {useNow, useDateFormat, useDark} from '@vueuse/core' import animate1Image from "./images/animate-1.png" import animate2Image from "./images/animate-2.png" import logoSvg from "@/assets/images/logo.svg" const appStore = useAppStore(); const now = useNow(); const nowTime = ref('') const timer = ref() const isDark = useDark(); //region sound var sound = new Howl({ src: [menuSound], volume: .4 }); const play = () => { sound.play(); }; //endregion const menus = [ {code:'home', text:'首页', icon:'mdi-home'}, {code:'network', text:'网络', icon:'mdi-lan'}, {code:'transfer', text:'数据', icon:'mdi-transfer'}/*, {code:'stat', text:'检索统计', icon:'mdi-chart-bar-stacked', href: headerQueryMenuUrl}, {code:'manage', text:'后台管理', icon:'mdi-monitor-dashboard', href:headerManageMenuUrl}*/ ]; import {usePageAnimate} from "@/services/hook/usePageAnimate"; import axios from "axios"; usePageAnimate("nav-ab"); onMounted(() => { }); onUnmounted(()=> { }) import { useFullscreen } from '@vueuse/core' import {headerManageMenuUrl, headerQueryMenuUrl} from "@/services/config"; const { isFullscreen, enter, exit, toggle: toggleFullscreen } = useFullscreen() </script> <style lang="scss" scoped> @use "sass:math"; @import "@/assets/css/_var"; $padding: 36px; .nav { position:absolute; left:$padding;right:$padding;top:$padding; z-index:10; height:80px; backdrop-filter: blur(3px); //box-shadow: 0 1px 10px rgba(0,0,0,.3) //background-color: rgba(red,.5); } .header-bg { //height: 90px; width:100%; //background: url(./images/header-bg.png) no-repeat bottom center; //background-size: contain; position: absolute; z-index:0; top:0;left:0;right:0;bottom:0; border-top: transparent solid 6px; border-bottom: transparent solid 1px; background: rgba($-primary-color, 0.3); border-top-color:$-primary-color; border-bottom-color: $-primary-color; box-shadow: 0 0 6px #035f71; &:after { content:""; position: absolute;top:0;bottom:0;left:0;right:0; //background: linear-gradient(45deg , rgba($-primary-color , .5) 60%, $-primary-color); } } .right-side { position: relative; } .logo-con { display: flex; align-items: center; justify-content: center; } .logo-border { //background:rgba(255,255,255,.1); padding:0 25px;display:flex;align-items:center; height:100%; position:relative;z-index:1; border-top:transparent solid 6px; border-bottom:transparent solid 6px; box-shadow: 1px 0 10px rgba(0,0,0,.2); border-color: rgba($-primary-color, 1);; } .logo-svg { width:60px;margin-left1:10px; //filter: drop-shadow( 0px 0px 6px rgba(#bcffff, .3)); //fill: #00c8e1; :deep { path {fill:#253223} path.lightning { fill:#ffcc00; stroke-width: 0; } //.circle-middle { // fill: #ffcc00; //} .dot {fill:#ffcc00;} .circle-bg {fill:transparent} } } .logo-text { padding-left:20px; font-family: shuhei;font-size:42px; margin-top:3px; text-shadow1: 5px 5px 1px rgba(255,255,255,.1); filter: drop-shadow( 1px 1px 2px #253223); background-image: -webkit-linear-gradient(90deg, rgb(245, 255, 250) , $-primary-color ); //background-image: linear-gradient(180deg,#fff,#2af1f8); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .menu-con { display: flex; flex:1; justify-content: center; position:relative;z-index:1; margin-top:6px; } .menu-item { display: flex; align-items: center;justify-content: center; border:rgba(#253223,.9) solid 1px; background: rgba($-primary-color,.4); color:rgba(#253223, .8); border-radius:2px; width:150px;height:44px; margin:0 15px; background-size:cover; text-align:center; font-size:20px; font-family: fzzzh; font-weight: normal; letter-spacing: 5px; transition: all .3s; span.mdi {opacity: .9} &:after, &:before { transition: all .3s; content:''; position: absolute; width:3px;height:24px; background: rgba(#253223,.6) } &:before {left:0;} &:after { right:0; } &:hover { border-color:#253223; color:#253223; background: rgba(#fff, .8); &:after, &:before { height:28px; background: rgba(#253223,.9) } &:after {right:3px} &:before {left:3px} } &.router-link-active { span.mdi {opacity: 1} color: $-primary-color; border-width:2px; border-radius:4px; border-color:$-primary-color; background: rgba(14, 31, 14,.9); font-weight:bold; box-shadow: 0 0 8px #253223; &:after, &:before { width:4px; background: rgba($-primary-color,.8) } } &.job, &.live, &.vehicle{ text-decoration: line-through; } } .animate-blocks { width: 55px; height: 25px; left: 662px; top: 74px; position: absolute; visibility: visible; pointer-events: none; transition: transform 600ms; display: flex; align-items: center; justify-content: space-evenly; } .animate-block-item { width:8px;height:10px; background: linear-gradient(to right , rgba(120, 255, 255, .8) , transparent); transform: skewX(-40deg); border-radius:1px; } .animate-1-con { position: absolute; pointer-events: none; left: 399px; top: 0; width: 120px; height: 100%; opacity:.3; } .animate-1-img { width:100%;height:100%; border-radius: unset; cursor: pointer; pointer-events: none; animation-name: animate-1; animation-iteration-count: infinite; animation-timing-function: linear; animation-duration: 5s; animation-delay: 0s; -webkit-user-drag: none; filter: none; } @keyframes animate-1 { 0% { opacity: 0; transform: none; } 15% { opacity: 0.75; transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) scaleX(1) scaleY(1) translate3d(150px, 0px, 0px); } 30% { opacity: 1; transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) scaleX(1) scaleY(1) translate3d(300px, 0px, 0px); } 45% { opacity: 0.75; transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) scaleX(1) scaleY(1) translate3d(450px, 0px, 0px); } 60% { opacity: 0; transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) scaleX(1) scaleY(1) translate3d(600px, 0px, 0px); } 100% { opacity: 0; transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) scaleX(1) scaleY(1) translate3d(600px, 0px, 0px); } } .animate-2-con { position: absolute; pointer-events: none; left: 646px; bottom: 0; width: 120px; height: 60%; opacity:.3; } .animate-2-img { width:100%;height:100%; border-radius: unset; cursor: pointer; pointer-events: none; animation-name: animate-2; animation-iteration-count: infinite; animation-timing-function: linear; animation-duration: 4s; animation-delay: 0s; -webkit-user-drag: none; filter: none; } @keyframes animate-2 { 0% { opacity: 0; transform: none; } 50% { opacity: .78; transform: translateX(450px); } 100% { opacity: 0; transform: translateX(900px); } } $star-width: math.div(1120px, 1.5); $star-height: math.div(660px, 1.5); .star { position:absolute;top:-113px;left:-10px; width:$star-width;height:$star-height; background: url(./images/star.png) no-repeat bottom center; background-size: cover; animation-name: star-animate; animation-iteration-count: infinite; animation-timing-function: linear; animation-duration: 10s; animation-delay: 10s; -webkit-user-drag: none; //filter: brightness(150%); } @keyframes star-animate { 0% { opacity: 1; } 50% { opacity: .5; } 100% { opacity: 1; } } div.nav.dark { .header-bg { border-top-color:rgb(71, 128, 76); border-bottom-color:rgba(6, 253, 253, .15); background: rgba($-primary-color, 0.3); //background-color: rgba(106, 211, 137, 0.12); &:after { background: linear-gradient(-45deg , rgba(0,0,0,.4), transparent); } } .logo-border { border-color: rgb(71, 128, 76); } .logo-text { background-image: -webkit-linear-gradient(90deg, rgb(150, 248, 140) 0%, rgb(245, 255, 250) 90%); } .logo-svg { :deep { path {fill:rgba(113, 228, 102,.6)} path.lightning { fill:#ffcc00; stroke-width: 0; } //.dot {fill:rgba(#fff,.7);} .circle-bg {fill:transparent} } } $-menu-color: #71e466; //7cffff .menu-item { border:rgba($-menu-color,.3) solid 1px; background: rgba(0,0,0,.2); color:rgba($-menu-color, .5); &:after, &:before { background: rgba($-menu-color,.3) } &:hover { border-color:$-menu-color; color:$-menu-color; background: rgba($-menu-color, .1); &:after, &:before { background: rgba($-menu-color,.6) } } &.router-link-active { color: $-menu-color; border-color:$-menu-color; &:after, &:before { background: rgba($-menu-color,.8) } } } } </style>
最新发布
07-22
<template> <div class="conversation-container"> <div class="conversation-list"> <div class="conversation-list-item"> <div class="conversation-list-title">待接入 {{ pendingConversations.length }}</div> <div class="conversation-list-body"> <router-link tag="div" :to="chat(conversation)" replace v-for="(conversation, key) in pendingConversations" :key="key"> <div class="conversation-item"> <div class="conversation-item-head"> <img :src="conversation.data.avatar" class="conversation-item-avatar" /> </div> <div class="item-info"> <div class="item-info-name">{{ conversation.data.name }}</div> <div v-if="conversation.lastMessage.type === 'text'" class="item-info-message"> {{ conversation.lastMessage.payload.text }} </div> <div v-else-if="conversation.lastMessage.type === 'image'" class="item-info-message">[图片消息]</div> <div v-else-if="conversation.lastMessage.type === 'video'" class="item-info-message">[视频消息]</div> <div v-else-if="conversation.lastMessage.type === 'audio'" class="item-info-message">[语音消息]</div> <div v-else-if="conversation.lastMessage.type === 'order'" class="item-info-message">[自定义消息:订单] </div> <div v-else-if="conversation.lastMessage.type === 'CS_END'" class="item-info-message">会话已结束</div> <div v-else-if="conversation.lastMessage.type === 'CS_ACCEPT'" class="item-info-message">接入成功</div> <div v-else-if="conversation.lastMessage.type === 'CS_TRANSFER'" class="item-info-message"> {{ conversation.lastMessage.senderId === currentAgent.id ? `已转接给` + conversation.lastMessage.payload.transferTo.data.name : '已接入来自' + conversation.lastMessage.senderData.name + '的转接' }} </div> <div v-else class="item-info-message">[未识别内容]</div> </div> </div> </router-link> </div> </div> <div class="conversation-list-item"> <div class="conversation-list-title">已接入 {{ conversations.length }}</div> <div v-if="conversations.length" class="conversation-list-body"> <router-link tag="div" :to="chat(conversation)" replace v-for="(conversation, key) in conversations" :key="key"> <div class="conversation-item" @contextmenu.prevent.stop="e => showRightClickMenu(e, conversation)"> <div class="conversation-item-head"> <img :src="conversation.data.avatar" class="conversation-item-avatar" /> <span v-if="conversation.unread" class="conversation-item-unread">{{ conversation.unread }}</span> </div> <div class="conversation-item-info"> <div class="item-info-top"> <div class="item-info-name">{{ conversation.data.name }}</div> <div class="item-info-time">{{ formatDate(conversation.lastMessage.timestamp) }}</div> </div> <div class="item-info-bottom"> <div v-if="conversation.lastMessage.status === 'sending'" class="item-info-sending"></div> <div v-if="conversation.lastMessage.status === 'fail'" class="item-info-failed"></div> <div v-if="conversation.lastMessage.type === 'text'" class="item-info-message"> {{ conversation.lastMessage.senderId === currentAgent.id ? '你' : conversation.lastMessage.senderData.name }}: {{ conversation.lastMessage.payload.text }} </div> <div v-else-if="conversation.lastMessage.type === 'image'" class="item-info-message">[图片消息]</div> <div v-else-if="conversation.lastMessage.type === 'video'" class="item-info-message">[视频消息]</div> <div v-else-if="conversation.lastMessage.type === 'audio'" class="item-info-message">[语音消息]</div> <div v-else-if="conversation.lastMessage.type === 'order'" class="item-info-message">[自定义消息:订单] </div> <div v-else-if="conversation.lastMessage.type === 'CS_END'" class="item-info-message">会话已结束</div> <div v-else-if="conversation.lastMessage.type === 'CS_ACCEPT'" class="item-info-message">接入成功</div> <div v-else-if="conversation.lastMessage.type === 'CS_TRANSFER'" class="item-info-message"> {{ conversation.lastMessage.senderId === currentAgent.id ? `已转接给` + conversation.lastMessage.payload.transferTo.data.name : '已接入来自' + conversation.lastMessage.senderData.name + '的转接' }} </div> <div v-else class="item-info-message">[未识别内容]</div> </div> </div> </div> </router-link> </div> </div> <div v-if="rightClickMenu.visible" :style="{ 'left': rightClickMenu.x + 'px', 'top': rightClickMenu.y + 'px' }" class="action-box"> <div class="action-item" @click="topConversation">{{ rightClickMenu.conversation.top ? '取消置顶' : '置顶' }}</div> <div class="action-item" @click="deleteConversation">删除聊天</div> </div> </div> <div class="conversation-main"> <router-view :key="$route.params.id"></router-view> </div> </div> </template> <script setup> import { ref, onMounted, onBeforeUnmount } from 'vue'; import { useRouter, useRoute } from 'vue-router'; import { formatDate } from '../utils/utils.js'; import GoEasy from 'goeasy'; // 引入真实的 GoEasy SDK import { useCounterStore } from '../stores/counter.js' const router = useRouter(); const route = useRoute(); // 定义响应式数据 const pendingConversations = ref([]); const conversations = ref([]); const rightClickMenu = ref({ conversation: null, visible: false, x: null, y: null, }); const currentAgent = ref(null); // 初始化 GoEasy const goEasy = GoEasy.getInstance({ host: 'hangzhou.goeasy.io', //应用所在的区域地址: 【hangzhou.goeasy.io |singapore.goeasy.io】 appkey: 'BC-f00d5ee0720d4dab888ca1b5536483ab', // common key, modules: ['im'], }); console.log('GoEasy initialized:', goEasy); console.log('GoEasy IM module:', goEasy.im); // 检查 IM 模块是否存在 // 其他代码保持不变... const loadConversations = () => { goEasy.im.pendingConversations({ onSuccess: (result) => { console.log('待接入会话:', result.content.conversations); renderPendingConversations(result.content); }, onFailed: (error) => { console.log('获取待接入列表失败:', error); }, }); goEasy.im.latestConversations({ onSuccess: (result) => { console.log('已接入会话:', result.content.conversations); renderLatestConversations(result.content); }, onFailed: (error) => { console.log('获取已接入列表失败:', error); }, }); }; const listenConversationUpdate = () => { // 监听会话列表变化 goEasy.im.on(goEasy.IM_EVENT.CONVERSATIONS_UPDATED, renderLatestConversations); goEasy.im.on(goEasy.IM_EVENT.PENDING_CONVERSATIONS_UPDATED, renderPendingConversations); }; const renderPendingConversations = (content) => { pendingConversations.value = content.conversations; }; const renderLatestConversations = (content) => { conversations.value = content.conversations; }; const chat = (conversation) => { return { path: `/conversations/chat/${conversation.id}`, query: { name: conversation.data.name, avatar: conversation.data.avatar, }, }; }; const showRightClickMenu = (e, conversation) => { rightClickMenu.value.conversation = conversation; rightClickMenu.value.visible = true; rightClickMenu.value.x = e.pageX; rightClickMenu.value.y = e.pageY; }; const hideRightClickMenu = () => { rightClickMenu.value.visible = false; }; const topConversation = () => { const conversation = rightClickMenu.value.conversation; const description = conversation.top ? '取消置顶' : '置顶'; goEasy.im.topConversation({ top: !conversation.top, conversation: conversation, onSuccess: () => { console.log(description, '成功'); }, onFailed: (error) => { console.log(description, '失败:', error); }, }); }; const deleteConversation = () => { if (!rightClickMenu.value.conversation.ended) { alert('删除失败:会话尚未结束'); return; } if (confirm('确认要删除这条会话吗?')) { goEasy.im.removeConversation({ conversation: rightClickMenu.value.conversation, onSuccess: () => { console.log('删除会话成功'); }, onFailed: (error) => { console.log(error); }, }); } }; onMounted(() => { // 隐藏 Conversation 右键菜单 document.addEventListener('click', hideRightClickMenu); // 获取当前客服信息 currentAgent.value = useCounterStore().currentAgent; console.log(currentAgent.value); // 监听 GoEasy 连接状态 goEasy.connect({ onSuccess: () => { console.log('GoEasy connected successfully'); // 确保用户信息存在 if (!currentAgent.value || !currentAgent.value.id || !currentAgent.value.name || !currentAgent.value.avatar) { console.error('Agent information is incomplete'); return; } // 登录IM goEasy.im.login({ id: currentAgent.value.id, // 必须 data: { // 必须 name: currentAgent.value.name, avatar: currentAgent.value.avatar, // 添加其他必要字段 }, onSuccess: () => { console.log('IM login success'); listenConversationUpdate(); loadConversations(); }, onFailed: (error) => { console.error('IM login failed:', error); } }); }, onFailed: (error) => { console.error('GoEasy connection failed:', error); } }); }); </script> <style scoped> .conversation-container { width: 100%; height: 100%; display: flex; background: #FFFFFF; } .conversation-list { width: 220px; border-right: 1px solid #eee; display: flex; flex-direction: column; padding: 10px; position: relative; } .conversation-list-title { font-size: 15px; margin: 5px 10px; color: rgba(0, 0, 0, 0.9); } .conversation-list-body { overflow-y: auto; max-height: 350px; scrollbar-width: none; -ms-overflow-style: none; } .conversation-list-body::-webkit-scrollbar { display: none; } .action-box { width: 100px; height: 60px; background: #ffffff; border: 1px solid #cccccc; position: fixed; z-index: 100; border-radius: 5px; } .action-item { padding-left: 15px; line-height: 30px; font-size: 13px; color: #262628; cursor: pointer; } .action-item:hover { background: #dddddd; } .conversation-item { display: flex; padding: 10px; cursor: pointer; } .conversation-item-head { position: relative; margin-right: 5px; } .conversation-item-avatar { width: 40px; height: 40px; border-radius: 4px; } .conversation-item-unread { position: absolute; top: -9px; right: -9px; width: 18px; height: 18px; line-height: 18px; border-radius: 50%; text-align: center; color: #fff; font-size: 12px; background-color: #fa5151; } .conversation-item-info { flex: 1; display: flex; flex-direction: column; justify-content: space-between; } .item-info-top { display: flex; justify-content: space-between; align-items: center; } .item-info-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; word-break: break-all; font-size: 15px; width: 80px; line-height: 25px; color: #333333; } .item-info-time { color: #666666; font-size: 12px; } .item-info-bottom { display: flex; align-items: center; } .item-info-message { font-size: 12px; line-height: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 150px; color: #606266; } .item-info-failed { background: url("../assets/images/failed.png") no-repeat center; background-size: 12px; width: 12px; height: 12px; margin-right: 2px; } .item-info-sending { background: url("../assets/images/pending.gif") no-repeat center; background-size: 12px; width: 12px; height: 12px; margin-right: 2px; } .router-link-active { background: #eeeeee; border-radius: 5px; } .conversation-main { flex: 1; background: #FFFFFF; } </style>我在用GoEasy实现即时通讯时报错code: 400, content: 'data: id and data are required for IM module
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值