Overte-community-apps-Alezi.../applications/BodyPaint4/html/brushesTab.html
SilverfishVR 6407bd7dff made Brush width edit field narrower
the "trigger sensitive Width" checkBox text was cut off
2022-08-25 00:12:02 +02:00

695 lines
No EOL
29 KiB
HTML

<!DOCTYPE html>
<html>
<script type="text/javascript" src="../hifi/js/keyboardControl.js"></script>
<script src="../hifi/js/jquery-2.1.4.min.js"></script>
<script src="../content/js/ColorUtils.js"></script>
<script src="../hifi/js/colpick.js"></script>
<style>
input[type=range] {
-webkit-appearance: none;
background: #2e2e2e;
height: 1.8rem;
border-radius: 1rem;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance:none;
width: 0.6rem;
height: 1.8rem;
padding:0;
margin: 0;
background-color: #696969;
border-radius: 1rem;
}
input[type=range]::-webkit-slider-thumb:hover {
background-color: white;
}
input[type=range]:focus {
outline: none;
}
.sliderWrapper {
display: table;
padding: 0.4rem 0;
}
.property.range input[type=number] {
margin-left: 0.8rem;
width: 3.4rem;
height: 1.8rem;
}
.brushButton {
background-color: #2e2e2e;
border:none;
position: relative;
width: 80px;
margin: 1px 0px;
}
.checkbox {
margin: 0px;
}
.BrushIcon {
width: 100%;
height: 80px;
background-size: 75% 75%;
background-position: center;
background-repeat: no-repeat;
background-blend-mode: multiply;
background-image: url("../hifi/resources/icons/loadingDark.gif");
-webkit-mask-repeat: no-repeat;
}
#animatedBrush {
margin: 20px 0;
}
.selectedBrush {
position: relative;
}
#selectedOverlay {
background-color: rgba(16, 128, 184, 0.7);
top:0;
left:0;
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
color: white;
font-size: 25px;
display: flex;
align-items: center;
justify-content: center;
}
#brushesCointainer {
margin-bottom: 50px;
margin-top: 24px;
}
.imageContainer {
display: block;
position: relative;
margin-bottom: 5px;
height: 80px;
}
.brushLabel {
display: block;
position: relative;
margin-bottom: 5px;
color: white;
width: 100%;
font-size: 12px;
z-index: 2;
word-wrap: break-word;
text-overflow: ellipsis;
}
#strokeWidthWidget {
position: fixed;
background-color: #404040;
display: flex;
z-index: 3;
width: 100%;
top: -1px;
margin: 0px;
padding: 15px 0px;
border: none;
padding-left: 21px;
left: 0px;
}
#pressureSensitiveCheckbox {
margin-left: 20px;
margin-top: 23px;
}
.animationBrush input[type=checkbox]:disabled + label,
.dynamicBrush input[type=checkbox]:disabled + label {
color: #202020;
}
.brushes-group[collapsed="true"] ~ .brushes-group,
.special-group[collapsed="true"] ~ .special-group {
display: none !important;
}
#brushesContent {
margin-top: 48px
}
.effectPreview {
width: 40px;
height: 18px;
background-color: red;
display: inline-block;
margin-right: 10px;
margin-top: 4px;
}
#continuousLineIcon {
text-align: center;
background-color: transparent;
color: white;
font-size: 32px;
margin-top: -6px;
}
</style>
<link rel="stylesheet" type="text/css" href="../hifi/css/edit-style.css">
<div id="strokeWidthWidget" class="property range">
<div>
<label style="display: block">Stroke Width</label>
<div class="sliderWrapper">
<input type="range" id="lineWidthRange" value=0.25 min=0 max=1 step=0.01 onchange="changeLineWidthRange(this)"/>
<input type="number" id="lineWidthText" value=0.25 min=0 max=1 step=0.01 onchange="changeLineWidthNumber(this)"/>
</div>
</div>
<div id="pressureSensitiveCheckbox" class="behavior-group property checkbox">
<input onchange="switchPressureSensitiveWidth(this)" type="checkbox" id="triggerSensitiveWidth"></input>
<label for="triggerSensitiveWidth">Trigger Sensitive Width</label>
</div>
</div>
<div id="brushesContent">
<div id="properties-list">
<fieldset class="major">
<legend id="special-section" class="section-header special-group special-section">
Special Effects<span>M</span>
</legend>
<div class="special-group special-brushes-section special-section">
<div class="special-group special-brushes property checkbox">
<span id="continuousLineIcon" class="glyph effectPreview">&#8734;</span>
<input onchange="setContinuosLineMode(this)" type="checkbox" id="continuousLine"></input>
<label for="continuousLine">Use Continuous Line</label>
</div>
<div class="special-group behavior-group property checkbox animationBrush">
<span id="animatedHue" class="effectPreview"></span>
<input onchange="setAnimatedBrush(this)" type="checkbox" id="animatedBrush"></input>
<label for="animatedBrush">Use Hue Animation</label>
</div>
<div class="special-group behavior-group property checkbox dynamicBrush">
<span id="hue" class="effectPreview"></span>
<input onchange="setDynamicBrush(this)" type="checkbox" id="dynamicHue"></input>
<label for="dynamicHue">Use Dynamic Hue</label>
</div>
<div class="special-group behavior-group property checkbox dynamicBrush">
<span id="saturation" class="effectPreview"></span>
<input onchange="setDynamicBrush(this)" type="checkbox" id="dynamicSaturation"></input>
<label for="dynamicSaturation">Use Dynamic Saturation</label>
</div>
<div class="special-group behavior-group property checkbox dynamicBrush">
<span id="value" class="effectPreview"></span>
<input onchange="setDynamicBrush(this)" type="checkbox" id="dynamicValue"></input>
<label for="dynamicValue">Use Dynamic Brightness</label>
</div>
</div>
</fieldset>
<fieldset class="major">
<legend id="brush-section" class="section-header brushes-group brushes-section">
Brushes<span>M</span>
</legend>
<div id="brushesCointainer" class="brushes-group">
<button class="brushButton" brushType="stretch" id="content/brushes/square.png" onclick="changePaintBrush(0)">
<div class="imageContainer">
<div imageSrc="../content/brushes/square.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Square</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/paintbrush6.png" onclick="changePaintBrush(1)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush6.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Rounded</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/soft.png" onclick="changePaintBrush(2)">
<div class="imageContainer">
<div imageSrc="../content/brushes/soft.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Soft</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/dupuiz.png" onclick="changePaintBrush(3)">
<div class="imageContainer">
<div imageSrc="../content/brushes/dupuiz.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Tri</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/basic.png" onclick="changePaintBrush(4)">
<div class="imageContainer">
<div imageSrc="../content/brushes/basic.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Basic</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/oil.png" onclick="changePaintBrush(5)">
<div class="imageContainer">
<div imageSrc="../content/brushes/oil.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Oil</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/gouache.png" onclick="changePaintBrush(6)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gouache.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Gouache A</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/gouache.png" onclick="changePaintBrush(7)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gouacheB.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Gouache B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/koons.png" onclick="changePaintBrush(8)">
<div class="imageContainer">
<div imageSrc="../content/brushes/koons.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Koons</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/sponge.png" onclick="changePaintBrush(9)">
<div class="imageContainer">
<div imageSrc="../content/brushes/sponge.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Sponge A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/sponge.png" onclick="changePaintBrush(10)">
<div class="imageContainer">
<div imageSrc="../content/brushes/spongeB.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Sponge B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/graphite.png" onclick="changePaintBrush(11)">
<div class="imageContainer">
<div imageSrc="../content/brushes/graphite.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Graphite</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/bristle.png" onclick="changePaintBrush(12)">
<div class="imageContainer">
<div imageSrc="../content/brushes/bristle.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Bristle</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/spat-fine.png" onclick="changePaintBrush(13)">
<div class="imageContainer">
<div imageSrc="../content/brushes/spat-fine.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Spat</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/gradient2.png" onclick="changePaintBrush(14)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gradient2.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Gradient A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gradient2.png" onclick="changePaintBrush(15)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gradient2.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Gradient B</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/dot.png" onclick="changePaintBrush(16)">
<div class="imageContainer">
<div imageSrc="../content/brushes/dot.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Dot</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/polka.png" onclick="changePaintBrush(17)">
<div class="imageContainer">
<div imageSrc="../content/brushes/polka.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Polka</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/heart.png" onclick="changePaintBrush(18)">
<div class="imageContainer">
<div imageSrc="../content/brushes/heart.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Heart</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/hearts.png" onclick="changePaintBrush(19)">
<div class="imageContainer">
<div imageSrc="../content/brushes/hearts.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Hearts</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/flowers2.png" onclick="changePaintBrush(20)">
<div class="imageContainer">
<div imageSrc="../content/brushes/flowers2.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Flowers</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/leaves.png" onclick="changePaintBrush(21)">
<div class="imageContainer">
<div imageSrc="../content/brushes/leaves.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Leaves</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/snowflakes2.png" onclick="changePaintBrush(22)">
<div class="imageContainer">
<div imageSrc="../content/brushes/snowflakes2.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Snowflakes</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/paintbrush1.png" onclick="changePaintBrush(23)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush1.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Stars</div>
</button>
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/breakfast.png" onclick="changePaintBrush(24)">
<div class="imageContainer">
<div imageSrc="../content/brushes/breakfast.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Breakfast</div>
</button>
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/newton.png" onclick="changePaintBrush(25)">
<div class="imageContainer">
<div imageSrc="../content/brushes/newton.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Newton</div>
</button>
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/softy.png" onclick="changePaintBrush(26)">
<div class="imageContainer">
<div imageSrc="../content/brushes/softy.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Softbow</div>
<button class="brushButton" brushType="repeat" id="content/brushes/paw-print.png" onclick="changePaintBrush(27)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paw-print.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Paws</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/barbWire.png" onclick="changePaintBrush(28)">
<div class="imageContainer">
<div imageSrc="../content/brushes/barbWire.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">KeepOut</div>
</button>
</button>
</fieldset>
</div>
</div>
</div>
</html>
<script type="text/javascript">
var ANIMATED_HUE_STEP = 1;
var currentBrush = 0;
var colorAnimPreviewInterval = null;
var currentAnimationColor = {h: 0, s: 100, b: 100};
colorAnimPreviewInterval = setInterval(setHueAnimationColorPreview, 30);
var EventBridge = parent.EventBridge;
function changeLineWidthRange(e) {
document.getElementById("lineWidthText").value = e.value;
notifyLineWidthChanged(e);
}
function changeLineWidthNumber(e) {
if (e.value > 1) {
document.getElementById("lineWidthText").value = 1;
}
if (e.value < 0) {
document.getElementById("lineWidthText").value = 0;
}
document.getElementById("lineWidthRange").value = e.value > 1 ? 1 : e.value;
document.getElementById("lineWidthRange").value = e.value < 0 ? 0 : e.value;
notifyLineWidthChanged(e);
}
function notifyLineWidthChanged(e) {
var changeLineWidthEvent = {
"type" : "changeLineWidth",
"brushWidth": e.value
};
EventBridge.emitWebEvent(JSON.stringify(changeLineWidthEvent));
}
function switchPressureSensitiveWidth(checkbox) {
// 'jscolor' instance can be used as a string
var switchPressureSensitiveWidthEvent = {
"type" : "switchTriggerPressureWidth",
"enabled" : checkbox.checked,
};
EventBridge.emitWebEvent(JSON.stringify(switchPressureSensitiveWidthEvent));
}
function changePaintBrush(brushIndex) {
var brushes = document.getElementById("brushesCointainer").children;
brushes[currentBrush].classList.remove("selectedBrush");
if (document.getElementById("selectedOverlay"))
document.getElementById("selectedOverlay").remove();
currentBrush = brushIndex;
brushes[currentBrush].classList.add("selectedBrush");
var selectedOverlay = document.createElement("div");
selectedOverlay.id = "selectedOverlay";
selectedOverlay.innerHTML = "&#x2714";
brushes[currentBrush].children[0].appendChild(selectedOverlay);
var changedBrushEvent = {
"type" : "changeBrush",
"brushName": brushes[currentBrush].id,
"brushType": brushes[currentBrush].getAttribute("brushType"),
"isColored": brushes[currentBrush].getAttribute("colored"),
"brushID" : brushIndex
};
EventBridge.emitWebEvent(JSON.stringify(changedBrushEvent));
}
function switchDynamicBrushEnabledStatus(checkbox) {
var isAnyAnimatedChecked = false;
$(".animationBrush").each(function( index ) {
isAnyAnimatedChecked |= $(this).find("input[type=checkbox]")[0].checked;
});
$(".dynamicBrush").each(function( index ) {
$(this).find("input[type=checkbox]")[0].disabled = isAnyAnimatedChecked;
});
}
function switchAnimationBrushEnabledStatus(checkbox) {
var isAnyDynamicChecked = false;
$(".dynamicBrush").each(function( index ) {
isAnyDynamicChecked |= $(this).find("input[type=checkbox]")[0].checked;
});
$(".animationBrush").each(function( index ) {
$(this).find("input[type=checkbox]")[0].disabled = isAnyDynamicChecked;
});
}
function setAnimatedBrush(checkbox) {
switchDynamicBrushEnabledStatus();
var switchAnimatedBrushEvent = {
"type" : "switchAnimatedBrush",
"animatedBrushName": "animatedHueBrush",
"enabled" : checkbox.checked,
"settings" : null,
"animatedBrushID" : checkbox.id
};
EventBridge.emitWebEvent(JSON.stringify(switchAnimatedBrushEvent));
}
function setDynamicBrush(checkbox) {
switchAnimationBrushEnabledStatus();
var switchDynamicBrushEvent = {
"type" : "switchDynamicBrush",
"enabled" : checkbox.checked,
"dynamicBrushId" : checkbox.id
};
EventBridge.emitWebEvent(JSON.stringify(switchDynamicBrushEvent));
}
function setContinuosLineMode(checkbox) {
var switchContinuousDrawModeEvent = {
"type" : "switchIsContinuous",
"enabled" : checkbox.checked,
};
EventBridge.emitWebEvent(JSON.stringify(switchContinuousDrawModeEvent));
}
function resizeImage(image, width, height) {
var height = height == width ? "80px" : "40px";
image.css("height", height);
image.first().css("background-image", "url(" + image.attr('imageSrc') + ")");
image.first().css("background-size", "contain");
image.first().css("background-position", "center");
if (height == "40px") {
image.first().css("top", "18px");
image.first().css("position", "absolute");
}
}
function setPreviewColors(id, hsvColor, num_steps, hsvComponent, min, max, start, step_size) {
var gradient_step = 100.0 / (num_steps - 1);
var previewColor = {h: hsvColor.h, s: hsvColor.s, b: hsvColor.b};
var gradientStr = "";
//generate the gradient string
previewColor[hsvComponent] = start;
for (var i = 0; i < num_steps; i++) {
gradientStr += "#" + $.colpick.hsbToHex({h: previewColor.h, s: previewColor.s, b: previewColor.b})
+ " " + (gradient_step * i).toFixed(1) + "%";
gradientStr += i < (num_steps - 1) ? ", " : "";
previewColor[hsvComponent] = start + (i + 1) * step_size;
previewColor[hsvComponent] = previewColor[hsvComponent] > max
? min + (previewColor[hsvComponent] % (max - min))
: previewColor[hsvComponent];
}
$(id).css("background", "-webkit-linear-gradient(left, " + gradientStr + ")");
}
function setHueAnimationColorPreview() {
currentAnimationColor.h += ANIMATED_HUE_STEP;
currentAnimationColor.h = currentAnimationColor.h > 360
? 360 - currentAnimationColor.h
: currentAnimationColor.h;
$("#animatedHue").css("background-color",
"#" + $.colpick.hsbToHex({h: currentAnimationColor.h, s: currentAnimationColor.s, b: currentAnimationColor.b}));
}
function setStrokeColor(strokeColor) {
$(".imageContainer").each(function( index ) {
//recalculate the image height so it keeps the aspect ratio
var image = new Image();
image.src = $(this).find('div').first().attr('imageSrc');
var img = $(this).find('div').first();
image.addEventListener("load", function(){
resizeImage(img, this.naturalWidth, this.naturalHeight);
});
if (!$(this).parent().attr("colored")) {
$(this).find('div').first().css("-webkit-mask-box-image",
"url(" + $(this).find('div').first().attr('imageSrc') + ")");
$(this).find('div').first().css("background-color",
"rgb(" + strokeColor.red + ", " + strokeColor.green + ", " + strokeColor.blue + ")");
}
});
var hsvColor = $.colpick.rgbToHsb({r: strokeColor.red, g: strokeColor.green, b: strokeColor.blue});
setPreviewColors("#hue", hsvColor, 7, "h", 0, 360, hsvColor.h, 60);
setPreviewColors("#saturation", hsvColor, 2, "s", 50, 100, 100, 50);
setPreviewColors("#value", hsvColor, 2, "b", 60, 100, 100, 60);
currentAnimationColor = {h: hsvColor.h, s: hsvColor.s, b: hsvColor.b};
}
restoreSavedBrushes(JSON.parse(decodeURIComponent(window.parent.location.search).substring(1)));
function restoreSavedBrushes(brushData) {
if ("currentTexture" in brushData) {
changePaintBrush(brushData.currentTexture.brushID);
}
if ("currentAnimatedBrushes" in brushData) {
var animatedBrushes = brushData.currentAnimatedBrushes;
for (var i = 0; i < animatedBrushes.length; i++) {
document.getElementById(animatedBrushes[i]).checked = true;
//Fix for onchange not being called (this appears to be the only checkbox where this happens)
$("#" + animatedBrushes[i]).trigger("change");
}
switchDynamicBrushEnabledStatus();
}
if ("currentDynamicBrushes" in brushData) {
for(var key in brushData.currentDynamicBrushes) {
document.getElementById(key).checked = brushData.currentDynamicBrushes[key];
}
switchAnimationBrushEnabledStatus();
}
if ("currentColor" in brushData) {
setStrokeColor(brushData.currentColor);
}
if ("currentStrokeWidth" in brushData) {
document.getElementById("lineWidthRange").value = brushData.currentStrokeWidth;
changeLineWidthRange({value: brushData.currentStrokeWidth});
changeLineWidthNumber({value: brushData.currentStrokeWidth});
}
if ("currentTriggerWidthEnabled" in brushData) {
document.getElementById("triggerSensitiveWidth").checked = brushData.currentTriggerWidthEnabled;
}
if ("currentIsContinuous" in brushData) {
document.getElementById("continuousLine").checked = brushData.currentIsContinuous;
}
if ("currentHeadersCollapsedStatus" in brushData) {
for (var key in brushData.currentHeadersCollapsedStatus) {
var element = document.getElementById(key);
if (brushData.currentHeadersCollapsedStatus[key]) {
element.setAttribute("collapsed", "true");
element.getElementsByTagName("span")[0].textContent ="L";
}
}
}
}
window.addEventListener("message", receiveStrokeColor, false);
function receiveStrokeColor(message) {
var event = JSON.parse(message.data);
setStrokeColor(event.value);
}
$(window).load(function(){
setUpKeyboardControl();
// Collapsible sections
var elCollapsible = document.getElementsByClassName("section-header");
var toggleCollapsedEvent = function(event) {
var element = event.target;
var isCollapsed = element.getAttribute("collapsed") !== "true";
element.setAttribute("collapsed", isCollapsed ? "true" : "false");
element.getElementsByTagName("span")[0].textContent = isCollapsed ? "L" : "M";
var switchCollapsedState = {
"type" : "switchCollapsed",
"isCollapsed": isCollapsed,
"sectionId" : element.getAttribute("id")
};
EventBridge.emitWebEvent(JSON.stringify(switchCollapsedState));
};
for (var i = 0, length = elCollapsible.length; i < length; i++) {
var element = elCollapsible[i];
element.addEventListener("click", toggleCollapsedEvent, true);
};
});
window.onbeforeunload = function(){
clearInterval(colorAnimPreviewInterval);
}
</script>