--- a/src/iconolab/static/iconolab/css/iconolab.css Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/static/iconolab/css/iconolab.css Wed Jul 13 17:57:35 2016 +0200
@@ -5,4 +5,5 @@
.form-drawing {border-bottom: 1px solid #C3C3C3; }
.form-drawing-wrapper .selected {border: 1px solid orange; color: white; background-color: orange}
-.showPointer {cursor: pointer;}
\ No newline at end of file
+.showPointer {cursor: pointer;}
+.zoomview-wrapper {border: 1px solid red; width: 135px; height: 100px; text-align: center;}
\ No newline at end of file
--- a/src/iconolab/static/iconolab/js/iconolab-bundle/index.html Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/index.html Wed Jul 13 17:57:35 2016 +0200
@@ -5,12 +5,10 @@
<title>iconolab-bundle</title>
</head>
<body>
-
<div id="AppContainer">
<cutout></cutout>
<typeahead></typeahead>
</div>
-
<script src="dist/build.js"></script>
</body>
</html>
--- a/src/iconolab/static/iconolab/js/iconolab-bundle/package.json Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/package.json Wed Jul 13 17:57:35 2016 +0200
@@ -4,7 +4,6 @@
"author": "hbaptiste",
"private": true,
"scripts": {
- "dev": "webpack-dev-server --inline --hot",
"start": "webpack --progress --colors --watch",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
--- a/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/cutout/Cutout.vue Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/cutout/Cutout.vue Wed Jul 13 17:57:35 2016 +0200
@@ -2,14 +2,17 @@
import svgboard from './svgboard'
import Typeahead from '../typeahead/Typeahead.vue'
+ import Zoomview from '../zoomview/Zoomview.vue'
export default {
el: '#drawing-zone',
MODE_RECT: 'RECT',
- MODE_FREE: 'FREE',
+ MODE_FREE: 'FREE',
+ ZOOM_IN: 'in',
+ ZOOM_OUT: 'out',
- components: {typeahead: Typeahead},
+ components: {typeahead: Typeahead, zoomview: Zoomview},
data: {
mode:"",
isRect: true,
@@ -19,6 +22,7 @@
useClipPath: false,
transformMatrix: "",
fragmentPath: "",
+ canZoom: true,
displayMask: false
},
@@ -38,8 +42,71 @@
},
methods: {
+
+ incraseDrawingZoom: function () {
+ this.drawingComponent.increaseZoom();
+ },
-
+ decreaseDrawingZoom: function () {
+ this.drawingComponent.decreaseZoom();
+ },
+
+ resetDrawingZoom: function () {
+ this.drawingComponent.reset();
+ },
+
+ computeZoomedViewBox: function () {
+ var viewBoxArray = [];
+ var zoomSvg = this.$refs.zoomSvg;
+ var shapeBBox = this.drawingComponent.getShapeBBox();
+ var imageWidth = zoomSvg.getAttribute("width");
+ var imageHeight = zoomSvg.getAttribute("height");
+ var xRatio = imageWidth / 100;
+ var yRatio = imageHeight / 100;
+ /* denormalize coordonate, max is imageX * 100x = imageHeigth*/
+ shapeBBox.x = shapeBBox.x * xRatio;
+ shapeBBox.y = shapeBBox.y * yRatio;
+
+ shapeBBox.w = shapeBBox.w * xRatio;
+ shapeBBox.h = shapeBBox.h * yRatio;
+
+ var imgRatio = imageWidth / imageHeight;
+ if (shapeBBox.w > shapeBBox.h) {
+ shapeBBox.y = Math.max(0, shapeBBox.y - (((shapeBBox.w * imgRatio) - shapeBBox.h) / 2));
+ shapeBBox.h = shapeBBox.w * imgRatio;
+ }
+ else {
+ shapeBBox.x = Math.max(0, shapeBBox.x - (((shapeBBox.h / imgRatio) - shapeBBox.w) / 2));
+ shapeBBox.w = shapeBBox.h / imgRatio;
+ console.log(shapeBBox.y);
+ }
+ viewBoxArray = [shapeBBox.x, shapeBBox.y, shapeBBox.w, shapeBBox.h];
+
+ if (!shapeBBox) { return false; }
+
+ /* test compute zoom
+ agrandir de sorte max bbox.h==viewPort.h && bbox.w
+ */
+ //var viewBoxArray = [shapeBBox.x, shapeBBox.y, imageWidth, imageHeight]
+ console.log(viewBoxArray);
+ return viewBoxArray.join(" ");
+ },
+
+ zoom: function (direction) {
+
+ var mainSvgWrapper = this.$refs.smallSvgWrapper;
+ if (this.$options.ZOOM_OUT === direction) {
+ var defaultViewBox = [0, 0, mainSvgWrapper.getAttribute("width"), mainSvgWrapper.getAttribute("height")];
+ mainSvgWrapper.setAttribute("viewBox", defaultViewBox.join(" "));
+ this.canZoom = true;
+ }
+
+ if (this.$options.ZOOM_IN === direction) {
+ mainSvgWrapper.setAttribute("viewBox", this.computeZoomedViewBox());
+ this.canZoom = false;
+ }
+ },
+
setDrawingMode: function (mode, updateComponent) {
if (!this.initialDrawingMode) {
this.initialDrawingMode = mode;//useful for cancel
@@ -61,10 +128,6 @@
}
},
- showEditor: function () {
- this.formView = false;
- },
-
highLightZone: function () {
if (!this.displayMask) {
this.displayMask = true;
@@ -77,14 +140,23 @@
displayEditedPath: function () {
var normalizePath = this.drawingComponent.getPath();
},
+
+ resetZoom: function () {
+ this.zoom(this.$options.ZOOM_OUT);
+ },
+
+ showEditor: function () {
+ this.formView = false;
+ this.resetZoom();
+ /* on edit mode reset*/
+ },
showForm: function () {
this.normalizePath = this.drawingComponent.getPath();
var smallImage = this.$refs.smallImage;
- console.log(this.$refs);
this.formView = true;
- var xRatio = smallImage.width / 100;
- var yRatio = smallImage.height / 100;
+ var xRatio = smallImage.getAttribute("width") / 100;
+ var yRatio = smallImage.getAttribute("height") / 100;
var transformMatrix = [xRatio, 0, 0, yRatio, 0, 0].join(',');
this.transformMatrix ="matrix(" + transformMatrix + ")";
this.fragmentPath = this.normalizePath.split(';')[0];
--- a/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/cutout/shape-resizer.js Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/cutout/shape-resizer.js Wed Jul 13 17:57:35 2016 +0200
@@ -123,7 +123,7 @@
export default {
- apply_resize : function (paper, rect) {
+ enable_resizer : function (paper, rect) {
new ShapeResizer(paper, rect);
}
}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/cutout/snapsvg-zoom.js Wed Jul 13 17:57:35 2016 +0200
@@ -0,0 +1,131 @@
+/* enable zoom */
+import { eventEmitter } from '../utils'
+
+class ZoomHandler {
+
+ constructor (params) {
+ this.zoomFactor = 0.1 || params.zoomFactor;
+ this.paper = params.paper;
+ this.viewport = {width: 529, height: 800};
+ this.scale = 1;
+ this.disableDrag = false;
+ this.paper.attr({"preserveAspectRatio": "xMidYMid meet"});
+ this.currentViewBox = [0, 0, this.viewport.width, this.viewport.height];
+ this.paper.drag(this.onDrag.bind(this), this.onStart.bind(this), this.onStop.bind(this));
+ this.lastPosition = [];
+ }
+
+ zoomIn () {
+ var viewBoxW = this.viewport.width - (this.viewport.width * this.zoomFactor * this.scale);
+ var viewBoxH = this.viewport.height - (this.viewport.height * this.zoomFactor * this.scale);
+ if (!viewBoxW || !viewBoxH) { return false; }
+
+ /* center the viewbox */
+ var topX = (this.viewport.width - viewBoxW) / 2;
+ var topY = (this.viewport.height - viewBoxH) / 2;
+
+ this.currentViewBox[0] = topX;
+ this.currentViewBox[1] = topY;
+
+ this.currentViewBox[2] = viewBoxW;
+ this.currentViewBox[3] = viewBoxH;
+
+ this.updateViewBox();
+ this.scale ++;
+ }
+
+ updateViewBox () {
+ this.paper.attr({"viewBox": this.currentViewBox});
+ eventEmitter.emit("zoomChanged", {
+ "zoomFactor": this.getZoomFactor(),
+ "viewport": this.viewport,
+ "currentViewBox": this.currentViewBox
+ });
+ }
+
+ getZoomFactor () {
+ return {
+ x: this.viewport.width / this.currentViewBox[2],
+ y: this.viewport.height / this.currentViewBox[3]
+ };
+ }
+
+ onStart (x, y, e) {
+
+ this.lastPosition[0] = this.currentViewBox[0];
+ this.lastPosition[1] = this.currentViewBox[1];
+
+ if (e.target.className.baseVal === "drawingHandler") {
+ this.disableDrag = true;
+ }
+ }
+
+ canDrag () {
+ return !this.disableDrag;
+ }
+
+ onStop () {
+ this.disableDrag = false;
+ }
+
+ onDrag (dx, dy, x, y, event) {
+
+ if (!this.canDrag()) { return true; }
+
+ var newX = this.lastPosition[0] - dx;
+ var newY = this.lastPosition[1] - dy;
+
+ /* maxX bound */
+ if (newX + this.currentViewBox[2] >= this.viewport.width) {
+ newX = this.viewport.width - this.currentViewBox[2];
+ }
+
+ /* maxY bound */
+ if (newY + this.currentViewBox[3] >= this.viewport.height) {
+ newY = this.viewport.height - this.currentViewBox[3];
+ }
+
+ if (newX <= 0) { newX = 0; }
+
+ if(newY <= 0) { newY = 0; }
+
+ this.currentViewBox[0] = newX;
+ this.currentViewBox[1] = newY;
+
+ this.updateViewBox();
+ }
+
+ reset () {
+ this.scale = 1;
+ this.currentViewBox = [0, 0, this.viewport.width, this.viewport.height];
+ this.updateViewBox();
+ }
+
+ zoomOut () {
+ if (this.scale === 1) { return false; }
+ var viewBoxW = this.currentViewBox[2] + (this.viewport.width * this.zoomFactor);
+ var viewBoxH = this.currentViewBox[3] + (this.viewport.height * this.zoomFactor);
+ if (viewBoxW > this.viewport.width || viewBoxW > this.viewport.height) {
+ return false;
+ }
+
+ var topX = (this.viewport.width - viewBoxW) / 2;
+ var topY = (this.viewport.height - viewBoxH) / 2;
+
+ this.currentViewBox[0] = topX;
+ this.currentViewBox[1] = topY;
+ this.currentViewBox[2] = viewBoxW;
+ this.currentViewBox[3] = viewBoxH;
+
+ this.scale--;
+ this.updateViewBox();
+
+ }
+}
+
+export default {
+
+ enable_zoom: function (params) {
+ return new ZoomHandler(params);
+ }
+}
\ No newline at end of file
--- a/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/cutout/svgboard.js Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/cutout/svgboard.js Wed Jul 13 17:57:35 2016 +0200
@@ -1,12 +1,13 @@
-var Snap = require('snapsvg');
-//import Snap from 'snapsvg'
+import Snap from 'snapsvg'
import ShapeResizer from './shape-resizer'
import EventEmitter from 'event-emitter'
+import SnapsvgZoom from './snapsvg-zoom'
+
var eventEmitter = EventEmitter({});
-/* custom plugin */
+/* custom plugins */
Snap.plugin(function (Snap, Element, Paper, glob) {
var elproto = Element.prototype;
@@ -28,6 +29,7 @@
var mainImage = null;
var pointData = [];
var viewBoxBounds = {X: 100, Y:100};
+var zoomManager = null;
var config = null;
var readOnly = false;
var startPoint = null;
@@ -73,7 +75,7 @@
drawing_path = rectZone;
canDraw = false;
pathIsClosed = true;
- ShapeResizer.apply_resize(paper, drawing_path);
+ ShapeResizer.enable_resizer(paper, drawing_path);
};
@@ -188,6 +190,10 @@
var onMoveHandler = function (dx, dy, posX, posY, e) {
isDragged = true;
/* update point then update the view */
+ var zoomFactor = zoomManager.getZoomFactor();
+ console.log(zoomFactor);
+ dx = dx / zoomFactor.x;
+ dy = dy / zoomFactor.y;
var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy];
this.attr({ transform: transformValue});
var boxSize = this.getBBox();
@@ -210,6 +216,7 @@
});
point.handler.drag(onMoveHandler, function () {
+ console.log(this.transform().globalMatrix);
this.data('origTransform', this.transform().local );
}, function () {
if (!isDragged) { return true; }
@@ -224,7 +231,7 @@
var handleY = point.y - HANDLE_SIZE/2;
handler = p.rect(handleX, handleY, HANDLE_SIZE, HANDLE_SIZE);
-
+ handler.addClass("drawingHandler");
point.handler = handler;
point.handler.data('point', point);
if (pointData.length === 0) {
@@ -341,11 +348,23 @@
};
var API = {
-
+
+ increaseZoom: function () {
+ zoomManager.zoomIn();
+ },
+
+ reset: function () {
+ zoomManager.reset();
+ },
+
+ decreaseZoom: function () {
+ zoomManager.zoomOut();
+ },
+
setPath: function (pathString) {
/* redraw the path */
var pathInfos = pathString.split(';');
- if( availableModes.indexOf(pathInfos[1]) === -1) {
+ if ( availableModes.indexOf(pathInfos[1]) === -1) {
/* We assume then it is a free path */
pathInfos[1] = "FREE";
}
@@ -353,14 +372,14 @@
this.setDrawingMode(pathInfos[1]);
var pathData = pathInfos[0];
- if(!pathData.length) {
+ if (!pathData.length) {
return;
}
- /* deal with path nomalization x = ImageWith/MaxXBound*/
+ /* deal with path nomalization x = ImageWith/MaxXBound */
var xRatio = mainImage.width() / viewBoxBounds.X;
var yRatio = mainImage.height() / viewBoxBounds.Y;
- if(isNaN(xRatio) || isNaN(yRatio)) {
+ if (isNaN(xRatio) || isNaN(yRatio)) {
new Error('Ratio should be a number.');
}
@@ -416,6 +435,11 @@
ENABLE_NEW_NODE = true;
},
+ getShapeBBox: function () {
+ var currentPath = this.getPath();
+ return Snap.path.getBBox(currentPath);
+ },
+
getPath: function () {
/* retourne le chemin */
/* send path and BBox | implement edit and load path */
@@ -478,22 +502,25 @@
export default {
init: function(config) {
- mainImage = jQuery(config.wrapperId).find('img').eq(0);
+ mainImage = jQuery(config.wrapperId).find('.main-image').eq(0);
var cutCanvas = jQuery(config.wrapperId).find('.cut-canvas').eq(0);
var path = jQuery(config.wrapperId).find('.image-path').eq(0);
if (typeof config.onDrawingModeChange === 'function') {
onChangeCallback = config.onDrawingModeChange;
}
+
+ if (!mainImage.length) {
+ throw new Error("The main image Can't be found ...");
+ }
if (!cutCanvas.length) {
var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
jQuery(config.wrapperId).append(cutCanvas);
+ cutCanvas.append(mainImage);
}
- if (!mainImage) {
- new Error(config.wrapperId + "Can't be found ...");
- }
+
cutCanvas.css({
position: 'absolute',
@@ -501,9 +528,9 @@
left: '15px',
marginLeft: 'auto',
marginRight: 'auto',
- width: mainImage.width(),
- height: mainImage.height(),
- viewBox: '0 0 100 100'
+ width: mainImage.attr('width'),
+ height: mainImage.attr('height'),
+ //viewBox: '0 0 100 100'
});
if (typeof config.readOnly === 'boolean' && config.readOnly === true) {
@@ -514,9 +541,12 @@
if (path.length) {
jQuery(cutCanvas).append(path);
- API.setPath(path.attr("d"));
+ var pathData = path.attr("d");
+ API.setPath(pathData);
+ path.remove();
}
-
+ /* enable zoom */
+ zoomManager = SnapsvgZoom.enable_zoom({paper : paper});
attachPointEvents(paper);
attachRectEvents(paper);
--- a/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/typeahead/Typeahead.vue Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/typeahead/Typeahead.vue Wed Jul 13 17:57:35 2016 +0200
@@ -6,7 +6,7 @@
import Taglist from '../taglist/Taglist.vue'
var autoCompletePath = "http://lookup.dbpedia.org/api/search/PrefixSearch?MaxHits=5";
- var wikipediaPath= "http://fr.wikipedia.org/w/api.php"
+ var wikipediaPath = "http://fr.wikipedia.org/w/api.php"
var parentsMethods = {
reset: typeahead.methods.reset
};
--- a/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/utils/index.js Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/utils/index.js Wed Jul 13 17:57:35 2016 +0200
@@ -1,3 +1,6 @@
+import EventEmitter from 'event-emitter'
+var eventEmitter = EventEmitter({});
+
var generateId = (function () {
var cpt = 0;
var defautPrefix = "item_";
@@ -7,4 +10,5 @@
return prefix + cpt;
}
}());
-export { generateId }
\ No newline at end of file
+
+export { generateId , eventEmitter }
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/zoomview/Zoomview.vue Wed Jul 13 17:57:35 2016 +0200
@@ -0,0 +1,36 @@
+
+<template src='./template.html'></template>
+
+<script>
+
+import {eventEmitter} from '../utils'
+
+import Snap from 'snapsvg'
+
+export default {
+
+ props: ['image-url', 'width', 'height'],
+
+ mounted () {
+ this.root = new Snap(this.$refs['root-svg']);
+ this.handleEvents();
+ },
+
+ /* reduire size en fonction */
+ methods: {
+
+ handleEvents: function () {
+ eventEmitter.on("zoomChanged", function (zoomInfos) {
+ console.log("zoomInfos", zoomInfos.currentViewBox);
+ });
+ },
+
+ createHandler: function () {},
+
+ handlerZoomChanged: function (params) {
+ console.log("params", params);
+ }
+ }
+}
+
+</script>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/static/iconolab/js/iconolab-bundle/src/components/zoomview/template.html Wed Jul 13 17:57:35 2016 +0200
@@ -0,0 +1,12 @@
+<div class="zoomview-wrapper">
+ <svg ref="root-svg">
+ <image
+ x="0"
+ y="0"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ :xlink:href="imageUrl"
+ :width="width"
+ :height="height"></image>
+ <rect ref='handler' x="0" y="0" width="10" height="10" style="fill:orange; opacity:0.7"></rect>
+ </svg>
+</div>
\ No newline at end of file
--- a/src/iconolab/templates/iconolab/change_annotation.html Tue Jul 05 14:28:04 2016 +0200
+++ b/src/iconolab/templates/iconolab/change_annotation.html Wed Jul 13 17:57:35 2016 +0200
@@ -14,6 +14,17 @@
<li @click="setDrawingMode('RECT')" v-bind:class="{ 'selected': isRect }" class='pull-md-right drawingModeBtn'>Rect.</li>
<li @click="setDrawingMode('FREE')" v-bind:class="{ 'selected': !isRect }" class='pull-md-right drawingModeBtn'>Libre</li>
</ul>
+
+ <ul class="form-drawing-wrapper list-inline">
+ <p class='form-drawing pullright'><strong>Zoom</strong></p>
+ <li class="small" @click="incraseDrawingZoom"><i class="fa fa-plus"></i> Zoomer</li>
+ <li class="small" @click="resetDrawingZoom"><i class="fa fa-square"></i> Taille réelle</li>
+ <li class="small" @click="decreaseDrawingZoom"><i class="fa fa-minus"></i> Dézoomer</li>
+ </ul>
+ {% thumbnail image.media "x100" crop="center" as im %}
+ <zoomview :image-url="'{{ im.url }}'" :width="{{ im.width }}" :height="{{ im.height }}">
+ </zoomview>
+ {% endthumbnail %}
<ul class='form-drawing-wrapper list-inline'>
<p class='form-drawing pullright'><strong>Actions</strong></p>
@@ -27,12 +38,14 @@
<div class="col-md-8">
<div ref="image" id="iconolab-image-wrapper">
{% thumbnail image.media "x800" crop="center" as im %}
- <img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
- <path class="image-path" d="{% if annotation %}{{ annotation.current_revision.fragment }}{% endif %}"></path>
+ <svg class="cut-canvas">
+ <image class="main-image" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="{{ im.url }}" x="0" y="0" width="{{ im.width }}" height="{{ im.height }}"></image>
+ <path class="image-path" d="{% if annotation %}{{ annotation.current_revision.fragment }}{% endif %}"></path>
+ </svg>
{% endthumbnail %}
</div>
</div>
-
+
<div class="col-md-2">
<a @click="cancel"><i class="fa fa-close"></i> Annuler</a>
</div>
@@ -41,13 +54,14 @@
<div v-show="formView" class="col-md-12">
- <div class="col-xs-6">
+ <div class="col-md-6">
<div class="small-image-wrapper" style="position: relative">
{% thumbnail image.media "x300" crop="center" as im %}
- <img ref="smallImage" @click="showEditor" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
- <svg width="{{ im.width }}" height="{{ im.height }}" version="1.1" style="position:absolute; top:0px; left: 0px">
+ <svg ref="smallSvgWrapper" width="{{ im.width }}" preserveAspectRatio="xMinYMin meet" height="{{ im.height }}" version="1.1">
+ <image ref="smallImage" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="{{ im.url }}" x="0" y="0" width="{{ im.width }}" height="{{ im.height }}"></image>
+
<defs>
<mask id="smallImage">
<rect x="0" y="0" width="{{ im.width }}" height="{{ im.height }}" fill="white"/>
@@ -63,6 +77,15 @@
<rect v-show="displayMask" ref="smallMask" x="0" y="0" mask="url(#smallImage)" opacity="0.7" fill="white" width="{{ im.width }}" height="{{ im.height }}"></rect>
</svg>
+
+ <svg style="display:none" ref="zoomSvg" width="{{ im.width }}" height="{{ im.height }}" version="1.1">
+
+ <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="{{ im.url }}" x="0" y="0" preserveAspectRatio="none" width="{{ im.width }}" height="{{ im.height }}"></image>
+
+ <g v-bind:transform="transformMatrix">
+ <path v-bind:d="fragmentPath" opacity="0.7" fill="orange"></path>
+ </g>
+ </svg>
{% endthumbnail %}
</div>
@@ -70,10 +93,12 @@
<li @click="showEditor" class="showPointer"> <i class='fa fa-edit'></i> Editer le fragment</li>
<li v-show="!displayMask" @click="highLightZone" class="showPointer"> <i class='fa fa-eye-slash'></i> Afficher la zone</li>
<li v-show="displayMask" @click="highLightZone" class="showPointer"> <i class='fa fa-eye-slash'></i> Masquer la zone</li>
+ <li v-if="canZoom" @click="zoom('in')"><i class="fa fa-zoom-in"></i>Zoomer</li>
+ <li v-if="!canZoom" @click="zoom('out')"><i class="fa fa-zoom-out"></i>Dezoomer</li>
</ul>
</div>
- <div class='col-xs-6' style="">
+ <div class='col-md-6' style="">
<form class="form" action="{% if annotation %}{% url 'annotation_edit' collection_name image_guid annotation_guid %}{% else %}{% url 'annotation_create' collection_name image_guid %}{% endif %}" method="POST">
{% if form.errors %}
<div id="errors" style="display: none;">