dqba94619
dqba94619
2015-11-02 12:31

使用模板.phtml中的interact.js的magento动态多维数据集

已采纳

I used interact.js library to write this piece of code which works absolutely fine standalone on chrome, firefox and w3schools "Try it Yourself" (doesn't work on Edge and IE for some reason). The problem is that when I call a template.phtml with this code inside from the layout.xml, the magento renders it only once, thus the user is not allowed to resize the cubes.

<!-- CSS -->
<style type="text/css">
svg {
  width: 100%;
  height: 300px;
  background-color: #CDC9C9;

  -ms-touch-action: none;
      touch-action: none;
}
.edit-rectangle {
  fill: black;
  stroke: #fff;
}
body { margin: 0; }
</style>

<!-- Content -->
<br>
<svg>
</svg>

<br>
<button onclick="location.href = 'square';" id="previousbutton">Go back</button>
<button onclick="location.href = 'squaresection';" style="float:right" id="nextButton">Proceed to next step</button>
<br>
<br>

<script type="text/javascript" src="interact.js">
</script>

<!-- JavaScript -->

<script type="text/javascript">

var svgCanvas = document.querySelector('svg'),
    svgNS = 'http://www.w3.org/2000/svg',
    rectangles = [];
    labels = [];
    rectNumb = 5;

function Rectangle (x, y, w, h, svgCanvas) {
  this.x = x;
  this.y = y;
  this.w = w;
  this.h = h;
  this.stroke = 0;
  this.el = document.createElementNS(svgNS, 'rect');

  this.el.setAttribute('data-index', rectangles.length);
  this.el.setAttribute('class', 'edit-rectangle');
  rectangles.push(this);

  this.draw();
  svgCanvas.appendChild(this.el);
}


function Label (x, y, text, svgCanvas){
  this.x = x;
  this.y = y;
  this.text = text;
  this.el = document.createElementNS(svgNS, 'text');
  labels.push(this);

  this.draw();
  svgCanvas.appendChild(this.el);
}
Label.prototype.draw = function () {
  this.el.setAttribute('x', this.x);
  this.el.setAttribute('y', this.y);
  this.el.setAttribute('font-family', "Verdana");
  this.el.setAttribute('font-size', 14);
  this.el.setAttribute('fill', "black");
  this.el.innerHTML = this.text;
}

Rectangle.prototype.draw = function () {
  this.el.setAttribute('x', this.x + this.stroke / 2);
  this.el.setAttribute('y', this.y + this.stroke / 2);
  this.el.setAttribute('width' , this.w - this.stroke);
  this.el.setAttribute('height', this.h - this.stroke);
  this.el.setAttribute('stroke-width', this.stroke);
}

interact('.edit-rectangle')
  // change how interact gets the
  // dimensions of '.edit-rectangle' elements
  .rectChecker(function (element) {
    // find the Rectangle object that the element belongs to
    var rectangle = rectangles[element.getAttribute('data-index')];
    // return a suitable object for interact.js
    return {
      left  : rectangle.x,
      top   : rectangle.y,
      right : rectangle.x + rectangle.w,
      bottom: rectangle.y + rectangle.h
    };
  })
/*
.draggable({
    max: Infinity,
    onmove: function (event) {
      var rectangle = rectangles[event.target.getAttribute('data-index')];

      rectangle.x += event.dx;
      rectangle.y += event.dy;
      rectangle.draw();
    }
  })
*/
 .resizable({
    onstart: function (event) {},
    onmove : function (event) {
      if (event.target.getAttribute('data-index') > 0)
      {
        // Main Rect
        var rectangle = rectangles[event.target.getAttribute('data-index')];
        var rectangle2 = rectangles[event.target.getAttribute('data-index') - 1];

        if (rectangle.w - event.dx > 10 && rectangle2.w + event.dx > 10){
          rectangle.x += event.dx;
          rectangle.w = rectangle.w - event.dx;

          rectangle2.w = rectangle2.w + event.dx;
        }

        rectangle.draw();
        rectangle2.draw();

        var label = labels[event.target.getAttribute('data-index')];
        var label2 = labels[event.target.getAttribute('data-index') - 1];
        label.text = rectangle.w + " mm";
        label2.text = rectangle2.w + " mm";

        label.x = rectangle.x + rectangle.w / 4;
        label2.x = rectangle2.x + rectangle2.w / 4;

        label.draw();
        label2.draw();
      }
    },
    onend  : function (event) {},

    edges: {
      top   : false,     // Disable resizing from top edge. 
      left  : true,      
      bottom: false,      
      right : false       // Enable resizing on right edge
    },

    inertia: false,

    // Width and height can be adjusted independently. When `true`, width and
    // height are adjusted at a 1:1 ratio.
    square: false,

    // Width and height can be adjusted independently. When `true`, width and
    // height maintain the aspect ratio they had when resizing started.
    preserveAspectRatio: false,

    // a value of 'none' will limit the resize rect to a minimum of 0x0
    // 'negate' will allow the rect to have negative width/height
    // 'reposition' will keep the width/height positive by swapping
    // the top and bottom edges and/or swapping the left and right edges
    invert: 'reposition',

    // limit multiple resizes.
    // See the explanation in the @Interactable.draggable example
    max: Infinity,
    maxPerElement: 3,
});

interact.maxInteractions(Infinity);

var positionX = 50,
    positionY = 80,
    width = 80,
    height = 80;

for (var i = 0; i < rectNumb; i++) {
  positionX = 50 + 82 * i;
  new Rectangle(positionX, positionY, width, height, svgCanvas);
}
for (var i = 0; i < rectNumb; i++) {
  positionX = 50 + 82 * i;
  new Label(positionX + width/4, positionY + height + 20, width +" mm", svgCanvas); 
}
</script>

Any suggestions of what I could do to implement this code into magento would be much appreciated.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dousi7579 dousi7579 6年前

    Magento did not render the code only once. The problem was that canvas event listener always assumed that pointer coordinates were wrong. Since canvas is the first element of the page(because it is the first element in that .phtml file), event listener assumed it will be displayed at the top, but that was not the case because of the way magento page rendering works.

    This issue was resolved simply by measuring the height of content above canvas and just mathematically subtracting that from pointers position before passing it to event listener.

    The problem with this solution is that it works only for single page or with multiple pages that have the same height of content above canvas(=>same design). If anyone knows a way in which person would not need to "recalculate" the height for every single page that has different design, sharing knowledge would be much appreciated.

    点赞 评论 复制链接分享