codeNinja
codeNinja

Reputation: 1462

wrapping around a circle

I want to wrap the text from 2 divs around a circle. I have created my divs and the circle. Now trying to figure out how to wrap the test. Nothing seems to do it.

.blackbox{
    width: 600px;
    height:400px;
    margin-top: 12%;
    margin-left:auto;
    margin-right:auto;
    background-color: black;
    padding:35px;
    display:block;   
    line-height: 2.8em;
    font-size: 13px;
}

.center img{
    width: 200px;
    height:200px;
    display:inline-block;
    float:left;
    background: #f00;
    border-radius: 50%;
}

.left{
    width:33%;
    margin-top: 3.5%;
    color: white;
    display:inline-block;   
    float:left;
    text-align: right;
}

.right{
    width:33%;    
    margin-top: 3.5%;
    color: white;
    display:inline-block;    
    float:left;
    text-align: left;
}
<div class="content">
    <div class="blackbox">
        <div class="left">we believe that a great brand is a compassionate brand, tuned into what's affecting the people around it. Great brands listen actively and respond thoughtfully. They don't try to appear sincere-they are sincere.</div>
         <div class="center"><img class="img-responsive" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"></div>
        <div class="right">You can be a Fortune 500 company, a nonprofit, a tech startup, or a fashion label, to be competitive and succeed unequivocally, while also doing what's right. ecognizes the value in every endeavor. <br><br> If that sounds good to you, let's get to work.</div>
    </div>
</div

Here is the jsfiddle

Upvotes: 2

Views: 339

Answers (3)

tao
tao

Reputation: 90013

This is what shape-outside (MDN, W3C) was made for. Currently at ~70% support, Firefox support "in development" and Edge "under consideration", can be used in production with css-shapes-polyfill.

body {
  text-align: center;
}
body [simple-container], 
body h2 {
  max-width: 800px;
  margin: 0 auto;
  text-align: left;
}
[path-parent] {
  display: flex;
}

[path-parent] p {
  overflow-x: hidden;
  text-align: justify;
  padding: 0 10px;
}

h2 { padding: 0 10px; }

[circle-path] {
  float: right;
  width: 400px;
  height: 400px;
  shape-outside: circle(50% at 100% 50%);
  shape-margin: 10px;
  position: relative;
  right: -10px;
}
[circle-path]::after {
  width: 100%;
  height: 100%;
  display: block;
  position: absolute;
  background: #787878 url('http://lorempixel.com/g/300/300/fashion/') no-repeat center center /cover;
  content: '';
  border-radius: 50%;
  right:-50%;
}
[circle-path][wrong-path]::after {
  right: auto;
  left: -50%;
}
[circle-path][wrong-path] {
  float: left;
  shape-outside: circle(50% at 0 50%);
  right: auto;
  left: -10px;
}
@media(max-width: 800px) {
  [circle-path] {
    width: 50vw;
    height: 50vw;
  }
}
<div simple-container>
   <h2>Lorem ipsum</h2>
   <div path-parent>
    <p><span circle-path></span>
   [32] But I must explain to you how all this mistaken idea of denouncing of a pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?
   <p><span circle-path wrong-path></span>
   [33] On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammeled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains.
</div>

And here's your example, fully responsive:

.blackbox {
  width: 600px;
  margin: 80px auto;
  padding: 35px 45px;
  background-color: black;
  display: block;
  line-height: 2.4em;
  font-size: 13px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex-wrap: wrap;
  box-sizing: border-box;
  color: white;
}

.blackbox > div {
  flex: 0 0 50%;
}

.blackbox img {
  width: 200px;
  height: 200px;
  display: block;
  float: left;
  position: relative;
  shape-margin: 10px;
}

.blackbox hr {
  width: 35%;
  border: solid #787878;
  border-width: 0 0 1px;
}

.blackbox .bottom {
  flex: 0 0 100%;
  text-align: center;
}

.left {
  text-align: right;
  right: 10px;
  position: relative;
}

.left img {
  float: right;
  margin-right: -100px;
  shape-outside: circle(50% at 100% 50%);
  right: -10px;
}

.right {
  text-align: left;
  left: 10px;
  position: relative;
}

.right img {
  margin-left: -100px;
  shape-outside: circle(50% at 0 50%);
  left: -10px;
}

@media (max-width: 600px) {
  .blackbox {
    width: 100%;
    padding: 5vw 10vw;
    line-height: 6vw;
  }
  .blackbox img {
    width: 33.33vw;
    height: 33.33vw;
  }
  .blackbox .right img {
    margin-left: -16.67vw;
    shape-margin: 10px;
  }
  .blackbox .left img {
    margin-right: -16.67vw;
    shape-margin: 10px;
  }
}
<div class="content">
  <div class="blackbox">
    <div class="left">
      <img class="img-responsive" src="https://upload.wikimedia.org/wikipedia/commons/2/22/Earth_Western_Hemisphere_transparent_background.png" /> we believe that a great brand is a compassionate brand, tuned into what's affecting the people around it.
      Great brands listen actively and respond thoughtfully. They don't try to appear sincere-they are sincere.</div>
    <div class="right">
      <img class="img-responsive" src="https://upload.wikimedia.org/wikipedia/commons/2/22/Earth_Western_Hemisphere_transparent_background.png" /> You can be a Fortune 500 company, a nonprofit, a tech startup, or a fashion label, to be competitive and
      succeed unequivocally, while also doing what's right. ecognizes the value in every endeavor.
    </div>
    <div class="bottom">
      <hr /> If that sounds good to you, let's get to work.
    </div>
  </div>
</div>

SCSS here.

Upvotes: 2

K Scandrett
K Scandrett

Reputation: 16540

