src_js/iconolab-bundle/src/components/editor/ZoomThumbnail.vue
author Alexandre Segura <mex.zktk@gmail.com>
Wed, 22 Feb 2017 18:32:39 +0100
changeset 351 2d5557c01f95
parent 335 86dbf2cdeeeb
child 355 004fdb42f063
permissions -rw-r--r--
Change design of right side panel.

<template>
    <div class="wrapper">
        <svg ref="svg" v-bind:width="thumbnailWidth" v-bind:height="thumbnailHeight">
            <image xmlns:xlink="http://www.w3.org/1999/xlink"
                x="0" y="0"
                v-bind:width="thumbnailWidth" v-bind:height="thumbnailHeight"
                v-bind:xlink:href="image"></image>
            <rect ref="handler"
                class="move-handler"
                v-bind:x="x" v-bind:y="y"
                v-bind:width="width" v-bind:height="height"
                style="fill: black; opacity: 0.4"></rect>
        </svg>
    </div>
</template>

<script>

    import Snap from 'snapsvg'

    export default {
        props: [
            'image',
            'viewport',
            'viewBox',
            'imageWidth',
            'imageHeight',
        ],
        data() {
            return {
                thumbnailWidth: 0,
                thumbnailHeight: 0,
                loaded: false
            }
        },
        computed: {
            x: function() {
                return this.viewBox[0] * this.getRatioX();
            },
            y: function() {
                return this.viewBox[1] * this.getRatioY();
            },
            width: function() {
                return this.viewBox[2] * this.getRatioX();
            },
            height: function() {
                return this.viewBox[3] * this.getRatioY();
            }
        },
        methods: {
            reset: function() {
                var handler = new Snap(this.$refs.handler);
                handler.node.removeAttribute('transform');
            },
            getRatioX: function() {
                if (this.imageWidth === 0) { return 0; }

                return this.thumbnailWidth / this.imageWidth;
            },
            getRatioY: function() {
                if (this.imageHeight === 0) { return 0; }

                return this.thumbnailHeight / this.imageHeight;
            }
        },
        mounted() {

            var svg = new Snap(this.$refs.svg);
            var handler = new Snap(this.$refs.handler);

            var img = new Image();
            img.onload = (e) => {

                var self = this;

                svg.attr({
                    viewBox: [0, 0, img.width, img.height]
                });

                Object.assign(this, {
                    thumbnailWidth: img.width,
                    thumbnailHeight: img.height,
                    loaded: true
                });

                var events = {
                    onMove: function (dx, dy, x, y) {

                        var snapInvMatrix = this.transform().diffMatrix.invert();
                        snapInvMatrix.e = snapInvMatrix.f = 0;
                        var tdx = snapInvMatrix.x(dx, dy);
                        var tdy = snapInvMatrix.y(dx, dy);

                        var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [tdx, tdy];
                        this.transform(transformValue);

                        self.$emit('change', {
                            x: this.getBBox().x * (self.imageWidth / self.thumbnailWidth),
                            y: this.getBBox().y * (self.imageHeight / self.thumbnailHeight),
                        });

                    },
                    onStart: function () {
                        this.data('origTransform', this.transform().local);
                        self.$emit('dragstart');
                    },
                    onEnd: function () {
                        self.$emit('dragend');
                    }
                }

                handler.drag(events.onMove, events.onStart, events.onEnd);
            }

            img.src = this.image;
        }
    }

</script>

<style scoped>
.wrapper {
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
}
.wrapper svg {
    border: 2px solid black;
    border-radius: 4px;
}
.move-handler {
    cursor: -moz-grab;
    cursor: -webkit-grab;
    cursor: grab;
}
</style>