Spaces:
Running
Running
(window["webpackJsonpGUI"] = window["webpackJsonpGUI"] || []).push([["addon-entry-default-costume-editor-color"],{ | |
/***/ "./src/addons/addons/default-costume-editor-color/_runtime_entry.js": | |
/*!**************************************************************************!*\ | |
!*** ./src/addons/addons/default-costume-editor-color/_runtime_entry.js ***! | |
\**************************************************************************/ | |
/*! exports provided: resources */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resources", function() { return resources; }); | |
/* harmony import */ var _userscript_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./userscript.js */ "./src/addons/addons/default-costume-editor-color/userscript.js"); | |
/* generated by pull.js */ | |
const resources = { | |
"userscript.js": _userscript_js__WEBPACK_IMPORTED_MODULE_0__["default"] | |
}; | |
/***/ }), | |
/***/ "./src/addons/addons/default-costume-editor-color/userscript.js": | |
/*!**********************************************************************!*\ | |
!*** ./src/addons/addons/default-costume-editor-color/userscript.js ***! | |
\**********************************************************************/ | |
/*! exports provided: default */ | |
/***/ (function(module, __webpack_exports__, __webpack_require__) { | |
; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony default export */ __webpack_exports__["default"] = (async function (_ref) { | |
let { | |
addon, | |
console, | |
msg | |
} = _ref; | |
// We don"t *need* to wait for the costume editor to be opened, but redux updates take a non-zero | |
// amount of CPU time so let's delay that for as long as possible. | |
await addon.tab.traps.getPaper(); | |
const hexComponent = str => Math.round(+str).toString(16).toUpperCase().padStart(2, "0"); | |
const parseColor = color => { | |
if (color === null) { | |
return null; | |
} | |
if (typeof color === "string") { | |
// TW natively supports hex color codes with or without transparency | |
if (color.startsWith("#")) { | |
return color.substring(0, 9).toUpperCase(); | |
} | |
// Sometimes paper gives us rgb() colors which have to be converted to hex | |
const rgbMatch = color.match(/^rgb\((\d+)\s*,(\d+)\s*,(\d+)\)$/); | |
if (rgbMatch) { | |
const [_, r, g, b] = rgbMatch; | |
return "#".concat(hexComponent(r)).concat(hexComponent(g)).concat(hexComponent(b)); | |
} | |
// It can also give us rgba() colors | |
const rgbaMatch = color.match(/^rgba\((\d+)\s*,(\d+)\s*,(\d+),([\d.]+)\)$/); | |
if (rgbaMatch) { | |
const [_, r, g, b, a] = rgbaMatch; | |
return "#".concat(hexComponent(r)).concat(hexComponent(g)).concat(hexComponent(b)).concat(hexComponent(a * 255)); | |
} | |
} | |
console.log("Could not normalize color", color); | |
return null; | |
}; | |
const parseColorStyleColor = color => { | |
if (color === MIXED) return MIXED; | |
return parseColor(color); | |
}; | |
// Special value Scratch uses as color when objects with different colors are selected | |
// https://github.com/LLK/scratch-paint/blob/6733e20b56f52d139f9885952a57c7da012a542f/src/helper/style-path.js#L10 | |
const MIXED = "scratch-paint/style-path/mixed"; | |
const SCRATCH_DEFAULT_FILL = parseColor("#9966FF"); | |
const SCRATCH_DEFAULT_STROKE = parseColor("#000000"); | |
const TOOL_INFO = Object.assign(Object.create(null), { | |
// Tool names and gradient info defined in https://github.com/LLK/scratch-paint/blob/develop/src/lib/modes.js | |
// Search for activateTool() in matching file in https://github.com/LLK/scratch-paint/tree/develop/src/containers | |
BRUSH: { | |
resetsFill: true | |
}, | |
ERASER: {}, | |
LINE: { | |
resetsStroke: true, | |
requiresNonZeroStrokeWidth: true, | |
supportsGradient: true | |
}, | |
FILL: { | |
resetsFill: true, | |
supportsGradient: true | |
}, | |
SELECT: { | |
supportsGradient: true | |
}, | |
RESHAPE: { | |
supportsGradient: true | |
}, | |
OVAL: { | |
resetsFill: true, | |
resetsStroke: true, | |
supportsGradient: true | |
}, | |
RECT: { | |
resetsFill: true, | |
resetsStroke: true, | |
supportsGradient: true | |
}, | |
TEXT: { | |
resetsFill: true, | |
resetsStroke: true | |
}, | |
BIT_BRUSH: { | |
resetsFill: true | |
}, | |
BIT_LINE: { | |
resetsFill: true, | |
requiresNonZeroStrokeWidth: true | |
}, | |
BIT_OVAL: { | |
resetsFill: true, | |
resetsStroke: true, | |
supportsGradient: true | |
}, | |
BIT_RECT: { | |
resetsFill: true, | |
resetsStroke: true, | |
supportsGradient: true | |
}, | |
BIT_TEXT: { | |
resetsFill: true, | |
resetsStroke: true | |
}, | |
BIT_FILL: { | |
resetsFill: true, | |
supportsGradient: true | |
}, | |
BIT_ERASER: {}, | |
BIT_SELECT: { | |
supportsGradient: true | |
} | |
}); | |
const getToolInfo = () => TOOL_INFO[addon.tab.redux.state.scratchPaint.mode]; | |
class ColorStyleReducerWrapper { | |
constructor(reduxPropertyName, primaryAction, secondaryAction, gradientTypeAction) { | |
this.reduxPropertyName = reduxPropertyName; | |
this.primaryAction = primaryAction; | |
this.secondaryAction = secondaryAction; | |
this.gradientTypeAction = gradientTypeAction; | |
} | |
get() { | |
let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : addon.tab.redux.state; | |
return state.scratchPaint.color[this.reduxPropertyName]; | |
} | |
set(newColor) { | |
const state = this.get(); | |
const newPrimary = parseColorStyleColor(newColor.primary); | |
if (state.primary !== newPrimary) { | |
addon.tab.redux.dispatch({ | |
type: this.primaryAction, | |
color: newPrimary | |
}); | |
} | |
const toolInfo = getToolInfo(); | |
const toolSupportsGradient = toolInfo && toolInfo.supportsGradient; | |
if (toolSupportsGradient) { | |
const newSecondary = parseColorStyleColor(newColor.secondary); | |
if (state.secondary !== newSecondary) { | |
addon.tab.redux.dispatch({ | |
type: this.secondaryAction, | |
color: newSecondary | |
}); | |
} | |
if (state.gradientType !== newColor.gradientType) { | |
addon.tab.redux.dispatch({ | |
type: this.gradientTypeAction, | |
gradientType: newColor.gradientType | |
}); | |
} | |
} | |
} | |
} | |
const fillStyle = new ColorStyleReducerWrapper("fillColor", "scratch-paint/fill-style/CHANGE_FILL_COLOR", "scratch-paint/fill-style/CHANGE_FILL_COLOR_2", "scratch-paint/fill-style/CHANGE_FILL_GRADIENT_TYPE"); | |
const strokeStyle = new ColorStyleReducerWrapper("strokeColor", "scratch-paint/stroke-style/CHANGE_STROKE_COLOR", "scratch-paint/stroke-style/CHANGE_STROKE_COLOR_2", "scratch-paint/stroke-style/CHANGE_STROKE_GRADIENT_TYPE"); | |
const simpleHexColor = hex => ({ | |
primary: hex, | |
secondary: null, | |
gradientType: "SOLID" | |
}); | |
let defaultFillColor; | |
let defaultStrokeColor; | |
let defaultStrokeWidth; | |
const setDefaultColorsToSettings = () => { | |
defaultFillColor = simpleHexColor(parseColor(addon.settings.get("fill"))); | |
defaultStrokeColor = simpleHexColor(parseColor(addon.settings.get("stroke"))); | |
defaultStrokeWidth = addon.settings.get("strokeSize"); | |
}; | |
setDefaultColorsToSettings(); | |
const applyFillColor = () => { | |
fillStyle.set(defaultFillColor); | |
}; | |
const applyStrokeColor = () => { | |
strokeStyle.set(defaultStrokeColor); | |
}; | |
const applyStrokeWidth = mustBeNonZero => { | |
let width = defaultStrokeWidth; | |
if (width === 0 && mustBeNonZero) { | |
width = 1; | |
} | |
if (addon.tab.redux.state.scratchPaint.color.strokeWidth !== width) { | |
addon.tab.redux.dispatch({ | |
type: "scratch-paint/stroke-width/CHANGE_STROKE_WIDTH", | |
strokeWidth: width | |
}); | |
} | |
}; | |
if (!addon.self.disabled) { | |
applyFillColor(); | |
applyStrokeColor(); | |
applyStrokeWidth(false); | |
} | |
addon.settings.addEventListener("change", () => { | |
if (!addon.settings.get("persistence")) { | |
setDefaultColorsToSettings(); | |
} | |
}); | |
const isValidColorToPersist = color => color.primary !== null && color.primary !== MIXED; | |
let activatingTool = false; | |
addon.tab.redux.initialize(); | |
addon.tab.redux.addEventListener("statechanged", _ref2 => { | |
let { | |
detail | |
} = _ref2; | |
if (addon.self.disabled) { | |
return; | |
} | |
const action = detail.action; | |
if (!activatingTool && addon.settings.get("persistence")) { | |
// We always want to check for changes instead of filtering to just certain actions because quite a few | |
// actions can change these. | |
const newFill = fillStyle.get(); | |
if (fillStyle.get(detail.prev) !== newFill && isValidColorToPersist(newFill)) { | |
defaultFillColor = newFill; | |
} | |
const newStroke = strokeStyle.get(); | |
if (strokeStyle.get(detail.prev) !== newStroke && isValidColorToPersist(newStroke)) { | |
defaultStrokeColor = newStroke; | |
} | |
const newStrokeWidth = detail.next.scratchPaint.color.strokeWidth; | |
if (typeof newStrokeWidth === "number") { | |
defaultStrokeWidth = newStrokeWidth; | |
} | |
} | |
if (action.type === "scratch-paint/modes/CHANGE_MODE") { | |
activatingTool = true; | |
queueMicrotask(() => { | |
activatingTool = false; | |
if (addon.settings.get("persistence")) { | |
// In persistence, we always want to re-apply the previous stroke and fill. | |
const toolInfo = getToolInfo(); | |
if (!toolInfo) { | |
console.warn("unknown tool", addon.tab.redux.state.scratchPaint.mode); | |
return; | |
} | |
if (toolInfo.resetsFill) { | |
applyFillColor(); | |
} | |
if (toolInfo.resetsStroke) { | |
applyStrokeWidth(!!toolInfo.requiresNonZeroStrokeWidth); | |
applyStrokeColor(); | |
} | |
} else { | |
// In non-persistence, we'll only apply the default colors when Scratch resets them to maintain the same behavior. | |
// We have to do this weird redux trick because we can't modify these constants: | |
// https://github.com/LLK/scratch-paint/blob/6733e20b56f52d139f9885952a57c7da012a542f/src/reducers/fill-style.js#L7 | |
// https://github.com/LLK/scratch-paint/blob/6733e20b56f52d139f9885952a57c7da012a542f/src/reducers/stroke-style.js#L7 | |
const oldFillColor = fillStyle.get(detail.prev); | |
if (oldFillColor.primary === null || oldFillColor.primary === MIXED) { | |
const newFillColor = fillStyle.get(); | |
if (newFillColor.primary === SCRATCH_DEFAULT_FILL) { | |
applyFillColor(); | |
} | |
} | |
const oldStrokeColor = strokeStyle.get(detail.prev); | |
if (oldStrokeColor.primary === null || oldStrokeColor.primary === MIXED) { | |
const newStrokeColor = strokeStyle.get(); | |
if (newStrokeColor.primary === SCRATCH_DEFAULT_STROKE) { | |
applyStrokeWidth(true); | |
applyStrokeColor(); | |
} | |
} | |
} | |
}); | |
} | |
}); | |
}); | |
/***/ }) | |
}]); | |
//# sourceMappingURL=addon-entry-default-costume-editor-color.js.map |