mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-24 22:26:10 +03:00
cleaning up changes
This commit is contained in:
parent
a578b97d96
commit
c86158f0ca
@ -237,6 +237,7 @@ $.DrawerBase = class DrawerBase{
|
||||
*
|
||||
* NOTE: This event is only fired in certain drawing contexts: either the 'canvas' drawer is
|
||||
* being used, or the 'webgl' drawer with 'drawerOptions.webgl.continuousTileRefresh'.
|
||||
* TODO: if we get rid of this in the webgl drawer, this can be moved to canvas drawer and the comment about continuousTileRefresh can be removed
|
||||
*
|
||||
* @event tile-drawing
|
||||
* @memberof OpenSeadragon.Viewer
|
||||
|
@ -1346,22 +1346,20 @@ function OpenSeadragon( options ){
|
||||
compositeOperation: null, // to be passed into each TiledImage
|
||||
|
||||
// DRAWER SETTINGS
|
||||
drawer: ['webgl', 'canvas', 'html'], // prefer using webgl, context2d, fallback to html
|
||||
drawer: ['webgl', 'canvas', 'html'], // prefer using webgl, then canvas (i.e. context2d), then fallback to html
|
||||
/**
|
||||
* drawerOptions dictionary.
|
||||
* @type {Object} drawerOptions
|
||||
* @property {Object} webgl - options if the WebGLDrawer is used.
|
||||
* Set 'continuousTileFresh: true' if tile data is modified programmatically
|
||||
* by filtering plugins or similar.
|
||||
* @property {Object} context2d - options if the CanvasDrawer is used
|
||||
* @property {Object} html - options if the HTMLDrawer is used
|
||||
* @property {Object} custom - options if a custom drawer is used
|
||||
* @property {Object} webgl - options if the WebGLDrawer is used. No options are currently supported.
|
||||
* @property {Object} canvas - options if the CanvasDrawer is used. No options are currently supported.
|
||||
* @property {Object} html - options if the HTMLDrawer is used. No options are currently supported.
|
||||
* @property {Object} custom - options if a custom drawer is used. No options are currently supported.
|
||||
*/
|
||||
drawerOptions: {
|
||||
webgl: {
|
||||
continuousTileRefresh: false,
|
||||
|
||||
},
|
||||
context2d: {
|
||||
canvas: {
|
||||
|
||||
},
|
||||
html: {
|
||||
|
@ -236,6 +236,13 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
||||
return this._needsDraw;
|
||||
},
|
||||
|
||||
/**
|
||||
* Mark the tiled image as needing to be (re)drawn
|
||||
*/
|
||||
redraw: function() {
|
||||
this._needsDraw = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Boolean} Whether all tiles necessary for this TiledImage to draw at the current view have been loaded.
|
||||
*/
|
||||
|
@ -438,7 +438,7 @@ $.Viewer = function( options ) {
|
||||
if (Object.prototype.hasOwnProperty.call(this.drawerOptions, 'useCanvas') ){
|
||||
$.console.error('useCanvas is deprecated, use the "drawer" option to indicate preferred drawer(s)');
|
||||
|
||||
// for backwards compatibility, use HTMLDrawer if useCanvas is defined an is falsey
|
||||
// for backwards compatibility, use HTMLDrawer if useCanvas is defined and is falsey
|
||||
if (!this.drawerOptions.useCanvas){
|
||||
this.drawer = $.HTMLDrawer;
|
||||
}
|
||||
@ -450,8 +450,8 @@ $.Viewer = function( options ) {
|
||||
drawerCandidates = [$.DEFAULT_SETTINGS.drawer].flat(); // ensure it is a list
|
||||
$.console.warn('No valid drawers were selected. Using the default value.');
|
||||
}
|
||||
// extend the drawerOptions object with additional properties to pass to the Drawer implementation
|
||||
// TODO: how to deal with the possibility that none of the requested drawers are supported?
|
||||
|
||||
|
||||
this.drawer = null;
|
||||
for (let i = 0; i < drawerCandidates.length; i++) {
|
||||
|
||||
@ -532,6 +532,7 @@ $.Viewer = function( options ) {
|
||||
displayRegionColor: this.navigatorDisplayRegionColor,
|
||||
crossOriginPolicy: this.crossOriginPolicy,
|
||||
animationTime: this.animationTime,
|
||||
drawer: this.drawer.getType(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -112,9 +112,6 @@
|
||||
// Delete all our created resources
|
||||
gl.deleteBuffer(this._secondPass.bufferOutputPosition);
|
||||
gl.deleteFramebuffer(this._glFrameBuffer);
|
||||
// TODO: if/when render buffers or frame buffers are used, release them:
|
||||
// gl.deleteRenderbuffer(someRenderbuffer);
|
||||
// gl.deleteFramebuffer(someFramebuffer);
|
||||
|
||||
// make canvases 1 x 1 px and delete references
|
||||
this._renderingCanvas.width = this._renderingCanvas.height = 1;
|
||||
@ -208,20 +205,21 @@
|
||||
//iterate over tiled images and draw each one using a two-pass rendering pipeline if needed
|
||||
tiledImages.forEach( (tiledImage, tiledImageIndex) => {
|
||||
|
||||
let useContext2dPipeline = ( tiledImage.compositeOperation ||
|
||||
this.viewer.compositeOperation ||
|
||||
tiledImage._clip ||
|
||||
tiledImage._croppingPolygons ||
|
||||
tiledImage.debugMode
|
||||
);
|
||||
|
||||
let useTwoPassRendering = useContext2dPipeline || (tiledImage.opacity < 1); // TODO: check hasTransparency in addition to opacity
|
||||
|
||||
let tilesToDraw = tiledImage.getTilesToDraw();
|
||||
|
||||
if(tilesToDraw.length === 0){
|
||||
return;
|
||||
}
|
||||
let firstTile = tilesToDraw[0];
|
||||
|
||||
let useContext2dPipeline = ( tiledImage.compositeOperation ||
|
||||
this.viewer.compositeOperation ||
|
||||
tiledImage._clip ||
|
||||
tiledImage._croppingPolygons ||
|
||||
tiledImage.debugMode
|
||||
);
|
||||
|
||||
let useTwoPassRendering = useContext2dPipeline || (tiledImage.opacity < 1) || firstTile.hasTransparency;
|
||||
|
||||
// using the context2d pipeline requires a clean rendering (back) buffer to start
|
||||
if(useContext2dPipeline){
|
||||
@ -321,8 +319,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// gl.flush(); // is this necessary?
|
||||
|
||||
if(useTwoPassRendering){
|
||||
// Second rendering pass: Render the tiled image from the framebuffer into the back buffer
|
||||
gl.useProgram(this._secondPass.shaderProgram);
|
||||
@ -346,21 +342,19 @@
|
||||
// Draw the quad (two triangles)
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
|
||||
// TODO: is this the mechanism we want to use here?
|
||||
// TODO: Can we get rid of this entirely in this version of the webgl drawer?
|
||||
// iterate over any filters - filters can use this._renderToTexture to get rendered data if desired
|
||||
let filters = this.filters || [];
|
||||
for(let fi = 0; fi < filters.length; fi++){
|
||||
let filter = this.filters[fi];
|
||||
if(filter.apply){
|
||||
filter.apply(gl); // filter.apply should write data on top of the backbuffer (bound above)
|
||||
}
|
||||
}
|
||||
// let filters = this.filters || [];
|
||||
// for(let fi = 0; fi < filters.length; fi++){
|
||||
// let filter = this.filters[fi];
|
||||
// if(filter.apply){
|
||||
// filter.apply(gl); // filter.apply should write data on top of the backbuffer (bound above)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
renderingBufferHasImageData = true;
|
||||
|
||||
// gl.flush(); //make sure drawing to the output buffer of the rendering canvas is complete. Is this necessary?
|
||||
|
||||
if(useContext2dPipeline){
|
||||
// draw from the rendering canvas onto the output canvas, clipping/cropping if needed.
|
||||
this._applyContext2dPipeline(tiledImage, tilesToDraw, tiledImageIndex);
|
||||
@ -371,7 +365,7 @@
|
||||
}
|
||||
|
||||
// Fire tiled-image-drawn event.
|
||||
// TODO: the image data may not be on the output canvas yet!!
|
||||
// TODO: do we need to ensure the image has been drawn to the output canvas already? is it possible the image data may not be on the output canvas?
|
||||
if( this.viewer ){
|
||||
/**
|
||||
* Raised when a tiled image is drawn to the canvas. Only valid
|
||||
@ -505,17 +499,18 @@
|
||||
|
||||
let overallMatrix = viewMatrix.multiply(matrix);
|
||||
|
||||
opacityArray[index] = tile.opacity;// * tiledImage.opacity;
|
||||
opacityArray[index] = tile.opacity;
|
||||
textureDataArray[index] = texture;
|
||||
matrixArray[index] = overallMatrix.values;
|
||||
|
||||
if(this.continuousTileRefresh){
|
||||
// Upload the image into the texture
|
||||
// TODO: test if this works appropriately
|
||||
let tileContext = tile.getCanvasContext();
|
||||
this._raiseTileDrawingEvent(tiledImage, this._outputContext, tile, tileContext);
|
||||
this._uploadImageData(tileContext, tile, tiledImage);
|
||||
}
|
||||
// TODO: can we get rid of this in this version of the webgl drawer?
|
||||
// if(this.continuousTileRefresh){
|
||||
// // Upload the image into the texture
|
||||
// // TODO: test if this works appropriately
|
||||
// let tileContext = tile.getCanvasContext();
|
||||
// this._raiseTileDrawingEvent(tiledImage, this._outputContext, tile, tileContext);
|
||||
// this._uploadImageData(tileContext, tile, tiledImage);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@ -889,8 +884,6 @@
|
||||
this._gl.deleteTexture(textureInfo.texture);
|
||||
}
|
||||
|
||||
// release the position buffer from the GPU
|
||||
// TODO: do this!
|
||||
}
|
||||
// private
|
||||
// necessary for clip testing to pass (test uses spyOnce(drawer._setClip))
|
||||
|
@ -6,7 +6,6 @@
|
||||
<script type="text/javascript" src='../lib/jquery-1.9.1.min.js'></script>
|
||||
<script type="text/javascript" src='../lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js'></script>
|
||||
<link rel="stylesheet" href="../lib/jquery-ui-1.10.2/css/smoothness/jquery-ui-1.10.2.min.css">
|
||||
<script type="text/javascript" src="./webgldemodrawer.js"></script>
|
||||
|
||||
<script type="module" src="./drawercomparison.js"></script>
|
||||
<style type="text/css">
|
||||
|
@ -38,7 +38,8 @@ let viewer1 = window.viewer1 = OpenSeadragon({
|
||||
ajaxWithCredentials: false,
|
||||
// maxImageCacheCount: 30,
|
||||
drawer:drawer1,
|
||||
blendTime:0
|
||||
blendTime:0,
|
||||
showNavigator:true,
|
||||
});
|
||||
|
||||
// viewer2: webgl drawer
|
||||
@ -53,6 +54,7 @@ let viewer2 = window.viewer2 = OpenSeadragon({
|
||||
// maxImageCacheCount: 30,
|
||||
drawer:drawer2,
|
||||
blendTime:0,
|
||||
showNavigator:true,
|
||||
});
|
||||
|
||||
// // viewer3: html drawer, unused
|
||||
@ -232,7 +234,7 @@ $('.image-options select[data-field=wrapping]').append(getWrappingOptions()).on(
|
||||
case "Vertical": tiledImage.wrapHorizontal = false; tiledImage.wrapVertical = true; break;
|
||||
case "Both": tiledImage.wrapHorizontal = tiledImage.wrapVertical = true; break;
|
||||
}
|
||||
tiledImage.viewer.raiseEvent('opacity-change');//trigger a redraw for the webgl renderer. TODO: fix this hack.
|
||||
tiledImage.redraw();//trigger a redraw for the webgl renderer.
|
||||
}
|
||||
tiledImage = $(`#image-picker input.toggle[data-image=${data.image}]`).data('item2');
|
||||
if(tiledImage){
|
||||
@ -242,7 +244,7 @@ $('.image-options select[data-field=wrapping]').append(getWrappingOptions()).on(
|
||||
case "Vertical": tiledImage.wrapHorizontal = false; tiledImage.wrapVertical = true; break;
|
||||
case "Both": tiledImage.wrapHorizontal = tiledImage.wrapVertical = true; break;
|
||||
}
|
||||
tiledImage.viewer.raiseEvent('opacity-change');//trigger a redraw for the webgl renderer. TODO: fix this hack.
|
||||
tiledImage.redraw();//trigger a redraw for the webgl renderer.
|
||||
}
|
||||
}).trigger('change');
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
<link rel="stylesheet" href="../lib/jquery-ui-1.10.2/css/smoothness/jquery-ui-1.10.2.min.css">
|
||||
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/17/Stats.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script> -->
|
||||
|
||||
<script type="text/javascript" src="./webgldemodrawer.js"></script>
|
||||
<script type="module" src="./drawerperformance.js"></script>
|
||||
<style type="text/css">
|
||||
.content{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,105 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WebGL Demo</title>
|
||||
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
||||
<script type="text/javascript" src='../lib/jquery-1.9.1.min.js'></script>
|
||||
<script type="text/javascript" src='../lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js'></script>
|
||||
<link rel="stylesheet" href="../lib/jquery-ui-1.10.2/css/smoothness/jquery-ui-1.10.2.min.css">
|
||||
<script type="text/javascript" src="./webgldemodrawer.js"></script>
|
||||
<script type="module" src="./webglfiltering.js"></script>
|
||||
<style type="text/css">
|
||||
.content{
|
||||
max-width:960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.side-by-side{
|
||||
display:grid;
|
||||
grid-template-columns:50% 50%;
|
||||
gap: 2em;
|
||||
}
|
||||
.viewer-container {
|
||||
/* width: 600px;
|
||||
height: 400px; */
|
||||
aspect-ratio: 4 / 3;
|
||||
border: thin gray solid;
|
||||
position:relative;
|
||||
}
|
||||
.example-code{
|
||||
background-color:tan;
|
||||
border: thin black solid;
|
||||
padding:10px;
|
||||
display:inline-block;
|
||||
width:95%;
|
||||
}
|
||||
.description pre{
|
||||
display:inline-block;
|
||||
background-color:gainsboro;
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.image-options{
|
||||
display: grid;
|
||||
grid-template-columns: 2em 9em 1fr;
|
||||
padding:3px;
|
||||
border: thin gray solid;
|
||||
}
|
||||
.option-grid{
|
||||
display: grid;
|
||||
grid-template-columns: 7em 7em 10em 10em 10em;
|
||||
/* grid-template-columns: repeat(5, auto); */
|
||||
}
|
||||
.image-options input[type=number]{
|
||||
width: 5em;
|
||||
}
|
||||
.image-options select{
|
||||
width: 5em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
|
||||
<h2>WebGLDrawer demonstration</h2>
|
||||
<div class="side-by-side">
|
||||
<div>
|
||||
<div id="webgl" class="viewer-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="image-picker">
|
||||
<h3>Image options (drag and drop to re-order images)</h3>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<h2>Example code</h2>
|
||||
<div>
|
||||
<div>
|
||||
<div class="description">
|
||||
Drawer options are shown below.
|
||||
</div>
|
||||
<pre class="example-code">
|
||||
let viewer = OpenSeadragon({
|
||||
...
|
||||
drawer: 'webgl',
|
||||
drawerOptions: {
|
||||
webgl: {
|
||||
programs: [],
|
||||
}
|
||||
}
|
||||
...
|
||||
});
|
||||
</pre>
|
||||
</div>
|
||||
<div id="htmldrawer" class="viewer-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,298 +0,0 @@
|
||||
const sources = {
|
||||
"rainbow":"../data/testpattern.dzi",
|
||||
"leaves":"../data/iiif_2_0_sizes/info.json",
|
||||
"bblue":{
|
||||
type:'image',
|
||||
url: "../data/BBlue.png",
|
||||
},
|
||||
"duomo":"https://openseadragon.github.io/example-images/duomo/duomo.dzi",
|
||||
}
|
||||
const labels = {
|
||||
rainbow: 'Rainbow Grid',
|
||||
leaves: 'Leaves',
|
||||
bblue: 'Blue B',
|
||||
duomo: 'Duomo',
|
||||
}
|
||||
|
||||
// viewer1: context2d drawer
|
||||
let viewer1 = window.viewer1 = OpenSeadragon({
|
||||
id: "webgl",
|
||||
prefixUrl: "../../build/openseadragon/images/",
|
||||
minZoomImageRatio:0.01,
|
||||
maxZoomPixelRatio:100,
|
||||
smoothTileEdgesMinZoom:1.1,
|
||||
crossOriginPolicy: 'Anonymous',
|
||||
ajaxWithCredentials: false,
|
||||
// maxImageCacheCount: 30,
|
||||
drawer:OpenSeadragon.WebGL2Drawer,
|
||||
blendTime:0,
|
||||
drawerOptions:{
|
||||
webgl:{
|
||||
programs:[makeRedFilter()],
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setupImageControls();
|
||||
|
||||
|
||||
|
||||
class ColorChanelFilter {
|
||||
constructor() {
|
||||
this.red = 1;
|
||||
this.blue = 1;
|
||||
this.green = 1;
|
||||
|
||||
this.program = null;
|
||||
}
|
||||
createProgram(gl){
|
||||
this.program = OpenSeadragon.WebGLDrawer.initShaderProgram(gl, this.getVertexShaderCode(), this.getFragmentShaderCode());
|
||||
}
|
||||
apply(gl, tiledImageTexture, tiledImage){
|
||||
|
||||
}
|
||||
getVertexShaderCode(){
|
||||
return `
|
||||
attribute vec2 a_output_position;
|
||||
attribute vec2 a_texture_position;
|
||||
|
||||
uniform mat3 u_matrix;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(u_matrix * vec3(a_output_position, 1), 1);
|
||||
|
||||
v_texCoord = a_texture_position;
|
||||
}
|
||||
`;
|
||||
}
|
||||
getFragmentShaderCode(){
|
||||
return `
|
||||
precision mediump float;
|
||||
|
||||
// our texture
|
||||
uniform sampler2D u_image;
|
||||
|
||||
// the texCoords passed in from the vertex shader.
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
// the opacity multiplier for the image
|
||||
uniform vec3 color_multiplier;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(u_image, v_texCoord);
|
||||
gl_FragColor *= vec4(color_multiplier, 1);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function setupImageControls(){
|
||||
|
||||
$('#image-picker').sortable({
|
||||
update: function(event, ui){
|
||||
let thisItem = ui.item.find('.toggle').data('item1');
|
||||
let items = $('#image-picker input.toggle:checked').toArray().map(item=>$(item).data('item1'));
|
||||
let newIndex = items.indexOf(thisItem);
|
||||
if(thisItem){
|
||||
viewer1.world.setItemIndex(thisItem, newIndex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(sources).forEach((key, index)=>{
|
||||
let element = makeImagePickerElement(key, labels[key])
|
||||
$('#image-picker').append(element);
|
||||
if(index === 0){
|
||||
element.find('.toggle').prop('checked',true);
|
||||
}
|
||||
})
|
||||
|
||||
$('#image-picker input.toggle').on('change',function(){
|
||||
let data = $(this).data();
|
||||
if(this.checked){
|
||||
addTileSource(viewer1, data.image, this);
|
||||
} else {
|
||||
if(data.item1){
|
||||
viewer1.world.removeItem(data.item1);
|
||||
$(this).data({item1: null});
|
||||
}
|
||||
}
|
||||
}).trigger('change');
|
||||
|
||||
$('#image-picker input:not(.toggle)').on('change',function(){
|
||||
let data = $(this).data();
|
||||
let value = $(this).val();
|
||||
let tiledImage1 = $(`#image-picker input.toggle[data-image=${data.image}]`).data('item1');
|
||||
updateTiledImage(tiledImage1, data, value, this);
|
||||
});
|
||||
|
||||
function updateTiledImage(tiledImage, data, value, item){
|
||||
if(tiledImage){
|
||||
//item = tiledImage
|
||||
let field = data.field;
|
||||
if(field == 'x'){
|
||||
let bounds = tiledImage.getBoundsNoRotate();
|
||||
let position = new OpenSeadragon.Point(Number(value), bounds.y);
|
||||
tiledImage.setPosition(position);
|
||||
} else if ( field == 'y'){
|
||||
let bounds = tiledImage.getBoundsNoRotate();
|
||||
let position = new OpenSeadragon.Point(bounds.x, Number(value));
|
||||
tiledImage.setPosition(position);
|
||||
} else if (field == 'width'){
|
||||
tiledImage.setWidth(Number(value));
|
||||
} else if (field == 'degrees'){
|
||||
tiledImage.setRotation(Number(value));
|
||||
} else if (field == 'opacity'){
|
||||
tiledImage.setOpacity(Number(value));
|
||||
} else if (field == 'flipped'){
|
||||
tiledImage.setFlip($(item).prop('checked'));
|
||||
} else if (field == 'cropped'){
|
||||
if( $(item).prop('checked') ){
|
||||
let croppingPolygons = [ [{x:200, y:200}, {x:800, y:200}, {x:500, y:800}] ];
|
||||
tiledImage.setCroppingPolygons(croppingPolygons);
|
||||
} else {
|
||||
tiledImage.resetCroppingPolygons();
|
||||
}
|
||||
} else if (field == 'clipped'){
|
||||
if( $(item).prop('checked') ){
|
||||
let clipRect = new OpenSeadragon.Rect(2000, 0, 3000, 4000);
|
||||
tiledImage.setClip(clipRect);
|
||||
} else {
|
||||
tiledImage.setClip(null);
|
||||
}
|
||||
}
|
||||
else if (field == 'debug'){
|
||||
if( $(item).prop('checked') ){
|
||||
tiledImage.debugMode = true;
|
||||
} else {
|
||||
tiledImage.debugMode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('.image-options select[data-field=composite]').append(getCompositeOperationOptions()).on('change',function(){
|
||||
let data = $(this).data();
|
||||
let tiledImage1 = $(`#image-picker input.toggle[data-image=${data.image}]`).data('item1');
|
||||
if(tiledImage1){
|
||||
tiledImage1.setCompositeOperation(this.value == 'null' ? null : this.value);
|
||||
}
|
||||
let tiledImage2 = $(`#image-picker input.toggle[data-image=${data.image}]`).data('item2');
|
||||
if(tiledImage2){
|
||||
tiledImage2.setCompositeOperation(this.value == 'null' ? null : this.value);
|
||||
}
|
||||
}).trigger('change');
|
||||
|
||||
$('.image-options select[data-field=wrapping]').append(getWrappingOptions()).on('change',function(){
|
||||
let data = $(this).data();
|
||||
let tiledImage = $(`#image-picker input.toggle[data-image=${data.image}]`).data('item1');
|
||||
if(tiledImage){
|
||||
switch(this.value){
|
||||
case "None": tiledImage.wrapHorizontal = tiledImage.wrapVertical = false; break;
|
||||
case "Horizontal": tiledImage.wrapHorizontal = true; tiledImage.wrapVertical = false; break;
|
||||
case "Vertical": tiledImage.wrapHorizontal = false; tiledImage.wrapVertical = true; break;
|
||||
case "Both": tiledImage.wrapHorizontal = tiledImage.wrapVertical = true; break;
|
||||
}
|
||||
tiledImage.viewer.raiseEvent('opacity-change');//trigger a redraw for the webgl renderer. TODO: fix this hack.
|
||||
}
|
||||
tiledImage = $(`#image-picker input.toggle[data-image=${data.image}]`).data('item2');
|
||||
if(tiledImage){
|
||||
switch(this.value){
|
||||
case "None": tiledImage.wrapHorizontal = tiledImage.wrapVertical = false; break;
|
||||
case "Horizontal": tiledImage.wrapHorizontal = true; tiledImage.wrapVertical = false; break;
|
||||
case "Vertical": tiledImage.wrapHorizontal = false; tiledImage.wrapVertical = true; break;
|
||||
case "Both": tiledImage.wrapHorizontal = tiledImage.wrapVertical = true; break;
|
||||
}
|
||||
tiledImage.viewer.raiseEvent('opacity-change');//trigger a redraw for the webgl renderer. TODO: fix this hack.
|
||||
}
|
||||
}).trigger('change');
|
||||
|
||||
function getWrappingOptions(){
|
||||
let opts = ['None', 'Horizontal', 'Vertical', 'Both'];
|
||||
let elements = opts.map((opt, i)=>{
|
||||
let el = $('<option>',{value:opt}).text(opt);
|
||||
if(i===0){
|
||||
el.attr('selected',true);
|
||||
}
|
||||
return el[0];
|
||||
// $('.image-options select').append(el);
|
||||
});
|
||||
return $(elements);
|
||||
}
|
||||
function getCompositeOperationOptions(){
|
||||
let opts = [null,'source-over','source-in','source-out','source-atop',
|
||||
'destination-over','destination-in','destination-out','destination-atop',
|
||||
'lighten','darken','copy','xor','multiply','screen','overlay','color-dodge',
|
||||
'color-burn','hard-light','soft-light','difference','exclusion',
|
||||
'hue','saturation','color','luminosity'];
|
||||
let elements = opts.map((opt, i)=>{
|
||||
let el = $('<option>',{value:opt}).text(opt);
|
||||
if(i===0){
|
||||
el.attr('selected',true);
|
||||
}
|
||||
return el[0];
|
||||
// $('.image-options select').append(el);
|
||||
});
|
||||
return $(elements);
|
||||
|
||||
}
|
||||
|
||||
function addTileSource(viewer, image, checkbox){
|
||||
let options = $(`#image-picker input[data-image=${image}][type=number]`).toArray().reduce((acc, input)=>{
|
||||
let field = $(input).data('field');
|
||||
if(field){
|
||||
acc[field] = Number(input.value);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
options.flipped = $(`#image-picker input[data-image=${image}][data-type=flipped]`).prop('checked');
|
||||
|
||||
let items = $('#image-picker input.toggle:checked').toArray();
|
||||
let insertionIndex = items.indexOf(checkbox);
|
||||
|
||||
let tileSource = sources[image];
|
||||
if(tileSource){
|
||||
viewer&&viewer.addTiledImage({tileSource: tileSource, ...options, index: insertionIndex});
|
||||
viewer&&viewer.world.addOnceHandler('add-item',function(ev){
|
||||
let item = ev.item;
|
||||
let field = viewer === viewer1 ? 'item1' : 'item2';
|
||||
$(checkbox).data(field,item);
|
||||
item.source.hasTransparency = ()=>true; //simulate image with transparency, to show seams in default renderer
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function makeImagePickerElement(key, label){
|
||||
return $(`<div class="image-options">
|
||||
<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
|
||||
<label><input type="checkbox" data-image="" class="toggle"> __title__</label>
|
||||
<div class="option-grid">
|
||||
<label>X: <input type="number" value="0" data-image="" data-field="x"> </label>
|
||||
<label>Y: <input type="number" value="0" data-image="" data-field="y"> </label>
|
||||
<label>Width: <input type="number" value="1" data-image="" data-field="width" min="0"> </label>
|
||||
<label>Degrees: <input type="number" value="0" data-image="" data-field="degrees"> </label>
|
||||
<label>Opacity: <input type="number" value="1" data-image="" data-field="opacity" min="0" max="1" step="0.2"> </label>
|
||||
<label>Flipped: <input type="checkbox" data-image="" data-field="flipped"></label>
|
||||
<label>Cropped: <input type="checkbox" data-image="" data-field="cropped"></label>
|
||||
<label>Debug: <input type="checkbox" data-image="" data-field="debug"></label>
|
||||
<label>Composite: <select data-image="" data-field="composite"></select></label>
|
||||
<label>Wrapping: <select data-image="" data-field="wrapping"></select></label>
|
||||
</div>
|
||||
|
||||
</div>`.replaceAll('data-image=""', `data-image="${key}"`).replace('__title__', label));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -135,7 +135,7 @@
|
||||
QUnit.test('update', function(assert) {
|
||||
var done = assert.async();
|
||||
var handlerCount = 0;
|
||||
var testTileDrawingEvent = viewer.drawerOptions.type === 'canvas';
|
||||
var testTileDrawingEvent = viewer.drawer.getType() === 'canvas';
|
||||
let expectedHandlers = testTileDrawingEvent ? 4 : 3;
|
||||
|
||||
viewer.addHandler('open', function(event) {
|
||||
|
Loading…
Reference in New Issue
Block a user