Blend Modes——混合模式


This example shows how to change the canvas compositing / blending mode in post- and precompose event handlers. The Canvas 2D API provides the property globalCompositeOperation with which one can influence which composition operation will be used when drawing on the canvas. The various options are well described on the MDN documentation page.

这个例子展示了如何在postcompose和precompose事件处理中改变Canvas的混合模式。Canvas 2D的API提供了一个globalCompositeOperation属性,使用这个属性可以影响在canvas上绘图的时候使用哪种混合操作。globalCompositeOperation的各种设置在MDN文档页面中有很好的描述。


In this example three circles on the corners of an equilateral triangle are drawn with red, green or blue styles respectively. By setting theglobalCompositeOperation you can change how these colors turn out when they are combined on the map.

在这个例子中,在一个等边三角形各个角上的三个圆分别用红、绿、蓝三种样式被绘制了出来,通过设置globalCompositeOperation属性,你可以改变这些颜色在地图上组合时的显示方式。


You can select an operation in the select-field and you can also control which layers will be affected by the chosen operation through the layer checkboxes.

你可以在下拉列表框中选择一种操作,你也可以通过图层复选框的勾选操作来控制哪些图层受到影响。


代码:
<!DOCTYPE html>
<html>
  <head>
    <title>Blend Modes</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v4.2.0/css/ol.css" type="text/css">
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://openlayers.org/en/v4.2.0/build/ol.js"></script>
    <style>
      .map{
        background-repeat: repeat;
        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAApSURBVBiVY7x///5/BjSgqKjIiC7GhC6ACwygQgxHMzAwMGDz4FDwDAD5/wevjSk4mwAAAABJRU5ErkJggg==);
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <form class="form-horizontal">
      <label>
        <select id="blend-mode" class="form-control">
          <option value="source-over">source-over (default)</option>
          <option>source-in</option>
          <option>source-out</option>
          <option>source-atop</option>
          <option>destination-over</option>
          <option>destination-in</option>
          <option>destination-out</option>
          <option>destination-atop</option>
          <option>lighter</option>
          <option>copy</option>
          <option>xor</option>
          <option>multiply</option>
          <option>screen</option>
          <option>overlay</option>
          <option>darken</option>
          <option>lighten</option>
          <option>color-dodge</option>
          <option>color-burn</option>
          <option>hard-light</option>
          <option>soft-light</option>
          <option selected>difference</option>
          <option>exclusion</option>
          <option>hue</option>
          <option>saturation</option>
          <option>color</option>
          <option>luminosity</option>
        </select>
        Canvas compositing / blending mode
      </label>
      <label>
        <input type="checkbox" id="affect-red" checked>
        Red circle affected
      </label>
      <label>
        <input type="checkbox" id="affect-green" checked>
        Green circle affected
      </label>
      <label>
        <input type="checkbox" id="affect-blue" checked>
        Blue circle affected
      </label>
    </form>
    <script>
      // Create separate layers for red, green an blue circles.
      // 为红、绿、蓝三个圆分别创建图层
      // Every layer has one feature that is styled with a circle,
     // 每一个图层都有一个设置了circle样式的要素
      // together the features form the corners of an equilateral triangle and their styles overlap
      // 同时这些要素处于一个等边三角形的各个角上而且他们的样式相互重叠
       var redLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          features: [new ol.Feature(new ol.geom.Point([0, 0]))]
        }),
        style: new ol.style.Style({
          image: new ol.style.Circle({
            fill: new ol.style.Fill({
              color: 'rgba(255,0,0,0.8)'
            }),
            stroke: new ol.style.Stroke({
              color: 'rgb(255,0,0)',
              width: 15
            }),
            radius: 120
          })
        })
      });
      var greenLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          // 433.013 is roughly 250 * Math.sqrt(3)
          features: [new ol.Feature(new ol.geom.Point([250, 433.013]))]
        }),
        style: new ol.style.Style({
          image: new ol.style.Circle({
            fill: new ol.style.Fill({
              color: 'rgba(0,255,0,0.8)'
            }),
            stroke: new ol.style.Stroke({
              color: 'rgb(0,255,0)',
              width: 15
            }),
            radius: 120
          })
        })
      });
      var blueLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          features: [new ol.Feature(new ol.geom.Point([500, 0]))]
        }),
        style: new ol.style.Style({
          image: new ol.style.Circle({
            fill: new ol.style.Fill({
              color: 'rgba(0,0,255,0.8)'
            }),
            stroke: new ol.style.Stroke({
              color: 'rgb(0,0,255)',
              width: 15
            }),
            radius: 120
          })
        })
      });

      // Create the map, the view is centered on the triangle. Zooming and panning is
      // restricted to a sane area
      // 创建地图,视图中心在三角形的中心,且缩放和平移都限制在一个合理的范围内
     var map = new ol.Map({
        layers: [
          redLayer,
          greenLayer,
          blueLayer
        ],
        target: 'map',
        view: new ol.View({
          center: [250, 220],
          extent: [0, 0, 500, 500],
          resolution: 4,
          minResolution: 2,
          maxResolution: 32
        })
      });

      // Get the form elements and bind the listeners
      // 获取元素并绑定监听器
      var select = document.getElementById('blend-mode');
      var affectRed = document.getElementById('affect-red');
      var affectGreen = document.getElementById('affect-green');
      var affectBlue = document.getElementById('affect-blue');


      /**
       * This method sets the globalCompositeOperation to the value of the select
       * field and it is bound to the precompose event of the layers.
       * 这个方法用来把选中的字段设置为globalCompositeOperation的属性值,并绑定到图层的precompose事件中
       * @param {ol.render.Event} evt The render event.
       */
      var setBlendModeFromSelect = function(evt) {
        evt.context.globalCompositeOperation = select.value;
      };


      /**
       * This method resets the globalCompositeOperation to the default value of
       * 'source-over' and it is bound to the postcompose event of the layers.
       * 这个方法把globalCompositeOperation重置为默认的source-over属性,并绑定到图层postcompose事件中
       * @param {ol.render.Event} evt The render event.
       */
      var resetBlendModeFromSelect = function(evt) {
        evt.context.globalCompositeOperation = 'source-over';
      };


      /**
       * Bind the pre- and postcompose handlers to the passed layer.
       * 绑定precompose和postcompose事件处理到传入的图层中
       * @param {ol.layer.Vector} layer The layer to bind the handlers to.
       */
      var bindLayerListeners = function(layer) {
        layer.on('precompose', setBlendModeFromSelect);
        layer.on('postcompose', resetBlendModeFromSelect);
      };


      /**
       * Unind the pre- and postcompose handlers to the passed layers.
       * 取消绑定precompose和postcompose事件处理到传入的图层中
       * @param {ol.layer.Vector} layer The layer to unbind the handlers from.
       */
      var unbindLayerListeners = function(layer) {
        layer.un('precompose', setBlendModeFromSelect);
        layer.un('postcompose', resetBlendModeFromSelect);
      };


      /**
       * Handler for the click event of the 'affect-XXX' checkboxes.
       * 处理affect-XXX复选框的单击事件
       * @this {HTMLInputElement}
       */
      var affectLayerClicked = function() {
        var layer;
        if (this.id == 'affect-red') {
          layer = redLayer;
        } else if (this.id == 'affect-green') {
          layer = greenLayer;
        } else {
          layer = blueLayer;
        }
        if (this.checked) {
          bindLayerListeners(layer);
        } else {
          unbindLayerListeners(layer);
        }
        map.render();
      };


      // Rerender map when blend mode changes
     // 当混合模式改变时渲染地图
      select.addEventListener('change', function() {
        map.render();
      });

      // Unbind / bind listeners depending on the checked state when the checkboxes
      // are clicked
      // 取消绑定/绑定监听取决于复选框是否被单击
     affectRed.addEventListener('click', affectLayerClicked);
      affectGreen.addEventListener('click', affectLayerClicked);
      affectBlue.addEventListener('click', affectLayerClicked);

      // Initially bind listeners
      // 初始化绑定监听
     bindLayerListeners(redLayer);
      bindLayerListeners(greenLayer);
      bindLayerListeners(blueLayer);
    </script>
  </body>
</html>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值