Triangular pictslider?
Hi guys,
I'm currently trying to make a triangular interactive xyz graph using pictslider, is there any way to set the boundaries of the object to fit in a triangular shape? Any help would be great!
you can use a mask for the transparency?
or design the graphics so that you use the background as "background". these are made without trasparency, it is all squared. not the worst idea for mousing, btw.
if that is not enough flexibility, lcd with sprites and background images or jitter are next on the plan.


Hi Roman,
Thanks for your response.
I'm actually hoping to somehow format the pictslider knob control to stay within the margins of a triangular image, allowing for vertical and horizontal control within the shape's margins. I don't know if its possible, unless each knob movement has an if statement attached that automates the margin boundaries, but that would be a very complex method.
I have a jsui but I can't send it at the moment. If you don't hear from me, remind me tomorrow.
as usual i misunderstood the question.
but this is easy! calculate the boundaries and when the mouse is about to leave the shape, convert the output either to the closest value on the border of the shape, or the last value which did not hit the border and then do [prepend set] and set the control back to the last "legit" value.
i´ve done that with circle and ellipse for pictureslider and the haptics is just fine, the mouse does what you would expect.
//Is this what you're looking for?
mgraphics.init();
mgraphics.relative_coords = 1;
mgraphics.autofill = 0;
var knobYMargin = 15;
var width = box.rect[2] - box.rect[0];
var height = box.rect[3] - box.rect[1];
var aspect = width/height;
var xMin = 0
var xMax = 100
var yMin = 0
var yMax = 100
var bgColor = [0,.3,0,1];
var fgColor = [1,.7,0,1]
var valY =yMin;
var valX = xMin;
function paint()
{
var knobYTop = height-knobYMargin;
var knobXDeviation = knobYMargin*width/(height*2)
var knobXPosMin = knobXDeviation;
var knobXPosMax = width-knobXDeviation;
var normY = scale(valY,yMin,yMax,0,knobYTop);
var normXTriScale = (normY/knobYTop);
var normX = scale(valX,xMin,xMax,knobXPosMin,knobXPosMax);
var boundR = lininterp(width/2,knobXPosMax,normXTriScale);
var boundL = lininterp(width/2,knobXPosMin,normXTriScale);
var normX = Math.max(boundL,Math.min(normX,boundR));
var knobCoords = knobDrawCoords(normX,normY,knobXDeviation);
var coordA = pixToRelative(knobCoords[0],knobCoords[1],width,height);
var coordB = pixToRelative(knobCoords[2],knobCoords[3],width,height);
var coordC = pixToRelative(knobCoords[4],knobCoords[5],width,height);
//big triangle
mgraphics.set_source_rgba(bgColor);
mgraphics.move_to(0,-1);
mgraphics.line_to(-aspect,1);
mgraphics.line_to(aspect,1);
mgraphics.line_to(0,-1);
mgraphics.fill();
//knob
mgraphics.set_source_rgba(fgColor);
mgraphics.move_to(coordA[0],coordA[1]);
mgraphics.line_to(coordB[0],coordB[1]);
mgraphics.line_to(coordC[0],coordC[1]);
mgraphics.line_to(coordA[0],coordA[1]);
mgraphics.fill();
}
function pixToRelative(x,y,xdim,ydim){
var aspect = xdim/ydim;
return [scale(x,0,xdim,-aspect,aspect),scale(y,0,ydim,-1,1)];
}
function relativeToPix(x,y,xdim,ydim){
var aspect = xdim/ydim;
return [scale(x,-aspect,aspect,0,xDim),scale(y,-1,1,0,ydim)];
}
function scale(val,inMin,inMax,outMin,outMax){
if(inMax==inMin)
return outMax
return ((val-inMin)/(inMax-inMin))*(outMax-outMin)+outMin;
}
function knobDrawCoords(x,y,knobXDeviation){
return [x,y,x+knobXDeviation,y+knobYMargin,x-knobXDeviation,y+knobYMargin];
}
function lininterp(start,end,perc){
return ((end-start)*perc)+start;
}
function onclick(x,y,but,mod1,shift,caps,opt,mod2){
ondrag(x,y,but,mod1,shift,caps,opt,mod2);
}
function ondrag(x,y,but,mod1,shift,caps,opt,mod2){
valY=scale(y,height-knobYMargin,0,yMin,yMax);
valY = clip(valY,yMin,yMax);
var normalizedX = x/width;
var xMinAsFunctionOfY = scale(y,0,height,0,width/2);
var xMinAsFunctionOfY = clip(xMinAsFunctionOfY,0,width/2);
valX = scale(x,xMinAsFunctionOfY,width-xMinAsFunctionOfY,xMin,xMax); // makes nan
valX = clip(valX,xMin,xMax);
outlet(0,valX,valY);
refresh();
}
function clip(val,mini,maxi){
return Math.max(mini,Math.min(maxi,val));
}
function setVal(x,y){
valX= clip(x,xMin,xMax);
valY= clip(y,yMin,yMax);
refresh();
}
function onresize(){
var width = box.rect[2] - box.rect[0];
var height = box.rect[3] - box.rect[1];
var aspect = width/height;
refresh();
}
function set(x,y){
valX= clip(x,xMin,xMax);
valY= clip(y,yMin,yMax);
refresh();
outlet(0,valX,valY);
}
function clip(val,mi,ma){
return Math.min(ma,Math.max(mi,val));
}
Thanks for the solutions! Both of those work how I want, and I actually found a third method involving (like Roman said) calculating just the lower and upper margins for the left and right border, and then sending the vertical value into a scale object routed to the margin message. It's a little less elegant but it seems to be working. I'll try out all 3 in context and see what fits. Thanks again!