I wrote a version in javascript, since, as noted in the comments, any CSS solutions quite likely have limited browser support.

In my demo I changed some of your text to better illustrate the wrapping. Also I gave the div elements ids, and adjusted the CSS.

To use, you would pass two jQuery objects to wrapToCircle(), the first being the text to wrap, and the other the element acting as the circle. For your demo this looks like:

$(function() {
  wrapToCircle($(".left"), $(".cirle img"));
  wrapToCircle($(".right"), $(".cirle img"));
});

It assumes that the 'circle' element's centre is in the middle, and that its diameter is its width (...or height - whichever is smaller if the element is rectangular).

$(function() {
  // call wrapToCircle( div that you want to wrap, adjacent circle to follow)
  wrapToCircle($("#left"), $("#cirle img"));
  wrapToCircle($("#right"), $("#cirle img"));
});

function wrapToCircle($elementToWrap, $aroundElement) {

  var elementToWrapPos = $elementToWrap.offset();
  var aroundElementCentre = {}
  var radius = Math.min($aroundElement.width() / 2, $aroundElement.height() / 2);

  aroundElementCentre.left = $aroundElement.offset().left + ($aroundElement.width() / 2);
  aroundElementCentre.top = $aroundElement.offset().top + ($aroundElement.height() / 2);

  var text = $elementToWrap.text().split(" ");
  var wrappedText = '';
  var wordWidths = [];
  var isToTheRightOfCircle = $elementToWrap.offset().left > aroundElementCentre.left;

  $(text).each(function(idx, elem) {
    wrappedText += '<span>' + elem + '</span> ';
  });

  wrappedText += '<span>&nbsp;</span>'; // wrap text, end with a space, to measure width
  $elementToWrap.empty().append(wrappedText);

  $elementToWrap.find("span").each(function(idx, elem) {
    wordWidths.push($(this).width());
  });

  var $space = $elementToWrap.find('span').last();
  var spaceWidth = $space.width();
  $space.remove();

  var widthToWrapTo = $elementToWrap.width();
  var currentLine = '';
  var currentLineWidth = 0;

  $elementToWrap.empty();

  var curEl = $("<div>.</div>").appendTo($elementToWrap); // need default content so we can get the height
  var textHeight = curEl.height();
  var adjustedWidth = 0;

  adjustedWidth = calculateNewTextWidth(aroundElementCentre, curEl, textHeight, radius, widthToWrapTo);

  currentLine = "";

  // loop over the words
  $(text).each(function(idx, elem) {

    if (currentLineWidth + wordWidths[idx] + spaceWidth <= adjustedWidth) {
      currentLine += text[idx] + " ";
      currentLineWidth += wordWidths[idx] + spaceWidth;
    } else { // start a new line
      curEl.text(currentLine);
      curEl.css('width', adjustedWidth);

      if (isToTheRightOfCircle) {
        curEl.css('position', 'relative');
        curEl.css('left', -(adjustedWidth - widthToWrapTo));
      }

      curEl = $("<div>").appendTo($elementToWrap);

      adjustedWidth = calculateNewTextWidth(aroundElementCentre, curEl, textHeight, radius, widthToWrapTo);

      currentLine = text[idx] + " ";
      currentLineWidth = wordWidths[idx] + spaceWidth;
    }
  });

  curEl.text(currentLine);
  curEl.css('width', adjustedWidth);
  if (isToTheRightOfCircle) {
    curEl.css('position', 'relative');
    curEl.css('left', -(adjustedWidth - widthToWrapTo));
  }
}

function findX(y, radius) {
  return Math.sqrt(radius * radius - y * y);
}

function calculateNewTextWidth(aroundElementCentre, curEl, curElHeight, radius, widthToWrapTo) {
  var heightfromCircleCentre = Math.abs(aroundElementCentre.top - (curEl.offset().top + (0.5 * curElHeight)));
  if (heightfromCircleCentre > radius) {
    return widthToWrapTo + radius;
  } else { // vertically, this text is within the top and bottom boundaries of the cirlce
    return widthToWrapTo + (radius - findX(heightfromCircleCentre, radius));
  }
}
.blackbox {
  width: 600px;
  height: 400px;
  margin-top: 12%;
  margin-left: auto;
  margin-right: auto;
  background-color: black;
  padding: 35px;
  display: block;
  line-height: 2.8em;
  font-size: 13px;
}

.center {
  width: 200px;
  height: 200px;
  float: left;
}

.center img {
  width: 200px;
  height: 200px;
  background: #f00;
  border-radius: 50%;
}

.left {
  width: 33%;
  margin-top: 3.5%;
  color: white;
  display: inline-block;
  float: left;
  text-align: left;
  padding-right: 5px;
}

.right {
  width: 32%;
  margin-top: 3.5%;
  color: white;
  display: inline-block;
  float: left;
  text-align: right;
  padding-left: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
  <div class="blackbox">
    <div id="left" class="left">we believe that a great brand is a useful brand, tuned into what's affecting the people around it. Great brands listen actively and respond thoughtfully. They don't try to appear sincere - they are sincere... Here is more text that wraps the bottom
      of the circle.</div>
    <div id="cirle" class="center"><img class="img-responsive" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"></div>
    <div id="right" class="right">You can be a Fortune 500 company, any nonprofit, a tech startup, or a fashion label, to be competitive and succeed unequivocally, while also doing what's right. ecognizes the value in every endeavor. If that sounds good to you, let's do this right
      now.</div>
  </div>
</div>

Here's the same code in JsFiddle https://jsfiddle.net/wbaatowk/4/

Upvotes: 4

Alfin Paul
Alfin Paul

Reputation: 1621

use lettering.js

Try This DEMO

Plugin Taken From this link

Upvotes: -1

Related Questions