File size: 4,764 Bytes
c6535db | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | <template lang="pug">
div(:class="prefix" :data-id="id")
template(v-if="values?.length>0 && show")
div(:class="[prefix + '-item',{'positive': index == 3 && type == 'sdxl' && mode == IPA_LAYER_WEIGHTS}, {'negative': index == 6 && type == 'sdxl' && mode == IPA_LAYER_WEIGHTS}]" v-for="(item,index) in values" :key="index")
div(:class="prefix + '-item-input'") {{item.value}}
div(:class="prefix + '-item-scroll'" ref="scroll")
div(:class="prefix + '-item-bar'" ref="bar" :style="{'top':item.top || (100 - calculatePercent(item.default,item.min,item.max) + '%')}" @mousedown="e=>mousedown(e,item,index)" @dblclick="e=>dblclick(e,item,index)")
div(:class="prefix + '-item-area'" :style="{'height':item.height || calculatePercent(item.default,item.min,item.max) + '%'}")
div(:class="prefix + '-item-label'")
span {{item.label}}
</template>
<script setup>
import { $t } from '@/composable/i18n.js'
import { ref, reactive, computed, watch, defineComponent, defineProps, defineEmits, onMounted } from 'vue'
import cloneDeep from "lodash/cloneDeep";
const prefix = 'comfyui-easyuse-slider'
defineComponent({name:prefix})
const IPA_LAYER_WEIGHTS = 'ipadapter layer weights'
const props = defineProps({
id: {
type: String | Number,
default: ''
},
mode:{
type: String,
default: ''
},
type:{
type: String,
default: ''
},
values:{
type: Array,
default: []
},
show:{
type:Boolean,
default:false
}
})
const emit = defineEmits(['changeValues','showSlider'])
const calculatePercent = (value,min,max) => ((value - min) / (max - min) * 100)
const getIPALayerDefaultValue = (length, i, v = undefined) => {
switch (props.mode){
case IPA_LAYER_WEIGHTS:
let default_values = {3:2.5,6:1}
let value = default_values[i] || 0
return {
default: length == 12 ? value : 0,
min:-1,
max:3,
step:0.05,
value: v!==undefined ? v : (length == 12 ? value : 0),
top: v!==undefined ? (100 - calculatePercent(v,-1,3) + '%') : null,
height: v!==undefined ? calculatePercent(v,-1,3) + '%' : null,
}
}
}
watch(_ => props.mode, async (newValue, oldValue) => {
if(newValue!==oldValue){
switch (newValue) {
case IPA_LAYER_WEIGHTS:
if(!oldValue && props.values?.length > 0){
const array = props.values.map(item=>{
const v = item.split(':')
return getIPALayerDefaultValue(props.values.length, v[0], parseFloat(v[1]))
})
await emit('changeValues', array)
}else{
let length = props.type == 'sd1' ? 16 : 12
let array = Array.from({length}, (v, i) => (getIPALayerDefaultValue(length, i)))
await emit('changeValues', array)
}
break
}
}
emit('showSlider')
},{
immediate:true
})
watch(_=> props.type, (newValue, oldValue) =>{
if(newValue == oldValue) return
if(props.mode == IPA_LAYER_WEIGHTS){
let length = props.type == 'sd1' ? 16 : 12
let array = Array.from({length}, (v, i) => (getIPALayerDefaultValue(length, i)))
emit('changeValues', array)
}
})
const scroll = ref(null)
const bar = ref(null)
const mousedown = (e, item, index)=>{
let event = e || window.event;
let _scroll = scroll.value[index]
let _bar = bar.value[index]
let _values = cloneDeep(props.values)
let y = event.clientY - _bar.offsetTop;
document.onmousemove = (e) => {
let event = e || window.event;
let top = event.clientY - y;
if(top < 0){
top = 0;
}
else if(top > _scroll.offsetHeight - _bar.offsetHeight){
top = _scroll.offsetHeight - _bar.offsetHeight;
}
// top到最近的GridHeight值
let GridTotal = (item.max - item.min) / item.step
let GridHeight = (_scroll.offsetHeight - _bar.offsetHeight)/ GridTotal
top = Math.round(top / GridHeight) * GridHeight;
const _top = Math.floor(top/(_scroll.offsetHeight - _bar.offsetHeight)* 100) + '%';
const _height = Math.floor((_scroll.offsetHeight - _bar.offsetHeight - top)/(_scroll.offsetHeight - _bar.offsetHeight)* 100) + '%';
const _value = parseFloat(parseFloat(item.max - (item.max-item.min) * (top/(_scroll.offsetHeight - _bar.offsetHeight))).toFixed(2))
_values[index] = {..._values[index],...{ top:_top, height:_height, value:_value}}
emit('changeValues', _values)
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
}
}
const dblclick = (e, item, index)=>{
let _values = cloneDeep(props.values)
_values[index] = {..._values[index],...{ top:null, height:null, value:item.default}}
emit('changeValues', _values)
}
onMounted(()=>{
document.onmouseup = _=> document.onmousemove = null;
})
</script> |