Merge pull request #482 from juliandescottes/feature-tiled-drawing

Feature tiled drawing
This commit is contained in:
Julian Descottes 2016-06-04 17:07:28 +02:00
commit 014a1d418f
9 changed files with 82 additions and 66 deletions

View File

@ -3,42 +3,37 @@
/*******************************/
.background-picker-wrapper {
display: inline-block;
width: 130px;
overflow: hidden;
padding: 5px 5px 2px 5px;
vertical-align: middle;
margin-left: 5px;
}
.background-picker {
cursor: pointer;
float: left;
height: 35px;
width: 35px;
height: 14px;
width: 14px;
background-color: transparent;
margin-right: 15px;
margin-right: 5px;
padding: 1px;
position: relative;
border: #888 2px solid;
}
.background-picker:after {
content: " ";
position: absolute;
top: -2px;
right: -2px;
bottom: -2px;
left: -2px;
.background-picker:hover {
border-color: #eee;
}
.background-picker:hover:after {
border: #eee 1px solid;
}
.background-picker.selected:after {
border: gold 1px solid;
.background-picker.selected {
border-color: gold;
}
.layer-opacity-input {
margin: 5px;
vertical-align: middle;
width: 145px;
width: 100px;
}
.layer-opacity-text {
@ -53,9 +48,10 @@
}
.grid-width-select {
margin: 5px;
margin: 5px 5px 0 5px;
}
.settings-section-application > .settings-item > label {
display: block;
}
.settings-section-application > .settings-title {
/* Override the default 10px margin bottom for this panel */
margin-bottom: 15px;
}

View File

@ -21,6 +21,7 @@ var Constants = {
DEFAULT_PEN_COLOR : '#000000',
TRANSPARENT_COLOR : 'rgba(0, 0, 0, 0)',
SEAMLESS_MODE_OVERLAY_COLOR : 'rgba(255, 255, 255, 0.5)',
CURRENT_COLORS_PALETTE_ID : '__current-colors',

View File

@ -116,8 +116,8 @@
ns.PreviewController.prototype.updateZoom_ = function () {
var originalSizeEnabled = pskl.UserSettings.get(pskl.UserSettings.ORIGINAL_SIZE_PREVIEW);
var tiledPreviewEnabled = pskl.UserSettings.get(pskl.UserSettings.TILED_PREVIEW);
var useOriginalSize = originalSizeEnabled || tiledPreviewEnabled;
var seamlessModeEnabled = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_MODE);
var useOriginalSize = originalSizeEnabled || seamlessModeEnabled;
var zoom = useOriginalSize ? 1 : this.calculateZoom_();
this.renderer.setZoom(zoom);
@ -208,12 +208,12 @@
};
ns.PreviewController.prototype.updateContainerDimensions_ = function () {
var isTiled = pskl.UserSettings.get(pskl.UserSettings.TILED_PREVIEW);
this.renderer.setRepeated(isTiled);
var isSeamless = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_MODE);
this.renderer.setRepeated(isSeamless);
var height, width;
if (isTiled) {
if (isSeamless) {
height = PREVIEW_SIZE;
width = PREVIEW_SIZE;
} else {

View File

@ -26,13 +26,13 @@
this.addEventListener(gridSelect, 'change', this.onGridWidthChange_);
// Tiled preview
var tiledPreview = pskl.UserSettings.get(pskl.UserSettings.TILED_PREVIEW);
var tiledPreviewCheckbox = document.querySelector('.tiled-preview-checkbox');
if (tiledPreview) {
tiledPreviewCheckbox.setAttribute('checked', tiledPreview);
// Seamless mode
var seamlessMode = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_MODE);
var seamlessModeCheckbox = document.querySelector('.seamless-mode-checkbox');
if (seamlessMode) {
seamlessModeCheckbox.setAttribute('checked', seamlessMode);
}
this.addEventListener(tiledPreviewCheckbox, 'change', this.onTiledPreviewChange_);
this.addEventListener(seamlessModeCheckbox, 'change', this.onSeamlessModeChange_);
// Max FPS
var maxFpsInput = document.querySelector('.max-fps-input');
@ -55,8 +55,8 @@
pskl.UserSettings.set(pskl.UserSettings.GRID_WIDTH, width);
};
ns.ApplicationSettingsController.prototype.onTiledPreviewChange_ = function (evt) {
pskl.UserSettings.set(pskl.UserSettings.TILED_PREVIEW, evt.currentTarget.checked);
ns.ApplicationSettingsController.prototype.onSeamlessModeChange_ = function (evt) {
pskl.UserSettings.set(pskl.UserSettings.SEAMLESS_MODE, evt.currentTarget.checked);
};
ns.ApplicationSettingsController.prototype.onBackgroundClick_ = function (evt) {

View File

@ -34,6 +34,7 @@
var serializedFrame = [
this.getZoom(),
this.getGridWidth(),
pskl.UserSettings.get('SEAMLESS_MODE'),
offset.x, offset.y,
size.width, size.height,
frame.getHash()

View File

@ -237,6 +237,10 @@
this.canvas = pskl.utils.CanvasUtils.createCanvas(frame.getWidth(), frame.getHeight());
}
var w = this.canvas.width;
var h = this.canvas.height;
var z = this.zoom;
// Draw in canvas
pskl.utils.FrameUtils.drawToCanvas(frame, this.canvas);
@ -245,31 +249,51 @@
var displayContext = this.displayCanvas.getContext('2d');
displayContext.save();
var smallerHeight = this.canvas.height * this.zoom < this.displayCanvas.height;
var smallerWidth = this.canvas.width * this.zoom < this.displayCanvas.width;
if (smallerHeight || smallerWidth) {
displayContext.fillStyle = Constants.ZOOMED_OUT_BACKGROUND_COLOR;
displayContext.fillRect(0, 0, this.displayCanvas.width - 1, this.displayCanvas.height - 1);
}
// Draw background
displayContext.fillStyle = Constants.ZOOMED_OUT_BACKGROUND_COLOR;
displayContext.fillRect(0, 0, this.displayCanvas.width - 1, this.displayCanvas.height - 1);
displayContext.translate(
this.margin.x - this.offset.x * this.zoom,
this.margin.y - this.offset.y * this.zoom
this.margin.x - this.offset.x * z,
this.margin.y - this.offset.y * z
);
displayContext.clearRect(0, 0, this.canvas.width * this.zoom, this.canvas.height * this.zoom);
var isIE10 = pskl.utils.UserAgent.isIE && pskl.utils.UserAgent.version === 10;
if (pskl.UserSettings.get('SEAMLESS_MODE')) {
displayContext.clearRect(-1 * w * z, -1 * h * z, 3 * w * z, 3 * h * z);
} else {
displayContext.clearRect(0, 0, w * z, h * z);
}
var gridWidth = this.computeGridWidthForDisplay_();
var isGridEnabled = gridWidth > 0;
if (isGridEnabled || isIE10) {
var scaled = pskl.utils.ImageResizer.resizeNearestNeighbour(this.canvas, this.zoom, gridWidth);
if (gridWidth > 0) {
var scaled = pskl.utils.ImageResizer.resizeNearestNeighbour(this.canvas, z, gridWidth);
if (pskl.UserSettings.get('SEAMLESS_MODE')) {
this.drawTiledFrames_(displayContext, scaled, w, h, z);
}
displayContext.drawImage(scaled, 0, 0);
} else {
displayContext.scale(this.zoom, this.zoom);
displayContext.scale(z, z);
if (pskl.UserSettings.get('SEAMLESS_MODE')) {
this.drawTiledFrames_(displayContext, this.canvas, w, h, 1);
}
displayContext.drawImage(this.canvas, 0, 0);
}
displayContext.restore();
};
/**
* Draw repeatedly the provided image around the main drawing area. Used for seamless
* drawing mode, to easily create seamless textures. A colored overlay is applied to
* differentiate those additional frames from the main frame.
*/
ns.FrameRenderer.prototype.drawTiledFrames_ = function (context, image, w, h, z) {
context.fillStyle = Constants.SEAMLESS_MODE_OVERLAY_COLOR;
[[0, -1], [0, 1], [-1, -1], [-1, 0], [-1, 1], [1, -1], [1, 0], [1, 1]].forEach(function (d) {
context.drawImage(image, d[0] * w * z, d[1] * h * z);
context.fillRect(d[0] * w * z, d[1] * h * z, w * z, h * z);
});
};
})();

View File

@ -7,7 +7,7 @@
DEFAULT_SIZE : 'DEFAULT_SIZE',
CANVAS_BACKGROUND : 'CANVAS_BACKGROUND',
SELECTED_PALETTE : 'SELECTED_PALETTE',
TILED_PREVIEW : 'TILED_PREVIEW',
SEAMLESS_MODE : 'SEAMLESS_MODE',
ORIGINAL_SIZE_PREVIEW : 'ORIGINAL_SIZE_PREVIEW',
ONION_SKIN : 'ONION_SKIN',
LAYER_PREVIEW : 'LAYER_PREVIEW',
@ -26,7 +26,7 @@
},
'CANVAS_BACKGROUND' : 'lowcont-dark-canvas-background',
'SELECTED_PALETTE' : Constants.CURRENT_COLORS_PALETTE_ID,
'TILED_PREVIEW' : false,
'SEAMLESS_MODE' : false,
'ORIGINAL_SIZE_PREVIEW' : false,
'ONION_SKIN' : false,
'LAYER_OPACITY' : 0.2,

View File

@ -4,6 +4,7 @@
<div class="settings-title">
General
</div>
<div class="settings-item">
<label>Background</label>
<div class="background-picker-wrapper">
@ -23,7 +24,7 @@
</div>
<div class="settings-item">
<label for="grid-width">Grid</label>
<label for="grid-width">Pixel Grid</label>
<select id="grid-width" class="grid-width-select">
<option value="0">Disabled</option>
<option value="1">1px</option>
@ -34,31 +35,24 @@
</div>
<div class="settings-item">
<label for="tiled-preview">Layer Preview Opacity</label>
<label>Layer Opacity</label>
<input type="range" class="layer-opacity-input" name="layer-opacity" min="0" max="1" step="0.05"/>
<span class="layer-opacity-text"></span>
</div>
</div>
<div class="settings-section">
<div class="settings-title">
Preview
</div>
<div class="settings-item">
<label>
<input type="checkbox" value="1" class="tiled-preview-checkbox checkbox-fix" name="tiled-preview-checkbox"/>
Repeated preview
Seamless drawing mode
<input type="checkbox" value="1" class="seamless-mode-checkbox" name="seamless-mode-checkbox"/>
</label>
</div>
<div class="settings-item">
<label for="tiled-preview">Maximum FPS </label>
<label>Maximum FPS</label>
<input type="text" class="textfield textfield-small max-fps-input" autocomplete="off" name="max-fps"/>
</div>
<input type="submit" class="button button-primary" value="Save" />
<input type="submit" class="button button-primary" value="Apply settings" />
</div>
</form>
</script>

View File

@ -1,7 +1,7 @@
<script type="text/html" id="templates/settings/export.html">
<div class="settings-section settings-section-export">
<div class="settings-title">Export</div>
<div class="settings-item export-scale" title="Scale the exported PNG spritesheet"
<div class="settings-item export-scale" title="Scale the animation for export"
rel="tooltip"
data-placement="top">
<label for="scale-input">Scale</label>